mirror of
https://github.com/Twigpine/zero.git
synced 2026-11-11 23:40:28 -10:00
* polish: cut per-turn overhead, stabilize cache, add /new Context economy - Compaction: preserveLast 8->6, triggerRatio 0.8->0.7 (both copies in sync). - System prompt: kill the "ELABORATE summary" directive; scale summary to the work. Comment discipline moved into the core prompt for all model families (was Anthropic-only); Minimax/DeepSeek/Qwen/etc. now get it. - Token-budget regression test ratchets the fixed per-turn overhead (base prompt + eager tool schemas) using the runtime's own estimator, so silent prompt/schema growth fails CI. Response quality - defaultResponseStyle balanced->concise. Reversible via /style. Tool discovery - <available_skills> block in the system prompt lists installed skills (name + one-line description) so the model loads the right one on the first call instead of guessing and reading the failure. Budget-capped at 640 bytes with an "...and N more" fallback; renders nothing when no skills are installed (byte-identical to prior prompt). Session lifecycle - /new starts a fresh session in place; previous session stays on disk and is named in the confirmation for /resume. Guards against mid-run reset. - /clear now notes that context persists and points to /new. Performance & caching - partitionTools no longer alpha-sorts the whole tools array every turn, which inserted a loaded deferred tool mid-array and shifted the cached prefix on every load. It now builds append-only regions [eager sorted] + [tool_search] + [loaded deferred sorted] so a mid-session load grows the tail instead of busting the eager prefix. Regression test asserts the eager block precedes any loaded tool. - /context now shows cache hit rate (flags low rate over >5 turns as a possible unstable prefix) and rolling average turn latency with time-to-first-token. Both reset on /new. Measured baselines (auto-mode, no workspace): base prompt 3162 tokens, eager tool schemas 2433 across 12 tools. Budget ceilings set ~10% above. Deliberately deferred (need a decision): inverted safety-policy rewrite (sandbox doesn't catch ~half the B-tier rules), core-tool/web_fetch deferral (activation-semantics blocker), aggressive prompt slim. * fix(tui): clear staged attachments + queued message on /new CodeRabbit: startNewSession reset conversation/usage/latency state but not the staged input (pendingImages, pendingImageLabels, pendingDocuments, queuedMessage), which is only consumed at prompt-submit. Without clearing it, the fresh session's first prompt silently inherited the previous session's images/documents/queued text. Test now stages all four and asserts they clear.
76 lines
3.0 KiB
Go
76 lines
3.0 KiB
Go
package agent
|
|
|
|
import "strings"
|
|
|
|
// Per-model prompt specialization.
|
|
//
|
|
// Different model families respond to different framing: the GPT family benefits
|
|
// from an explicit markdown/output spec and a strong "prefer native tools" nudge;
|
|
// Gemini benefits from explicit tool-preference and conciseness guidance. The
|
|
// Claude family is already aligned with the core prompt and needs no addendum —
|
|
// comment discipline is universal in the core prompt now, so every family gets it.
|
|
// modelPromptAddendum returns the family-specific block appended after the core
|
|
// prompt, or "" when the family is unknown or needs no specialization.
|
|
// Classification is by model id (the agent only has the model string — no registry
|
|
// dependency).
|
|
|
|
const (
|
|
familyOpenAI = "openai"
|
|
familyGemini = "gemini"
|
|
familyAnthropic = "anthropic"
|
|
)
|
|
|
|
// modelFamily classifies a model id into a prompt-tuning family, or "" when
|
|
// unknown (in which case no addendum is added).
|
|
func modelFamily(model string) string {
|
|
m := strings.ToLower(strings.TrimSpace(model))
|
|
switch {
|
|
case m == "":
|
|
return ""
|
|
case strings.HasPrefix(m, "gpt"), strings.HasPrefix(m, "o1"), strings.HasPrefix(m, "o3"),
|
|
strings.HasPrefix(m, "o4"), strings.Contains(m, "openai"):
|
|
return familyOpenAI
|
|
case strings.HasPrefix(m, "gemini"), strings.Contains(m, "google"):
|
|
return familyGemini
|
|
case strings.HasPrefix(m, "claude"), strings.Contains(m, "anthropic"):
|
|
return familyAnthropic
|
|
default:
|
|
return ""
|
|
}
|
|
}
|
|
|
|
// modelPromptAddendum returns the family-specific prompt block for a model id,
|
|
// or "" when the family is unknown.
|
|
func modelPromptAddendum(model string) string {
|
|
switch modelFamily(model) {
|
|
case familyOpenAI:
|
|
return openAIPromptAddendum
|
|
case familyGemini:
|
|
return geminiPromptAddendum
|
|
default:
|
|
// Anthropic (aligned with the core prompt) and unknown families get no
|
|
// family-specific block; comment discipline now lives in the core prompt
|
|
// for every model.
|
|
return ""
|
|
}
|
|
}
|
|
|
|
const openAIPromptAddendum = `<model_guidance>
|
|
- Output your final responses in GitHub-flavored Markdown: headings to structure
|
|
longer answers, fenced code blocks for code, and ` + "`inline code`" + ` for paths,
|
|
commands, and symbols.
|
|
- Strongly prefer the native file tools (read_file, list_directory, grep, glob,
|
|
write_file, edit_file, apply_patch) over shelling out to cat/sed/awk/python for
|
|
file work. Make one tool call per file; do not batch file writes into a script.
|
|
- Persist until the task is fully handled this turn: gather context, implement,
|
|
run the validators, and report — do not stop at a partial result.
|
|
</model_guidance>`
|
|
|
|
const geminiPromptAddendum = `<model_guidance>
|
|
- Prefer the dedicated tools (read_file, grep, glob, edit_file, apply_patch) over
|
|
equivalent shell commands; they are safer and produce cleaner diffs.
|
|
- Be concise and concrete. When you run a shell command with side effects, state
|
|
in one short clause why it is needed.
|
|
- Use update_plan for any multi-step task and keep it current.
|
|
</model_guidance>`
|