`portal-trainer generate` turns a plain-words business intake into a content repo in three phases, each held to portal's question_lint: needs.yaml (then frozen, so the generator cannot weaken the spec to pass), structure (revised against the lint's findings until green), and wording (personas answered blind, misroutes fed back; a rewrite that breaks structure is reverted). Model output is written to disk only under aggregates.yaml, site.yaml and questions/**.yaml. `portal-trainer answer` is the blind answerer alone. The LLM is an external command, prompt on stdin, text on stdout: engines/ollama.sh (local Ollama), engines/anthropic.sh (API key), engines/mailbox.sh (hand each prompt to an agent or a person). portal-portal/ is the onboarding site as a portal content repo: the front door is the intake interview, records land in `onboardings` (open -> drafted <-> revising -> live | declined), and it passes its own needs spec. runs/uhhm-2026-09-21/ollama: qwen3:8b and granite4.1:8b as blind answerers on the same eight tasks. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L4jrCgLiKKHAEFuZUJjckH
14 lines
641 B
Bash
Executable File
14 lines
641 B
Bash
Executable File
#!/bin/sh
|
|
# LLM backend for portal-trainer on a local Ollama: prompt on stdin,
|
|
# text on stdout. MODEL, OLLAMA_HOST, NUM_CTX and TIMEOUT override.
|
|
# Thinking is off: the generator wants files, the answerer wants JSONL.
|
|
set -eu
|
|
jq -Rs --arg model "${MODEL:-qwen3:8b}" --argjson ctx "${NUM_CTX:-32768}" \
|
|
'{model: $model, stream: false, think: false,
|
|
options: {num_ctx: $ctx, temperature: 0.2},
|
|
messages: [{role: "user", content: .}]}' |
|
|
curl -sS --fail-with-body --max-time "${TIMEOUT:-1800}" \
|
|
"${OLLAMA_HOST:-http://127.0.0.1:11434}/api/chat" \
|
|
-H "content-type: application/json" --data-binary @- |
|
|
jq -er '.message.content'
|