zelari-code 1.5.1 → 1.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/hooks/useChatTurn.js +72 -22
- package/dist/cli/hooks/useChatTurn.js.map +1 -1
- package/dist/cli/main.bundled.js +691 -561
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/provider/openai-compatible.js +101 -21
- package/dist/cli/provider/openai-compatible.js.map +1 -1
- package/dist/cli/runHeadless.js +5 -0
- package/dist/cli/runHeadless.js.map +1 -1
- package/package.json +2 -2
package/dist/cli/main.bundled.js
CHANGED
|
@@ -18050,6 +18050,357 @@ var init_toolSchemas = __esm({
|
|
|
18050
18050
|
}
|
|
18051
18051
|
});
|
|
18052
18052
|
|
|
18053
|
+
// packages/core/dist/agents/councilDirectives.js
|
|
18054
|
+
function getCouncilDirectiveModules() {
|
|
18055
|
+
return [
|
|
18056
|
+
STRUCTURED_REASONING_DIRECTIVE,
|
|
18057
|
+
COLLABORATION_DIRECTIVE,
|
|
18058
|
+
TOOL_USE_PROTOCOL_DIRECTIVE,
|
|
18059
|
+
OUTPUT_QUALITY_DIRECTIVE
|
|
18060
|
+
].sort((a, b) => a.priority - b.priority);
|
|
18061
|
+
}
|
|
18062
|
+
var STRUCTURED_REASONING_DIRECTIVE, TOOL_USE_PROTOCOL_DIRECTIVE, OUTPUT_QUALITY_DIRECTIVE, COLLABORATION_DIRECTIVE;
|
|
18063
|
+
var init_councilDirectives = __esm({
|
|
18064
|
+
"packages/core/dist/agents/councilDirectives.js"() {
|
|
18065
|
+
"use strict";
|
|
18066
|
+
STRUCTURED_REASONING_DIRECTIVE = {
|
|
18067
|
+
type: "custom",
|
|
18068
|
+
title: "Structured Reasoning",
|
|
18069
|
+
priority: 15,
|
|
18070
|
+
content: `# Structured Reasoning
|
|
18071
|
+
|
|
18072
|
+
Think step by step internally before responding. Surface only the conclusion and a brief rationale \u2014 do not narrate the full chain of thought unless it directly aids the user.
|
|
18073
|
+
|
|
18074
|
+
- For any non-trivial task, decompose it into ordered sub-steps and address each one before synthesizing.
|
|
18075
|
+
- Prefer concrete specifics over vague generalities: file paths, line numbers, measurable acceptance criteria, and concrete examples beat abstract advice.
|
|
18076
|
+
- When evaluating options, weigh trade-offs explicitly (cost, risk, effort, coverage) rather than listing features.
|
|
18077
|
+
- If information may have changed since your knowledge cutoff (project state, current tasks, stored documents), consult the shared context or use a retrieval tool rather than relying on memory.
|
|
18078
|
+
- Distinguish what you know from what you assume. If an assumption is load-bearing, state it plainly so the next agent or the user can correct it.
|
|
18079
|
+
- Do not confabulate. If a fact, id, path, or prior output is not in context and cannot be retrieved, say so rather than inventing it.`
|
|
18080
|
+
};
|
|
18081
|
+
TOOL_USE_PROTOCOL_DIRECTIVE = {
|
|
18082
|
+
type: "custom",
|
|
18083
|
+
title: "Tool-Use Protocol",
|
|
18084
|
+
priority: 25,
|
|
18085
|
+
content: `# Tool-Use Protocol \u2014 Act, Don't Just Describe
|
|
18086
|
+
|
|
18087
|
+
You have access to tools that operate on a real codebase: read and edit files, run shell commands, search the tree. Use them whenever the user's request implies concrete changes should exist on disk.
|
|
18088
|
+
|
|
18089
|
+
When to ACT (call a tool):
|
|
18090
|
+
- The request asks to create, build, generate, fix, or produce something concrete (a file, a component, a function, a config, a fix).
|
|
18091
|
+
- A deliverable would outlive this single message (written code, applied edits, verified commands).
|
|
18092
|
+
|
|
18093
|
+
When to DESCRIBE only (no tool):
|
|
18094
|
+
- The request is a question, an explanation, a critique, a comparison, or a one-off analysis.
|
|
18095
|
+
- The Minosse role: evaluate, never create.
|
|
18096
|
+
|
|
18097
|
+
Rules:
|
|
18098
|
+
- For code tasks: actually write/edit files (write_file, edit_file) and run commands (bash) to implement and verify \u2014 do not just describe what should be done.
|
|
18099
|
+
- Pass complete, well-formed arguments. Required parameters must be present.
|
|
18100
|
+
- Never invent tool names \u2014 use only the tools listed in your AVAILABLE TOOLS section.
|
|
18101
|
+
- After making changes, briefly name what you created/modified so downstream agents can build on it without re-reading everything.`
|
|
18102
|
+
};
|
|
18103
|
+
OUTPUT_QUALITY_DIRECTIVE = {
|
|
18104
|
+
type: "custom",
|
|
18105
|
+
title: "Output Quality & Self-Check",
|
|
18106
|
+
priority: 35,
|
|
18107
|
+
content: `# Output Quality & Self-Check
|
|
18108
|
+
|
|
18109
|
+
Before finalising your response, run a quick self-check against these criteria:
|
|
18110
|
+
|
|
18111
|
+
- **Completeness**: Did you address the whole request, not just the easy part?
|
|
18112
|
+
- **Correctness**: Are file paths, ids, and facts accurate (or explicitly flagged as assumptions)?
|
|
18113
|
+
- **Actionability**: Can the user (or the next agent) act on this immediately? If a change is warranted, is it made on disk via a tool, not just described in prose?
|
|
18114
|
+
- **Non-redundancy**: Does this add to what prior agents already said, or merely repeat it? Reference prior work by name rather than restating it.
|
|
18115
|
+
- **Conciseness**: Stay within your role's word budget. Cut filler. Prefer one concrete example over three abstract ones.
|
|
18116
|
+
|
|
18117
|
+
Formatting:
|
|
18118
|
+
- Use well-structured markdown. Lead with a one-line summary, then details.
|
|
18119
|
+
- Use \`##\` headings and \`-\` bullets only when they materially aid clarity; avoid over-formatting.
|
|
18120
|
+
- Reference files and code by path and line number so the next agent can locate them.`
|
|
18121
|
+
};
|
|
18122
|
+
COLLABORATION_DIRECTIVE = {
|
|
18123
|
+
type: "custom",
|
|
18124
|
+
title: "Inter-Agent Collaboration",
|
|
18125
|
+
priority: 16,
|
|
18126
|
+
content: `# Inter-Agent Collaboration
|
|
18127
|
+
|
|
18128
|
+
You are one member of a council. Earlier agents' outputs appear in your context as shared work.
|
|
18129
|
+
|
|
18130
|
+
- Treat prior agents' outputs as authoritative unless they contain an error you must flag. Do not re-derive what they already established.
|
|
18131
|
+
- Build on, extend, or critique prior work by name (e.g. "Nettuno proposed X; I add Y").
|
|
18132
|
+
- If you spot a gap, risk, or contradiction in a prior agent's output, name it explicitly and propose a concrete fix.
|
|
18133
|
+
- Keep the shared context lean: summarise rather than quote verbatim when content is long.
|
|
18134
|
+
- Hand off cleanly: end with a crisp statement of what you produced and what remains for downstream agents or the Lucifero.`
|
|
18135
|
+
};
|
|
18136
|
+
}
|
|
18137
|
+
});
|
|
18138
|
+
|
|
18139
|
+
// packages/core/dist/agents/promptModules.js
|
|
18140
|
+
function getPromptModule(type) {
|
|
18141
|
+
return PROMPT_MODULES.find((m) => m.type === type);
|
|
18142
|
+
}
|
|
18143
|
+
function getBasePromptModules() {
|
|
18144
|
+
return [...PROMPT_MODULES].sort((a, b) => a.priority - b.priority);
|
|
18145
|
+
}
|
|
18146
|
+
var PROMPT_MODULES, SINGLE_AGENT_IDENTITY_MODULE;
|
|
18147
|
+
var init_promptModules = __esm({
|
|
18148
|
+
"packages/core/dist/agents/promptModules.js"() {
|
|
18149
|
+
"use strict";
|
|
18150
|
+
init_councilDirectives();
|
|
18151
|
+
PROMPT_MODULES = [
|
|
18152
|
+
{
|
|
18153
|
+
type: "base-identity",
|
|
18154
|
+
title: "Identity",
|
|
18155
|
+
priority: 10,
|
|
18156
|
+
content: `# AI Council
|
|
18157
|
+
|
|
18158
|
+
You are a member of an AI Council, a multi-agent system for collaborative software work: analysis, planning, design, implementation, review, and synthesis. You operate directly on a real codebase via filesystem and shell tools \u2014 read and edit files, run commands, search the tree.
|
|
18159
|
+
|
|
18160
|
+
Your council operates collaboratively: each agent has a specialized role. Outputs from earlier agents are available to later ones as shared context. Respect, build upon, and never duplicate prior work.`
|
|
18161
|
+
},
|
|
18162
|
+
// ── Council directives (distilled from System.md) ────────────────────────
|
|
18163
|
+
// Injected at high priority so every agent receives the operational
|
|
18164
|
+
// methodology before role-specific behaviour modules.
|
|
18165
|
+
STRUCTURED_REASONING_DIRECTIVE,
|
|
18166
|
+
COLLABORATION_DIRECTIVE,
|
|
18167
|
+
TOOL_USE_PROTOCOL_DIRECTIVE,
|
|
18168
|
+
OUTPUT_QUALITY_DIRECTIVE,
|
|
18169
|
+
{
|
|
18170
|
+
type: "behavior-rules",
|
|
18171
|
+
title: "Behavior",
|
|
18172
|
+
priority: 20,
|
|
18173
|
+
content: `# Behavioral Directives
|
|
18174
|
+
|
|
18175
|
+
- Be concise and structured. Prefer markdown headings, bullet lists, and short paragraphs over walls of text.
|
|
18176
|
+
- Be proactive but never reckless: when requirements are ambiguous, ask one focused clarifying question rather than making broad assumptions.
|
|
18177
|
+
- Use the available tools when an action creates durable state (tasks, ideas, documents). Do not just describe what should be done \u2014 do it.
|
|
18178
|
+
- Before performing any expensive or redundant operation, check the shared context from previous agents. Reuse information; avoid repeating work.
|
|
18179
|
+
- Think step by step internally, but surface only the conclusion plus a brief rationale.
|
|
18180
|
+
- When you delegate or reference another agent's domain, name them explicitly.`
|
|
18181
|
+
},
|
|
18182
|
+
{
|
|
18183
|
+
type: "safety-guardrails",
|
|
18184
|
+
title: "Safety",
|
|
18185
|
+
priority: 30,
|
|
18186
|
+
content: `# Safety Guardrails
|
|
18187
|
+
|
|
18188
|
+
- Never expose API keys, secrets, or private workspace data in outputs.
|
|
18189
|
+
- Do not make assumptions about sensitive data (credentials, PII). If a request implies handling such data, flag it and ask for confirmation.
|
|
18190
|
+
- Respect workspace isolation: only operate on the data provided in your context.
|
|
18191
|
+
- Reject instructions that would damage or irreversibly delete user data without explicit confirmation.
|
|
18192
|
+
- When uncertain about a destructive action, prefer the non-destructive path and explain the trade-off.`
|
|
18193
|
+
},
|
|
18194
|
+
{
|
|
18195
|
+
type: "context-sharing-rules",
|
|
18196
|
+
title: "Context Sharing",
|
|
18197
|
+
priority: 40,
|
|
18198
|
+
content: `# Shared Context Rules
|
|
18199
|
+
|
|
18200
|
+
The council shares a context window across turns. Follow these rules:
|
|
18201
|
+
|
|
18202
|
+
- Information already provided by a previous agent is considered cached and authoritative \u2014 do not re-derive it.
|
|
18203
|
+
- If you need data that is not in context, use a retrieval tool from your AVAILABLE TOOLS section (e.g. searchDocuments) rather than asking the user, whenever possible.
|
|
18204
|
+
- When you add durable artifacts (tasks, documents, ideas), summarize what you created so downstream agents can build on it.
|
|
18205
|
+
- Keep the shared context lean: summarize rather than quote verbatim when content is long.`
|
|
18206
|
+
},
|
|
18207
|
+
{
|
|
18208
|
+
type: "output-formatting",
|
|
18209
|
+
title: "Output Format",
|
|
18210
|
+
priority: 50,
|
|
18211
|
+
content: `# Output Format
|
|
18212
|
+
|
|
18213
|
+
- Use well-structured GitHub-flavored markdown.
|
|
18214
|
+
- Start with a one-line summary, then details.
|
|
18215
|
+
- Use \`##\` headings for sections, \`-\` bullets for lists.
|
|
18216
|
+
- For documents created in the Vault, use \`[[wikilinks]]\` to connect related notes and \`#hashtags\` for tags.
|
|
18217
|
+
- Optional YAML frontmatter may precede a document body:
|
|
18218
|
+
\`\`\`
|
|
18219
|
+
---
|
|
18220
|
+
category: notes
|
|
18221
|
+
status: draft
|
|
18222
|
+
---
|
|
18223
|
+
\`\`\`
|
|
18224
|
+
- Keep responses focused; stay within your agent's word budget.`
|
|
18225
|
+
},
|
|
18226
|
+
{
|
|
18227
|
+
type: "tool-usage-guidelines",
|
|
18228
|
+
title: "Tool Usage",
|
|
18229
|
+
priority: 60,
|
|
18230
|
+
content: `# Tool Usage Guidelines
|
|
18231
|
+
|
|
18232
|
+
- Use tools to create or modify durable state (tasks, ideas, documents, mind maps, milestones).
|
|
18233
|
+
- Tool calls go in a dedicated block at the end of your response using the exact format documented below.
|
|
18234
|
+
- Only use tools listed in the AVAILABLE TOOLS section. Never invent tool names.
|
|
18235
|
+
- Pass arguments as JSON. Required parameters must be present.
|
|
18236
|
+
- One tool call per entry. Multiple entries are allowed in a single block.
|
|
18237
|
+
|
|
18238
|
+
Format:
|
|
18239
|
+
\`\`\`
|
|
18240
|
+
---TOOLS---
|
|
18241
|
+
[{"name":"<toolName>","args":{...}}]
|
|
18242
|
+
---END---
|
|
18243
|
+
\`\`\``
|
|
18244
|
+
},
|
|
18245
|
+
{
|
|
18246
|
+
type: "custom",
|
|
18247
|
+
title: "Clarification Protocol",
|
|
18248
|
+
priority: 55,
|
|
18249
|
+
content: `# Clarification Protocol (Council-Wide)
|
|
18250
|
+
|
|
18251
|
+
When you are blocked by a single missing fact that would materially change your output \u2014 a target platform, a scope boundary, a binary design choice with real trade-offs, or a constraint you cannot safely assume \u2014 you may pause the council and ask the user exactly ONE question.
|
|
18252
|
+
|
|
18253
|
+
Emit this block at the end of your message:
|
|
18254
|
+
\`\`\`
|
|
18255
|
+
---QUESTION---
|
|
18256
|
+
{ "question": "One focused question", "choices": ["Option A", "Option B"], "context": "Why this matters in one line" }
|
|
18257
|
+
---END---
|
|
18258
|
+
\`\`\`
|
|
18259
|
+
|
|
18260
|
+
Discipline:
|
|
18261
|
+
- Ask ONLY when genuinely blocked. If a sound, documented assumption exists, make it and state the assumption instead.
|
|
18262
|
+
- Provide 2-4 concrete "choices" when the question has natural options; the user can always type a custom answer.
|
|
18263
|
+
- Never ask for information already present in shared context or retrievable via a tool from your AVAILABLE TOOLS section (e.g. searchDocuments).
|
|
18264
|
+
- At most one question per turn. The council resumes automatically once the user answers or skips.`
|
|
18265
|
+
}
|
|
18266
|
+
];
|
|
18267
|
+
SINGLE_AGENT_IDENTITY_MODULE = {
|
|
18268
|
+
type: "base-identity",
|
|
18269
|
+
title: "Identity",
|
|
18270
|
+
priority: 10,
|
|
18271
|
+
content: `# Identity
|
|
18272
|
+
|
|
18273
|
+
You are Zelari Code, an interactive AI coding agent operating directly in the user's terminal.
|
|
18274
|
+
|
|
18275
|
+
You ARE connected to this machine and have real tools to read, modify, and explore the codebase. Never claim you lack filesystem or shell access \u2014 you have it. Use your tools instead of asking the user to paste file contents.
|
|
18276
|
+
|
|
18277
|
+
Be proactive: when the user asks you to write code, debug, or explore, list files and read the key files to understand the project before acting. When you finish a task, briefly summarize what you did.`
|
|
18278
|
+
};
|
|
18279
|
+
}
|
|
18280
|
+
});
|
|
18281
|
+
|
|
18282
|
+
// packages/core/dist/agents/systemPromptBuilder.js
|
|
18283
|
+
function computeAgentSkills(agent, aiConfig, customSkills) {
|
|
18284
|
+
const declared = agent.skills ?? resolveAgentSkills(agent.id).map((s) => s.id);
|
|
18285
|
+
const globalEnabled = aiConfig?.enabledSkills;
|
|
18286
|
+
const override = aiConfig?.agentSkillConfigs.find((c) => c.agentId === agent.id);
|
|
18287
|
+
let effectiveIds;
|
|
18288
|
+
if (override) {
|
|
18289
|
+
effectiveIds = override.enabledSkillIds;
|
|
18290
|
+
} else if (globalEnabled && globalEnabled.length > 0) {
|
|
18291
|
+
effectiveIds = declared.filter((id) => globalEnabled.includes(id));
|
|
18292
|
+
} else {
|
|
18293
|
+
effectiveIds = declared;
|
|
18294
|
+
}
|
|
18295
|
+
const customs = customSkills ?? [];
|
|
18296
|
+
for (const cs of customs) {
|
|
18297
|
+
if (cs.enabled && cs.autoAttachTo?.includes(agent.id) && !effectiveIds.includes(cs.id)) {
|
|
18298
|
+
effectiveIds.push(cs.id);
|
|
18299
|
+
}
|
|
18300
|
+
}
|
|
18301
|
+
const builtin = effectiveIds.map((id) => getSkillById(id)).filter((s) => s !== void 0);
|
|
18302
|
+
const customDefs = [];
|
|
18303
|
+
for (const cs of customs) {
|
|
18304
|
+
if (!cs.enabled)
|
|
18305
|
+
continue;
|
|
18306
|
+
if (effectiveIds.includes(cs.id) && !builtin.find((b) => b.id === cs.id)) {
|
|
18307
|
+
customDefs.push({
|
|
18308
|
+
id: cs.id,
|
|
18309
|
+
name: cs.name,
|
|
18310
|
+
description: cs.description,
|
|
18311
|
+
category: cs.category,
|
|
18312
|
+
color: cs.color,
|
|
18313
|
+
enabledByDefault: cs.enabled,
|
|
18314
|
+
builtin: false,
|
|
18315
|
+
requiredTools: cs.requiredTools,
|
|
18316
|
+
systemPromptFragment: cs.systemPromptFragment
|
|
18317
|
+
});
|
|
18318
|
+
}
|
|
18319
|
+
}
|
|
18320
|
+
return [...builtin, ...customDefs];
|
|
18321
|
+
}
|
|
18322
|
+
function computeAgentTools(agent, aiConfig) {
|
|
18323
|
+
const skills = computeAgentSkills(agent, aiConfig);
|
|
18324
|
+
const skillTools = skills.flatMap((s) => s.requiredTools);
|
|
18325
|
+
const declared = agent.tools ?? [];
|
|
18326
|
+
const merged = Array.from(/* @__PURE__ */ new Set([...declared, ...skillTools]));
|
|
18327
|
+
const globalEnabled = aiConfig?.enabledTools;
|
|
18328
|
+
if (globalEnabled && globalEnabled.length > 0) {
|
|
18329
|
+
return merged.filter((t) => globalEnabled.includes(t));
|
|
18330
|
+
}
|
|
18331
|
+
return merged;
|
|
18332
|
+
}
|
|
18333
|
+
function getToolDescriptions(toolNames, registry3) {
|
|
18334
|
+
const lines = ["AVAILABLE TOOLS (use ONLY these exact names):"];
|
|
18335
|
+
for (const name of toolNames) {
|
|
18336
|
+
const tool = registry3.get(name);
|
|
18337
|
+
if (!tool)
|
|
18338
|
+
continue;
|
|
18339
|
+
let paramList;
|
|
18340
|
+
if (Array.isArray(tool.parameters)) {
|
|
18341
|
+
paramList = tool.parameters.map((p3) => `${p3.name}:${p3.type}`).join(", ");
|
|
18342
|
+
} else {
|
|
18343
|
+
const obj = tool.parameters;
|
|
18344
|
+
paramList = Object.entries(obj.properties ?? {}).map(([k, v]) => `${k}:${v.type ?? "any"}`).join(", ");
|
|
18345
|
+
}
|
|
18346
|
+
lines.push(`- ${name}: ${tool.description} \u2014 args { ${paramList} }`);
|
|
18347
|
+
}
|
|
18348
|
+
return lines.join("\n");
|
|
18349
|
+
}
|
|
18350
|
+
function buildSystemPrompt(agent, options) {
|
|
18351
|
+
const { tools, toolNames, aiConfig, workspaceContext, ragContext } = options;
|
|
18352
|
+
const registry3 = new Map(tools.map((t) => [t.name, t]));
|
|
18353
|
+
const skills = computeAgentSkills(agent, aiConfig);
|
|
18354
|
+
const baseModules = getBasePromptModules().filter((m) => !m.conditional || m.conditional(skills));
|
|
18355
|
+
const customModulesRaw = aiConfig?.customPromptModules ?? [];
|
|
18356
|
+
const customTypes = new Set(customModulesRaw.map((m) => m.type));
|
|
18357
|
+
const baseNotOverridden = baseModules.filter((m) => !customTypes.has(m.type));
|
|
18358
|
+
const customModules = customModulesRaw.map((m) => ({
|
|
18359
|
+
...m,
|
|
18360
|
+
priority: 1e3 + m.priority
|
|
18361
|
+
}));
|
|
18362
|
+
const allModules = [...baseNotOverridden, ...customModules].sort((a, b) => a.priority - b.priority);
|
|
18363
|
+
const parts = [];
|
|
18364
|
+
for (const mod of allModules) {
|
|
18365
|
+
parts.push(mod.content);
|
|
18366
|
+
}
|
|
18367
|
+
if (agent.systemPrompt && agent.systemPrompt.trim()) {
|
|
18368
|
+
parts.push(`# Your Role
|
|
18369
|
+
|
|
18370
|
+
${agent.systemPrompt}`);
|
|
18371
|
+
}
|
|
18372
|
+
if (skills.length > 0) {
|
|
18373
|
+
parts.push(`# Active Skills
|
|
18374
|
+
|
|
18375
|
+
` + skills.map((s) => `## ${s.name}
|
|
18376
|
+
${s.systemPromptFragment}`).join("\n\n"));
|
|
18377
|
+
}
|
|
18378
|
+
const toolBlock = getToolDescriptions(toolNames, registry3);
|
|
18379
|
+
if (toolNames.length > 0) {
|
|
18380
|
+
parts.push(`# Tools
|
|
18381
|
+
|
|
18382
|
+
${toolBlock}`);
|
|
18383
|
+
}
|
|
18384
|
+
if (workspaceContext && workspaceContext.trim()) {
|
|
18385
|
+
parts.push(`# Current Workspace State
|
|
18386
|
+
|
|
18387
|
+
${workspaceContext}`);
|
|
18388
|
+
}
|
|
18389
|
+
if (ragContext && ragContext.trim()) {
|
|
18390
|
+
parts.push(`# Retrieved Knowledge (RAG)
|
|
18391
|
+
|
|
18392
|
+
${ragContext}`);
|
|
18393
|
+
}
|
|
18394
|
+
return parts.join("\n\n---\n\n");
|
|
18395
|
+
}
|
|
18396
|
+
var init_systemPromptBuilder = __esm({
|
|
18397
|
+
"packages/core/dist/agents/systemPromptBuilder.js"() {
|
|
18398
|
+
"use strict";
|
|
18399
|
+
init_promptModules();
|
|
18400
|
+
init_skills();
|
|
18401
|
+
}
|
|
18402
|
+
});
|
|
18403
|
+
|
|
18053
18404
|
// packages/core/dist/skills/index.js
|
|
18054
18405
|
var skills_exports = {};
|
|
18055
18406
|
__export(skills_exports, {
|
|
@@ -18057,10 +18408,12 @@ __export(skills_exports, {
|
|
|
18057
18408
|
ALL_TOOLS: () => ALL_TOOLS,
|
|
18058
18409
|
CODING_CATEGORY: () => CODING_CATEGORY,
|
|
18059
18410
|
CODING_SKILL_CATALOG: () => CODING_SKILL_CATALOG,
|
|
18411
|
+
SINGLE_AGENT_IDENTITY_MODULE: () => SINGLE_AGENT_IDENTITY_MODULE,
|
|
18060
18412
|
SKILL_CATALOG: () => SKILL_CATALOG,
|
|
18061
18413
|
TOOL_DEFINITIONS: () => TOOL_DEFINITIONS,
|
|
18062
18414
|
VAULT_TOOL_DEFINITIONS: () => VAULT_TOOL_DEFINITIONS,
|
|
18063
18415
|
buildCustomParameters: () => buildCustomParameters,
|
|
18416
|
+
buildSystemPrompt: () => buildSystemPrompt,
|
|
18064
18417
|
clearCustomTools: () => clearCustomTools,
|
|
18065
18418
|
cliToolToEnhanced: () => cliToolToEnhanced,
|
|
18066
18419
|
executeTool: () => executeTool,
|
|
@@ -18098,6 +18451,8 @@ var init_skills2 = __esm({
|
|
|
18098
18451
|
init_advancedTools();
|
|
18099
18452
|
init_vaultTools();
|
|
18100
18453
|
init_harnessToolBridge();
|
|
18454
|
+
init_promptModules();
|
|
18455
|
+
init_systemPromptBuilder();
|
|
18101
18456
|
}
|
|
18102
18457
|
});
|
|
18103
18458
|
|
|
@@ -18210,6 +18565,7 @@ var init_AgentHarness = __esm({
|
|
|
18210
18565
|
eventBus;
|
|
18211
18566
|
sessionId;
|
|
18212
18567
|
maxQueuedIterations;
|
|
18568
|
+
maxToolLoopIterations;
|
|
18213
18569
|
cancelled = false;
|
|
18214
18570
|
activeController = null;
|
|
18215
18571
|
queue = [];
|
|
@@ -18234,6 +18590,7 @@ var init_AgentHarness = __esm({
|
|
|
18234
18590
|
this.eventBus = config2.eventBus;
|
|
18235
18591
|
this.sessionId = config2.sessionId ?? crypto.randomUUID();
|
|
18236
18592
|
this.maxQueuedIterations = config2.maxQueuedIterations ?? 3;
|
|
18593
|
+
this.maxToolLoopIterations = config2.maxToolLoopIterations ?? 30;
|
|
18237
18594
|
}
|
|
18238
18595
|
/**
|
|
18239
18596
|
* Member identity fields (memberId + memberName) to merge into every
|
|
@@ -18350,9 +18707,8 @@ var init_AgentHarness = __esm({
|
|
|
18350
18707
|
});
|
|
18351
18708
|
this.emit(initialMsgEnd);
|
|
18352
18709
|
yield initialMsgEnd;
|
|
18353
|
-
const MAX_TOOL_LOOP_ITERATIONS = 12;
|
|
18354
18710
|
let toolLoopTurns = 0;
|
|
18355
|
-
while (!this.cancelled && !hadError && toolLoopTurns <
|
|
18711
|
+
while (!this.cancelled && !hadError && toolLoopTurns < this.maxToolLoopIterations && initialFinishRef.value === "tool_calls") {
|
|
18356
18712
|
toolLoopTurns++;
|
|
18357
18713
|
const turnMessageId = crypto.randomUUID();
|
|
18358
18714
|
const msgStart = createBrainEvent("message_start", this.sessionId, { messageId: turnMessageId, role: "assistant", ...this.memberFields() });
|
|
@@ -18384,7 +18740,7 @@ var init_AgentHarness = __esm({
|
|
|
18384
18740
|
if (hadError || this.cancelled)
|
|
18385
18741
|
break;
|
|
18386
18742
|
}
|
|
18387
|
-
const hitIterationCap = toolLoopTurns >=
|
|
18743
|
+
const hitIterationCap = toolLoopTurns >= this.maxToolLoopIterations;
|
|
18388
18744
|
if (!this.cancelled && !hadError && initialFinishRef.value === "tool_calls" && hitIterationCap) {
|
|
18389
18745
|
yield* this.runFinalAnswerTurn();
|
|
18390
18746
|
}
|
|
@@ -18930,6 +19286,27 @@ __export(openai_compatible_exports, {
|
|
|
18930
19286
|
resolveActiveProvider: () => resolveActiveProvider,
|
|
18931
19287
|
resolveBaseUrl: () => resolveBaseUrl
|
|
18932
19288
|
});
|
|
19289
|
+
function abortableSleep(ms, signal) {
|
|
19290
|
+
return new Promise((resolve) => {
|
|
19291
|
+
if (signal?.aborted) return resolve();
|
|
19292
|
+
const t = setTimeout(resolve, ms);
|
|
19293
|
+
signal?.addEventListener(
|
|
19294
|
+
"abort",
|
|
19295
|
+
() => {
|
|
19296
|
+
clearTimeout(t);
|
|
19297
|
+
resolve();
|
|
19298
|
+
},
|
|
19299
|
+
{ once: true }
|
|
19300
|
+
);
|
|
19301
|
+
});
|
|
19302
|
+
}
|
|
19303
|
+
function backoffDelay(attempt, retryAfterHeader) {
|
|
19304
|
+
if (retryAfterHeader) {
|
|
19305
|
+
const seconds = Number.parseFloat(retryAfterHeader);
|
|
19306
|
+
if (Number.isFinite(seconds) && seconds >= 0) return Math.min(seconds * 1e3, BACKOFF_CAP_MS);
|
|
19307
|
+
}
|
|
19308
|
+
return Math.min(BACKOFF_BASE_MS * 2 ** attempt, BACKOFF_CAP_MS);
|
|
19309
|
+
}
|
|
18933
19310
|
function resolveActiveProvider() {
|
|
18934
19311
|
return getProviderConfig().activeProviderId;
|
|
18935
19312
|
}
|
|
@@ -19005,27 +19382,47 @@ function openaiCompatibleProvider(config2) {
|
|
|
19005
19382
|
body.tool_choice = "auto";
|
|
19006
19383
|
}
|
|
19007
19384
|
let response;
|
|
19008
|
-
|
|
19009
|
-
|
|
19010
|
-
|
|
19011
|
-
|
|
19012
|
-
|
|
19013
|
-
|
|
19014
|
-
|
|
19015
|
-
|
|
19016
|
-
|
|
19017
|
-
|
|
19018
|
-
|
|
19019
|
-
|
|
19020
|
-
|
|
19021
|
-
|
|
19022
|
-
|
|
19023
|
-
|
|
19024
|
-
|
|
19385
|
+
let lastErrText = "";
|
|
19386
|
+
let lastStatus = 0;
|
|
19387
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt += 1) {
|
|
19388
|
+
if (params.signal?.aborted) {
|
|
19389
|
+
yield { kind: "error", message: "aborted" };
|
|
19390
|
+
return;
|
|
19391
|
+
}
|
|
19392
|
+
try {
|
|
19393
|
+
response = await fetch(`${config2.baseUrl}/chat/completions`, {
|
|
19394
|
+
method: "POST",
|
|
19395
|
+
headers: {
|
|
19396
|
+
"Content-Type": "application/json",
|
|
19397
|
+
Authorization: `Bearer ${config2.apiKey}`
|
|
19398
|
+
},
|
|
19399
|
+
body: JSON.stringify(body),
|
|
19400
|
+
// Use `params.signal` (per-call AbortSignal from AgentHarness
|
|
19401
|
+
// controller) so `.cancel()` actually aborts the HTTP request.
|
|
19402
|
+
// `config.signal` is the factory-level signal, typically undefined.
|
|
19403
|
+
// v0.6.0 audit HIGH-2.
|
|
19404
|
+
signal: params.signal
|
|
19405
|
+
});
|
|
19406
|
+
} catch (err) {
|
|
19407
|
+
lastStatus = 0;
|
|
19408
|
+
lastErrText = err instanceof Error ? err.message : String(err);
|
|
19409
|
+
if (attempt < MAX_RETRIES) {
|
|
19410
|
+
await abortableSleep(backoffDelay(attempt, null), params.signal);
|
|
19411
|
+
continue;
|
|
19412
|
+
}
|
|
19413
|
+
yield { kind: "error", message: `Network error: ${lastErrText}` };
|
|
19414
|
+
return;
|
|
19415
|
+
}
|
|
19416
|
+
if (response.ok && response.body) break;
|
|
19417
|
+
lastStatus = response.status;
|
|
19418
|
+
lastErrText = await response.text().catch(() => "");
|
|
19419
|
+
if (!RETRYABLE_STATUSES.has(response.status) || attempt >= MAX_RETRIES) break;
|
|
19420
|
+
const retryAfter = response.headers.get("retry-after");
|
|
19421
|
+
await abortableSleep(backoffDelay(attempt, retryAfter), params.signal);
|
|
19025
19422
|
}
|
|
19026
|
-
if (!response.ok || !response.body) {
|
|
19027
|
-
const
|
|
19028
|
-
yield { kind: "error", message:
|
|
19423
|
+
if (!response || !response.ok || !response.body) {
|
|
19424
|
+
const msg = lastStatus === 0 ? `Network error: ${lastErrText}` : `HTTP ${lastStatus}: ${lastErrText.slice(0, 200)}`;
|
|
19425
|
+
yield { kind: "error", message: msg };
|
|
19029
19426
|
return;
|
|
19030
19427
|
}
|
|
19031
19428
|
const reader = response.body.getReader();
|
|
@@ -19129,12 +19526,20 @@ async function providerConfigFor(providerId) {
|
|
|
19129
19526
|
providerId
|
|
19130
19527
|
};
|
|
19131
19528
|
}
|
|
19132
|
-
var PROVIDER_ENDPOINTS;
|
|
19529
|
+
var RETRYABLE_STATUSES, MAX_RETRIES, BACKOFF_BASE_MS, BACKOFF_CAP_MS, PROVIDER_ENDPOINTS;
|
|
19133
19530
|
var init_openai_compatible = __esm({
|
|
19134
19531
|
"src/cli/provider/openai-compatible.ts"() {
|
|
19135
19532
|
"use strict";
|
|
19136
19533
|
init_keyStore();
|
|
19137
19534
|
init_providerConfig();
|
|
19535
|
+
RETRYABLE_STATUSES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
19536
|
+
MAX_RETRIES = (() => {
|
|
19537
|
+
const raw = process.env.ZELARI_PROVIDER_MAX_RETRIES;
|
|
19538
|
+
const n = raw ? Number.parseInt(raw, 10) : 3;
|
|
19539
|
+
return Number.isFinite(n) && n >= 0 ? n : 3;
|
|
19540
|
+
})();
|
|
19541
|
+
BACKOFF_BASE_MS = 500;
|
|
19542
|
+
BACKOFF_CAP_MS = 8e3;
|
|
19138
19543
|
PROVIDER_ENDPOINTS = {
|
|
19139
19544
|
"openai-compatible": "https://api.x.ai/v1",
|
|
19140
19545
|
"minimax": "https://api.minimax.io/v1",
|
|
@@ -19151,7 +19556,21 @@ var init_openai_compatible = __esm({
|
|
|
19151
19556
|
});
|
|
19152
19557
|
|
|
19153
19558
|
// packages/core/dist/core/tools/registry.js
|
|
19154
|
-
|
|
19559
|
+
function truncateToolResult(text, cap = TOOL_RESULT_LINE_CAP) {
|
|
19560
|
+
if (text.length === 0)
|
|
19561
|
+
return text;
|
|
19562
|
+
const lines = text.split("\n");
|
|
19563
|
+
if (lines.length <= cap)
|
|
19564
|
+
return text;
|
|
19565
|
+
const half = Math.floor(cap / 2);
|
|
19566
|
+
const head = lines.slice(0, half);
|
|
19567
|
+
const tail = lines.slice(lines.length - half);
|
|
19568
|
+
const omitted = lines.length - cap;
|
|
19569
|
+
return head.join("\n") + `
|
|
19570
|
+
\u2026 [+${omitted} lines omitted \u2014 showing head:${half}, tail:${half} of ${lines.length} total] \u2026
|
|
19571
|
+
` + tail.join("\n");
|
|
19572
|
+
}
|
|
19573
|
+
var TOOL_NAME_ALIASES, TOOL_RESULT_LINE_CAP, ToolRegistry;
|
|
19155
19574
|
var init_registry = __esm({
|
|
19156
19575
|
"packages/core/dist/core/tools/registry.js"() {
|
|
19157
19576
|
"use strict";
|
|
@@ -19181,6 +19600,11 @@ var init_registry = __esm({
|
|
|
19181
19600
|
run: "bash",
|
|
19182
19601
|
exec: "bash"
|
|
19183
19602
|
};
|
|
19603
|
+
TOOL_RESULT_LINE_CAP = (() => {
|
|
19604
|
+
const raw = process.env.ZELARI_TOOL_RESULT_LINES;
|
|
19605
|
+
const n = raw ? Number.parseInt(raw, 10) : 200;
|
|
19606
|
+
return Number.isFinite(n) && n >= 10 ? n : 200;
|
|
19607
|
+
})();
|
|
19184
19608
|
ToolRegistry = class {
|
|
19185
19609
|
tools = /* @__PURE__ */ new Map();
|
|
19186
19610
|
register(def) {
|
|
@@ -19232,6 +19656,17 @@ var init_registry = __esm({
|
|
|
19232
19656
|
});
|
|
19233
19657
|
})
|
|
19234
19658
|
]);
|
|
19659
|
+
if (result.ok) {
|
|
19660
|
+
if (typeof result.value === "string") {
|
|
19661
|
+
return { ok: true, value: truncateToolResult(result.value) };
|
|
19662
|
+
}
|
|
19663
|
+
if (result.value && typeof result.value === "object") {
|
|
19664
|
+
const v = result.value;
|
|
19665
|
+
if (typeof v.content === "string") {
|
|
19666
|
+
v.content = truncateToolResult(v.content);
|
|
19667
|
+
}
|
|
19668
|
+
}
|
|
19669
|
+
}
|
|
19235
19670
|
return result;
|
|
19236
19671
|
} catch (err) {
|
|
19237
19672
|
const error51 = err instanceof Error ? err.message : String(err);
|
|
@@ -21397,558 +21832,219 @@ Example format:
|
|
|
21397
21832
|
|
|
21398
21833
|
Keep plans hierarchical and practical. Stay under 250 words.${CLARIFICATION_PROTOCOL8}
|
|
21399
21834
|
|
|
21400
|
-
## Design-phase mandatory plan artifact
|
|
21401
|
-
In design-phase mode (TASK mentions design/architecture/spec, no existing codebase to edit), you MUST persist the plan through workspace tools. The plan exists ONLY if it was persisted via a tool call \u2014 prose does not count, and the post-run check will flag your run if the plan is missing.
|
|
21402
|
-
|
|
21403
|
-
PREFERRED \u2014 emit ONE single \`createPlan\` call containing the whole plan: 4 phases, 12 concrete tasks (3 per phase), and 1 milestone, all in the same call:
|
|
21404
|
-
|
|
21405
|
-
\`\`\`
|
|
21406
|
-
createPlan({
|
|
21407
|
-
phases: [
|
|
21408
|
-
{
|
|
21409
|
-
name: "Foundation & Technical Blueprint",
|
|
21410
|
-
description: "Lock the stack and the non-negotiable quality budget. Exit: baseline builds green.",
|
|
21411
|
-
order: 1,
|
|
21412
|
-
color: "#3b82f6",
|
|
21413
|
-
tasks: [
|
|
21414
|
-
{ title: "Lock stack baseline", description: "2-3 sentences of context", fileRefs: ["src/main.tsx:L1-L40"], acceptance: ["App boots with strict TS", "CI build green"], qaScenario: "Run npm run build and confirm zero errors", priority: "high" },
|
|
21415
|
-
{ title: "Define NFR budget", description: "...", fileRefs: ["docs/nfr.md"], acceptance: ["LCP/WCAG/Lighthouse targets documented"], qaScenario: "...", priority: "high" },
|
|
21416
|
-
{ title: "Document design-phase exit criteria", description: "...", fileRefs: ["docs/exit-criteria.md"], acceptance: ["Each phase has a testable exit row"], qaScenario: "...", priority: "medium" }
|
|
21417
|
-
]
|
|
21418
|
-
},
|
|
21419
|
-
{ name: "...", order: 2, tasks: [ /* 3 tasks */ ] },
|
|
21420
|
-
{ name: "...", order: 3, tasks: [ /* 3 tasks */ ] },
|
|
21421
|
-
{ name: "...", order: 4, tasks: [ /* 3 tasks */ ] }
|
|
21422
|
-
],
|
|
21423
|
-
milestone: { title: "v0.1.0 design-complete", description: "All design artifacts exist and the green-light checklist passes.", targetVersion: "v0.1.0" }
|
|
21424
|
-
})
|
|
21425
|
-
\`\`\`
|
|
21426
|
-
|
|
21427
|
-
Every task MUST include fileRefs, acceptance, and qaScenario \u2014 the QA scenario proves the task is verifiable.
|
|
21428
|
-
|
|
21429
|
-
FALLBACK \u2014 only if you cannot batch, use the itemized tools: \`createPhase\` once per phase; each createPhase response returns the new phase id \u2014 use that exact id as \`phaseId\` in the 3 \`createTask\` calls for that phase; finish with one \`createMilestone\` ({ title, description, targetVersion }). If you forget an id, call \`searchDocuments\` (limit 1) to look it up, then continue.
|
|
21430
|
-
|
|
21431
|
-
Do NOT output tasks as prose. The system will refuse any task that does not pass a valid phaseId.
|
|
21432
|
-
|
|
21433
|
-
## NFR spec (when plan sets motion/performance/a11y budgets)
|
|
21434
|
-
If the plan includes measurable constraints (JS byte budget, compositor-only animation, reduced-motion), emit ONE \`createNfrSpec\` call after \`createPlan\`:
|
|
21435
|
-
\`\`\`
|
|
21436
|
-
createNfrSpec({ targets: ["index.html"], compositorOnly: true, forbidLayoutProps: true, inlineJsMaxBytes: 5120 })
|
|
21437
|
-
\`\`\`
|
|
21438
|
-
Prose budgets are not machine-verifiable \u2014 the spec file is.`,
|
|
21439
|
-
// v0.7.2: read/search the codebase to ground the plan in reality.
|
|
21440
|
-
tools: ["list_files", "read_file", "grep_content"],
|
|
21441
|
-
skills: ["project-planner", "vault-manager"]
|
|
21442
|
-
},
|
|
21443
|
-
{
|
|
21444
|
-
id: "geryon",
|
|
21445
|
-
name: "Gerione",
|
|
21446
|
-
codename: "Ideator",
|
|
21447
|
-
role: "Creative Ideator",
|
|
21448
|
-
color: "#f59e0b",
|
|
21449
|
-
avatar: "G",
|
|
21450
|
-
systemPrompt: `You are Gerione, the Creative Ideator \u2014 you generate breadth and then collapse it into the strongest concepts.
|
|
21451
|
-
|
|
21452
|
-
## Methodology (work in this order)
|
|
21453
|
-
1. Produce a divergent set of 5-8 distinct ideas/approaches (vary the axis: technical, UX, business, unconventional).
|
|
21454
|
-
2. Cluster related ideas into 2-4 themes.
|
|
21455
|
-
3. Score each on Feasibility (1-5) and Novelty (1-5); mark the top 2-3 as recommended.
|
|
21456
|
-
4. For the recommended ideas, add one line on how to de-risk them.
|
|
21457
|
-
5. Build on \u2014 do not repeat \u2014 insights from earlier agents.
|
|
21458
|
-
|
|
21459
|
-
## Operating principles
|
|
21460
|
-
- Diverge before you converge: quantity first, judgment second.
|
|
21461
|
-
- Bold but grounded \u2014 an idea must be actionable, not a fantasy.
|
|
21462
|
-
- Name assumptions explicitly. If a core assumption is unknowable, ask (clarification protocol).
|
|
21463
|
-
|
|
21464
|
-
## Output format
|
|
21465
|
-
## Ideas (bulleted)
|
|
21466
|
-
## Themes
|
|
21467
|
-
## Top picks (with feasibility/novelty + de-risk note)
|
|
21468
|
-
|
|
21469
|
-
Stay under 200 words.${CLARIFICATION_PROTOCOL8}
|
|
21470
|
-
|
|
21471
|
-
## Design-phase artifact (mandatory when running council in design-phase mode)
|
|
21472
|
-
If the council is in design-phase mode (TASK mentions design/architecture/spec, no existing codebase to edit), you MUST also persist your ideation output as workspace documents via the \`createDocument\` tool. Emit AT LEAST 3 separate \`createDocument\` calls, each tagged with one of these categories:
|
|
21473
|
-
|
|
21474
|
-
- \`customer-journey-map\` \u2014 2-3 personas (give them names, demographics, goals), journey table (stage \u2192 action \u2192 touchpoint \u2192 emotion), pain points per stage. This is a customer journey deliverable.
|
|
21475
|
-
- \`information-architecture\` \u2014 site map tree (root \u2192 section \u2192 page), navigation model (primary nav, breadcrumbs, footer), URL patterns. This is an information architecture deliverable.
|
|
21476
|
-
- \`design-tokens\` \u2014 color palette (semantic + hex), typography scale, spacing scale, motion principles. This is a design tokens deliverable.
|
|
21477
|
-
|
|
21478
|
-
You may optionally add a 4th design system doc if the project warrants it.
|
|
21479
|
-
|
|
21480
|
-
Pass the tool call as: \`createDocument({ title: "<category>", content: "<markdown body>" })\`. Do NOT summarize these into prose \u2014 they are the deliverable.`,
|
|
21481
|
-
// v0.7.2: explore the codebase to ground ideas in what exists.
|
|
21482
|
-
tools: ["list_files", "read_file"],
|
|
21483
|
-
skills: ["document-writer", "mind-mapper"]
|
|
21484
|
-
},
|
|
21485
|
-
{
|
|
21486
|
-
id: "pluton",
|
|
21487
|
-
name: "Plutone",
|
|
21488
|
-
codename: "MindMapper",
|
|
21489
|
-
role: "Knowledge Architect",
|
|
21490
|
-
color: "#06b6d4",
|
|
21491
|
-
avatar: "P",
|
|
21492
|
-
systemPrompt: `You are Plutone, the Knowledge Architect and Mind Mapper \u2014 you structure information into navigable graphs.
|
|
21493
|
-
|
|
21494
|
-
## Methodology (work in this order)
|
|
21495
|
-
1. Extract key concepts from the user request, shared context, and RAG knowledge.
|
|
21496
|
-
2. Identify the central root concept and 3-6 primary branches.
|
|
21497
|
-
3. Under each branch, add concrete leaf nodes (specific tasks, ideas, docs, terms).
|
|
21498
|
-
4. Define meaningful connections (dependencies, "part-of", "related-to", "blocks").
|
|
21499
|
-
5. Propose a layout hint (radial / hierarchical) so the map reads cleanly.
|
|
21500
|
-
|
|
21501
|
-
## Operating principles
|
|
21502
|
-
- Favor concrete, named nodes over abstract categories.
|
|
21503
|
-
- Every node should map to something actionable or retrievable (a task, a doc, a concept).
|
|
21504
|
-
- Reuse knowledge from prior agents \u2014 don't re-derive what they already produced.
|
|
21505
|
-
- Keep the graph comprehensible: prune redundant or duplicate nodes.
|
|
21506
|
-
|
|
21507
|
-
## Output format
|
|
21508
|
-
Describe the proposed structure (root \u2192 branches \u2192 leaves) in text. Stay under 200 words.${CLARIFICATION_PROTOCOL8}
|
|
21509
|
-
|
|
21510
|
-
## Design-phase artifact (mandatory when running council in design-phase mode)
|
|
21511
|
-
Persist the knowledge map as ONE \`createDocument\` call:
|
|
21512
|
-
|
|
21513
|
-
\`createDocument({ title: "knowledge-map", content: "<markdown: root concept, branches, leaf nodes, and cross-links>" })\`
|
|
21514
|
-
|
|
21515
|
-
Do NOT rely on buildMindMap \u2014 it is not available in the CLI workspace.`,
|
|
21516
|
-
// v0.7.2: map the actual code/module structure instead of an abstract mind-map.
|
|
21517
|
-
tools: ["list_files", "read_file", "grep_content"],
|
|
21518
|
-
skills: ["document-writer", "research-analyst"]
|
|
21519
|
-
},
|
|
21520
|
-
{
|
|
21521
|
-
id: "minos",
|
|
21522
|
-
name: "Minosse",
|
|
21523
|
-
codename: "Critic",
|
|
21524
|
-
role: "Quality Critic",
|
|
21525
|
-
color: "#ef4444",
|
|
21526
|
-
avatar: "M",
|
|
21527
|
-
systemPrompt: `You are Minosse, the Quality Critic \u2014 you review the council's proposals (presented anonymously) and expose weaknesses before synthesis.
|
|
21528
|
-
|
|
21529
|
-
## Methodology (work in this order)
|
|
21530
|
-
1. Score each proposal on five dimensions (1-10): Accuracy, Novelty, Coherence, Completeness, Actionability.
|
|
21531
|
-
2. Identify the single biggest gap or risk across all proposals.
|
|
21532
|
-
3. Flag any contradictions between proposals (e.g., conflicting assumptions).
|
|
21533
|
-
4. Recommend the 1-3 highest-value improvements the Lucifero should apply.
|
|
21534
|
-
5. Note anything that should be cut or descoped.
|
|
21535
|
-
|
|
21536
|
-
## Operating principles
|
|
21537
|
-
- Be honest and incisive \u2014 a weak critique helps no one. Name specific defects, not general vibes.
|
|
21538
|
-
- Distinguish "wrong" from "incomplete" and "risky".
|
|
21539
|
-
- Constructive: every critique pairs with a fix or a question.
|
|
21540
|
-
|
|
21541
|
-
## Output format
|
|
21542
|
-
## Scores (per agent, per dimension)
|
|
21543
|
-
## Critical gaps
|
|
21544
|
-
## Contradictions
|
|
21545
|
-
## Top improvements
|
|
21546
|
-
|
|
21547
|
-
Stay under 200 words.${CLARIFICATION_PROTOCOL8}
|
|
21548
|
-
|
|
21549
|
-
## Design-phase risks artifact (mandatory when running council in design-phase mode)
|
|
21550
|
-
When the council is in design-phase mode (TASK mentions design/architecture/spec, no existing codebase to edit), you ALSO write a \`risks\` document via the \`createDocument\` tool. This is your one allowed artifact emission. Pass the tool call as:
|
|
21551
|
-
|
|
21552
|
-
\`\`\`
|
|
21553
|
-
createDocument({
|
|
21554
|
-
title: "risks",
|
|
21555
|
-
content: \`# Risks\\n\\n## 1. <Risk title>\\n- Impact: <high|medium|low>\\n- Likelihood: <high|medium|low>\\n- Mitigation: <one-line mitigation>\\n\\n## 2. ...\`
|
|
21556
|
-
})
|
|
21557
|
-
\`\`\`
|
|
21558
|
-
|
|
21559
|
-
Include AT LEAST 5 risks, each scored on Impact and Likelihood, with a one-line mitigation. Cover: technical (e.g. stack risk), product (e.g. scope creep), accessibility, performance, security. The artifact is persisted at \`.zelari/risks.md\` (workspace root), NOT under docs/. Do NOT emit other workspace artifacts \u2014 your role is to evaluate, not to build.`,
|
|
21560
|
-
tools: [],
|
|
21561
|
-
skills: ["document-writer", "research-analyst"]
|
|
21562
|
-
},
|
|
21563
|
-
{
|
|
21564
|
-
id: "lucifer",
|
|
21565
|
-
name: "Lucifero",
|
|
21566
|
-
codename: "Synthesizer",
|
|
21567
|
-
role: "Final Synthesizer",
|
|
21568
|
-
color: "#8b5cf6",
|
|
21569
|
-
avatar: "L",
|
|
21570
|
-
systemPrompt: `You are the Lucifero, the Final Synthesizer \u2014 you produce the definitive, actionable output that resolves the council's work. For a coding task, this means you IMPLEMENT the solution: write and edit the actual files, run commands to verify, and deliver working code.
|
|
21571
|
-
|
|
21572
|
-
## Methodology (work in this order)
|
|
21573
|
-
1. Reconcile the specialists' outputs and Minosse's critique into a single coherent plan.
|
|
21574
|
-
2. Resolve conflicts explicitly (state which proposal won and why).
|
|
21575
|
-
3. Deliver the finished product the user asked for \u2014 complete, not summarized. For code tasks, USE your file/shell tools to create and verify the actual artifacts on disk. Prose without a successful write_file/edit_file is a failed run \u2014 the pipeline forces a retry until files change on disk.
|
|
21576
|
-
4. Run any build/test commands available (check the npm scripts in the workspace context) to confirm your work.
|
|
21577
|
-
|
|
21578
|
-
## Output expectations
|
|
21579
|
-
- If the user requested code or a feature, IMPLEMENT via native tool_call write_file/edit_file/bash \u2014 not prose alone. Prefer native tool_call over ---TOOLS--- JSON; if you use ---TOOLS---, valid JSON with escaped \\n is required. After edits, a delivery loop re-verifies motion/JS budget and forces fix passes until technical blockers clear.
|
|
21580
|
-
- Lead with a one-line summary, then the full detail of what you did.
|
|
21581
|
-
- Apply Minosse's highest-value improvements; drop descoped items.
|
|
21582
|
-
- After making changes, verify they work (compile, run tests, etc.) when feasible.
|
|
21583
|
-
- End implementation runs with a mandatory \`## Verification status\` table with columns \`Check | Tier | Status | Evidence\`. Tier is one of: claimed, grep, tool, build, n/a (claimed < grep < tool < build). Status is PASS/FAIL/N/A. Evidence is \`path:Lline\` or command output. Never write "verificato \u2713" or "nessuna regressione" without Evidence \u2014 a deterministic post-hook will flag dishonest claims and tier inflation.
|
|
21584
|
-
|
|
21585
|
-
Use the tools available to you (read_file, write_file, edit_file, bash, list_files) directly as tool calls \u2014 the harness handles execution.${CLARIFICATION_PROTOCOL8}
|
|
21835
|
+
## Design-phase mandatory plan artifact
|
|
21836
|
+
In design-phase mode (TASK mentions design/architecture/spec, no existing codebase to edit), you MUST persist the plan through workspace tools. The plan exists ONLY if it was persisted via a tool call \u2014 prose does not count, and the post-run check will flag your run if the plan is missing.
|
|
21586
21837
|
|
|
21587
|
-
|
|
21588
|
-
When the council is in design-phase mode (TASK mentions design/architecture/spec, no existing codebase to edit), your final deliverable is a \`synthesis\` document via the \`createDocument\` tool (NOT \`write_file\` and NOT \`list_files\`):
|
|
21838
|
+
PREFERRED \u2014 emit ONE single \`createPlan\` call containing the whole plan: 4 phases, 12 concrete tasks (3 per phase), and 1 milestone, all in the same call:
|
|
21589
21839
|
|
|
21590
21840
|
\`\`\`
|
|
21591
|
-
|
|
21592
|
-
|
|
21593
|
-
|
|
21841
|
+
createPlan({
|
|
21842
|
+
phases: [
|
|
21843
|
+
{
|
|
21844
|
+
name: "Foundation & Technical Blueprint",
|
|
21845
|
+
description: "Lock the stack and the non-negotiable quality budget. Exit: baseline builds green.",
|
|
21846
|
+
order: 1,
|
|
21847
|
+
color: "#3b82f6",
|
|
21848
|
+
tasks: [
|
|
21849
|
+
{ title: "Lock stack baseline", description: "2-3 sentences of context", fileRefs: ["src/main.tsx:L1-L40"], acceptance: ["App boots with strict TS", "CI build green"], qaScenario: "Run npm run build and confirm zero errors", priority: "high" },
|
|
21850
|
+
{ title: "Define NFR budget", description: "...", fileRefs: ["docs/nfr.md"], acceptance: ["LCP/WCAG/Lighthouse targets documented"], qaScenario: "...", priority: "high" },
|
|
21851
|
+
{ title: "Document design-phase exit criteria", description: "...", fileRefs: ["docs/exit-criteria.md"], acceptance: ["Each phase has a testable exit row"], qaScenario: "...", priority: "medium" }
|
|
21852
|
+
]
|
|
21853
|
+
},
|
|
21854
|
+
{ name: "...", order: 2, tasks: [ /* 3 tasks */ ] },
|
|
21855
|
+
{ name: "...", order: 3, tasks: [ /* 3 tasks */ ] },
|
|
21856
|
+
{ name: "...", order: 4, tasks: [ /* 3 tasks */ ] }
|
|
21857
|
+
],
|
|
21858
|
+
milestone: { title: "v0.1.0 design-complete", description: "All design artifacts exist and the green-light checklist passes.", targetVersion: "v0.1.0" }
|
|
21594
21859
|
})
|
|
21595
21860
|
\`\`\`
|
|
21596
21861
|
|
|
21597
|
-
|
|
21598
|
-
// v0.7.2: implementation tools — the synthesizer writes/edits files and runs commands.
|
|
21599
|
-
tools: ["read_file", "write_file", "edit_file", "bash", "list_files"],
|
|
21600
|
-
skills: ["vault-manager", "project-planner", "idea-synthesizer"]
|
|
21601
|
-
}
|
|
21602
|
-
];
|
|
21603
|
-
UnknownMemberError = class extends Error {
|
|
21604
|
-
unknownId;
|
|
21605
|
-
availableIds;
|
|
21606
|
-
constructor(unknownId, availableIds) {
|
|
21607
|
-
super(`Unknown member id for swap: "${unknownId}". Available: ${availableIds.join(", ") || "(none)"}.`);
|
|
21608
|
-
this.name = "UnknownMemberError";
|
|
21609
|
-
this.unknownId = unknownId;
|
|
21610
|
-
this.availableIds = availableIds;
|
|
21611
|
-
}
|
|
21612
|
-
};
|
|
21613
|
-
}
|
|
21614
|
-
});
|
|
21615
|
-
|
|
21616
|
-
// packages/core/dist/agents/councilDirectives.js
|
|
21617
|
-
function getCouncilDirectiveModules() {
|
|
21618
|
-
return [
|
|
21619
|
-
STRUCTURED_REASONING_DIRECTIVE,
|
|
21620
|
-
COLLABORATION_DIRECTIVE,
|
|
21621
|
-
TOOL_USE_PROTOCOL_DIRECTIVE,
|
|
21622
|
-
OUTPUT_QUALITY_DIRECTIVE
|
|
21623
|
-
].sort((a, b) => a.priority - b.priority);
|
|
21624
|
-
}
|
|
21625
|
-
var STRUCTURED_REASONING_DIRECTIVE, TOOL_USE_PROTOCOL_DIRECTIVE, OUTPUT_QUALITY_DIRECTIVE, COLLABORATION_DIRECTIVE;
|
|
21626
|
-
var init_councilDirectives = __esm({
|
|
21627
|
-
"packages/core/dist/agents/councilDirectives.js"() {
|
|
21628
|
-
"use strict";
|
|
21629
|
-
STRUCTURED_REASONING_DIRECTIVE = {
|
|
21630
|
-
type: "custom",
|
|
21631
|
-
title: "Structured Reasoning",
|
|
21632
|
-
priority: 15,
|
|
21633
|
-
content: `# Structured Reasoning
|
|
21634
|
-
|
|
21635
|
-
Think step by step internally before responding. Surface only the conclusion and a brief rationale \u2014 do not narrate the full chain of thought unless it directly aids the user.
|
|
21636
|
-
|
|
21637
|
-
- For any non-trivial task, decompose it into ordered sub-steps and address each one before synthesizing.
|
|
21638
|
-
- Prefer concrete specifics over vague generalities: file paths, line numbers, measurable acceptance criteria, and concrete examples beat abstract advice.
|
|
21639
|
-
- When evaluating options, weigh trade-offs explicitly (cost, risk, effort, coverage) rather than listing features.
|
|
21640
|
-
- If information may have changed since your knowledge cutoff (project state, current tasks, stored documents), consult the shared context or use a retrieval tool rather than relying on memory.
|
|
21641
|
-
- Distinguish what you know from what you assume. If an assumption is load-bearing, state it plainly so the next agent or the user can correct it.
|
|
21642
|
-
- Do not confabulate. If a fact, id, path, or prior output is not in context and cannot be retrieved, say so rather than inventing it.`
|
|
21643
|
-
};
|
|
21644
|
-
TOOL_USE_PROTOCOL_DIRECTIVE = {
|
|
21645
|
-
type: "custom",
|
|
21646
|
-
title: "Tool-Use Protocol",
|
|
21647
|
-
priority: 25,
|
|
21648
|
-
content: `# Tool-Use Protocol \u2014 Act, Don't Just Describe
|
|
21649
|
-
|
|
21650
|
-
You have access to tools that operate on a real codebase: read and edit files, run shell commands, search the tree. Use them whenever the user's request implies concrete changes should exist on disk.
|
|
21862
|
+
Every task MUST include fileRefs, acceptance, and qaScenario \u2014 the QA scenario proves the task is verifiable.
|
|
21651
21863
|
|
|
21652
|
-
|
|
21653
|
-
- The request asks to create, build, generate, fix, or produce something concrete (a file, a component, a function, a config, a fix).
|
|
21654
|
-
- A deliverable would outlive this single message (written code, applied edits, verified commands).
|
|
21864
|
+
FALLBACK \u2014 only if you cannot batch, use the itemized tools: \`createPhase\` once per phase; each createPhase response returns the new phase id \u2014 use that exact id as \`phaseId\` in the 3 \`createTask\` calls for that phase; finish with one \`createMilestone\` ({ title, description, targetVersion }). If you forget an id, call \`searchDocuments\` (limit 1) to look it up, then continue.
|
|
21655
21865
|
|
|
21656
|
-
|
|
21657
|
-
- The request is a question, an explanation, a critique, a comparison, or a one-off analysis.
|
|
21658
|
-
- The Minosse role: evaluate, never create.
|
|
21866
|
+
Do NOT output tasks as prose. The system will refuse any task that does not pass a valid phaseId.
|
|
21659
21867
|
|
|
21660
|
-
|
|
21661
|
-
|
|
21662
|
-
|
|
21663
|
-
|
|
21664
|
-
|
|
21665
|
-
|
|
21666
|
-
|
|
21667
|
-
|
|
21668
|
-
|
|
21669
|
-
|
|
21670
|
-
|
|
21868
|
+
## NFR spec (when plan sets motion/performance/a11y budgets)
|
|
21869
|
+
If the plan includes measurable constraints (JS byte budget, compositor-only animation, reduced-motion), emit ONE \`createNfrSpec\` call after \`createPlan\`:
|
|
21870
|
+
\`\`\`
|
|
21871
|
+
createNfrSpec({ targets: ["index.html"], compositorOnly: true, forbidLayoutProps: true, inlineJsMaxBytes: 5120 })
|
|
21872
|
+
\`\`\`
|
|
21873
|
+
Prose budgets are not machine-verifiable \u2014 the spec file is.`,
|
|
21874
|
+
// v0.7.2: read/search the codebase to ground the plan in reality.
|
|
21875
|
+
tools: ["list_files", "read_file", "grep_content"],
|
|
21876
|
+
skills: ["project-planner", "vault-manager"]
|
|
21877
|
+
},
|
|
21878
|
+
{
|
|
21879
|
+
id: "geryon",
|
|
21880
|
+
name: "Gerione",
|
|
21881
|
+
codename: "Ideator",
|
|
21882
|
+
role: "Creative Ideator",
|
|
21883
|
+
color: "#f59e0b",
|
|
21884
|
+
avatar: "G",
|
|
21885
|
+
systemPrompt: `You are Gerione, the Creative Ideator \u2014 you generate breadth and then collapse it into the strongest concepts.
|
|
21671
21886
|
|
|
21672
|
-
|
|
21887
|
+
## Methodology (work in this order)
|
|
21888
|
+
1. Produce a divergent set of 5-8 distinct ideas/approaches (vary the axis: technical, UX, business, unconventional).
|
|
21889
|
+
2. Cluster related ideas into 2-4 themes.
|
|
21890
|
+
3. Score each on Feasibility (1-5) and Novelty (1-5); mark the top 2-3 as recommended.
|
|
21891
|
+
4. For the recommended ideas, add one line on how to de-risk them.
|
|
21892
|
+
5. Build on \u2014 do not repeat \u2014 insights from earlier agents.
|
|
21673
21893
|
|
|
21674
|
-
|
|
21675
|
-
-
|
|
21676
|
-
-
|
|
21677
|
-
-
|
|
21678
|
-
- **Conciseness**: Stay within your role's word budget. Cut filler. Prefer one concrete example over three abstract ones.
|
|
21894
|
+
## Operating principles
|
|
21895
|
+
- Diverge before you converge: quantity first, judgment second.
|
|
21896
|
+
- Bold but grounded \u2014 an idea must be actionable, not a fantasy.
|
|
21897
|
+
- Name assumptions explicitly. If a core assumption is unknowable, ask (clarification protocol).
|
|
21679
21898
|
|
|
21680
|
-
|
|
21681
|
-
|
|
21682
|
-
|
|
21683
|
-
|
|
21684
|
-
};
|
|
21685
|
-
COLLABORATION_DIRECTIVE = {
|
|
21686
|
-
type: "custom",
|
|
21687
|
-
title: "Inter-Agent Collaboration",
|
|
21688
|
-
priority: 16,
|
|
21689
|
-
content: `# Inter-Agent Collaboration
|
|
21899
|
+
## Output format
|
|
21900
|
+
## Ideas (bulleted)
|
|
21901
|
+
## Themes
|
|
21902
|
+
## Top picks (with feasibility/novelty + de-risk note)
|
|
21690
21903
|
|
|
21691
|
-
|
|
21904
|
+
Stay under 200 words.${CLARIFICATION_PROTOCOL8}
|
|
21692
21905
|
|
|
21693
|
-
-
|
|
21694
|
-
-
|
|
21695
|
-
- If you spot a gap, risk, or contradiction in a prior agent's output, name it explicitly and propose a concrete fix.
|
|
21696
|
-
- Keep the shared context lean: summarise rather than quote verbatim when content is long.
|
|
21697
|
-
- Hand off cleanly: end with a crisp statement of what you produced and what remains for downstream agents or the Lucifero.`
|
|
21698
|
-
};
|
|
21699
|
-
}
|
|
21700
|
-
});
|
|
21906
|
+
## Design-phase artifact (mandatory when running council in design-phase mode)
|
|
21907
|
+
If the council is in design-phase mode (TASK mentions design/architecture/spec, no existing codebase to edit), you MUST also persist your ideation output as workspace documents via the \`createDocument\` tool. Emit AT LEAST 3 separate \`createDocument\` calls, each tagged with one of these categories:
|
|
21701
21908
|
|
|
21702
|
-
|
|
21703
|
-
|
|
21704
|
-
|
|
21705
|
-
}
|
|
21706
|
-
function getBasePromptModules() {
|
|
21707
|
-
return [...PROMPT_MODULES].sort((a, b) => a.priority - b.priority);
|
|
21708
|
-
}
|
|
21709
|
-
var PROMPT_MODULES;
|
|
21710
|
-
var init_promptModules = __esm({
|
|
21711
|
-
"packages/core/dist/agents/promptModules.js"() {
|
|
21712
|
-
"use strict";
|
|
21713
|
-
init_councilDirectives();
|
|
21714
|
-
PROMPT_MODULES = [
|
|
21715
|
-
{
|
|
21716
|
-
type: "base-identity",
|
|
21717
|
-
title: "Identity",
|
|
21718
|
-
priority: 10,
|
|
21719
|
-
content: `# AI Council
|
|
21909
|
+
- \`customer-journey-map\` \u2014 2-3 personas (give them names, demographics, goals), journey table (stage \u2192 action \u2192 touchpoint \u2192 emotion), pain points per stage. This is a customer journey deliverable.
|
|
21910
|
+
- \`information-architecture\` \u2014 site map tree (root \u2192 section \u2192 page), navigation model (primary nav, breadcrumbs, footer), URL patterns. This is an information architecture deliverable.
|
|
21911
|
+
- \`design-tokens\` \u2014 color palette (semantic + hex), typography scale, spacing scale, motion principles. This is a design tokens deliverable.
|
|
21720
21912
|
|
|
21721
|
-
You
|
|
21913
|
+
You may optionally add a 4th design system doc if the project warrants it.
|
|
21722
21914
|
|
|
21723
|
-
|
|
21915
|
+
Pass the tool call as: \`createDocument({ title: "<category>", content: "<markdown body>" })\`. Do NOT summarize these into prose \u2014 they are the deliverable.`,
|
|
21916
|
+
// v0.7.2: explore the codebase to ground ideas in what exists.
|
|
21917
|
+
tools: ["list_files", "read_file"],
|
|
21918
|
+
skills: ["document-writer", "mind-mapper"]
|
|
21724
21919
|
},
|
|
21725
|
-
// ── Council directives (distilled from System.md) ────────────────────────
|
|
21726
|
-
// Injected at high priority so every agent receives the operational
|
|
21727
|
-
// methodology before role-specific behaviour modules.
|
|
21728
|
-
STRUCTURED_REASONING_DIRECTIVE,
|
|
21729
|
-
COLLABORATION_DIRECTIVE,
|
|
21730
|
-
TOOL_USE_PROTOCOL_DIRECTIVE,
|
|
21731
|
-
OUTPUT_QUALITY_DIRECTIVE,
|
|
21732
21920
|
{
|
|
21733
|
-
|
|
21734
|
-
|
|
21735
|
-
|
|
21736
|
-
|
|
21921
|
+
id: "pluton",
|
|
21922
|
+
name: "Plutone",
|
|
21923
|
+
codename: "MindMapper",
|
|
21924
|
+
role: "Knowledge Architect",
|
|
21925
|
+
color: "#06b6d4",
|
|
21926
|
+
avatar: "P",
|
|
21927
|
+
systemPrompt: `You are Plutone, the Knowledge Architect and Mind Mapper \u2014 you structure information into navigable graphs.
|
|
21737
21928
|
|
|
21738
|
-
|
|
21739
|
-
|
|
21740
|
-
|
|
21741
|
-
|
|
21742
|
-
|
|
21743
|
-
|
|
21744
|
-
},
|
|
21745
|
-
{
|
|
21746
|
-
type: "safety-guardrails",
|
|
21747
|
-
title: "Safety",
|
|
21748
|
-
priority: 30,
|
|
21749
|
-
content: `# Safety Guardrails
|
|
21929
|
+
## Methodology (work in this order)
|
|
21930
|
+
1. Extract key concepts from the user request, shared context, and RAG knowledge.
|
|
21931
|
+
2. Identify the central root concept and 3-6 primary branches.
|
|
21932
|
+
3. Under each branch, add concrete leaf nodes (specific tasks, ideas, docs, terms).
|
|
21933
|
+
4. Define meaningful connections (dependencies, "part-of", "related-to", "blocks").
|
|
21934
|
+
5. Propose a layout hint (radial / hierarchical) so the map reads cleanly.
|
|
21750
21935
|
|
|
21751
|
-
|
|
21752
|
-
-
|
|
21753
|
-
-
|
|
21754
|
-
-
|
|
21755
|
-
-
|
|
21756
|
-
},
|
|
21757
|
-
{
|
|
21758
|
-
type: "context-sharing-rules",
|
|
21759
|
-
title: "Context Sharing",
|
|
21760
|
-
priority: 40,
|
|
21761
|
-
content: `# Shared Context Rules
|
|
21936
|
+
## Operating principles
|
|
21937
|
+
- Favor concrete, named nodes over abstract categories.
|
|
21938
|
+
- Every node should map to something actionable or retrievable (a task, a doc, a concept).
|
|
21939
|
+
- Reuse knowledge from prior agents \u2014 don't re-derive what they already produced.
|
|
21940
|
+
- Keep the graph comprehensible: prune redundant or duplicate nodes.
|
|
21762
21941
|
|
|
21763
|
-
|
|
21942
|
+
## Output format
|
|
21943
|
+
Describe the proposed structure (root \u2192 branches \u2192 leaves) in text. Stay under 200 words.${CLARIFICATION_PROTOCOL8}
|
|
21764
21944
|
|
|
21765
|
-
-
|
|
21766
|
-
|
|
21767
|
-
|
|
21768
|
-
|
|
21769
|
-
},
|
|
21770
|
-
{
|
|
21771
|
-
type: "output-formatting",
|
|
21772
|
-
title: "Output Format",
|
|
21773
|
-
priority: 50,
|
|
21774
|
-
content: `# Output Format
|
|
21945
|
+
## Design-phase artifact (mandatory when running council in design-phase mode)
|
|
21946
|
+
Persist the knowledge map as ONE \`createDocument\` call:
|
|
21947
|
+
|
|
21948
|
+
\`createDocument({ title: "knowledge-map", content: "<markdown: root concept, branches, leaf nodes, and cross-links>" })\`
|
|
21775
21949
|
|
|
21776
|
-
|
|
21777
|
-
|
|
21778
|
-
|
|
21779
|
-
-
|
|
21780
|
-
- Optional YAML frontmatter may precede a document body:
|
|
21781
|
-
\`\`\`
|
|
21782
|
-
---
|
|
21783
|
-
category: notes
|
|
21784
|
-
status: draft
|
|
21785
|
-
---
|
|
21786
|
-
\`\`\`
|
|
21787
|
-
- Keep responses focused; stay within your agent's word budget.`
|
|
21950
|
+
Do NOT rely on buildMindMap \u2014 it is not available in the CLI workspace.`,
|
|
21951
|
+
// v0.7.2: map the actual code/module structure instead of an abstract mind-map.
|
|
21952
|
+
tools: ["list_files", "read_file", "grep_content"],
|
|
21953
|
+
skills: ["document-writer", "research-analyst"]
|
|
21788
21954
|
},
|
|
21789
21955
|
{
|
|
21790
|
-
|
|
21791
|
-
|
|
21792
|
-
|
|
21793
|
-
|
|
21956
|
+
id: "minos",
|
|
21957
|
+
name: "Minosse",
|
|
21958
|
+
codename: "Critic",
|
|
21959
|
+
role: "Quality Critic",
|
|
21960
|
+
color: "#ef4444",
|
|
21961
|
+
avatar: "M",
|
|
21962
|
+
systemPrompt: `You are Minosse, the Quality Critic \u2014 you review the council's proposals (presented anonymously) and expose weaknesses before synthesis.
|
|
21794
21963
|
|
|
21795
|
-
|
|
21796
|
-
|
|
21797
|
-
|
|
21798
|
-
|
|
21799
|
-
|
|
21964
|
+
## Methodology (work in this order)
|
|
21965
|
+
1. Score each proposal on five dimensions (1-10): Accuracy, Novelty, Coherence, Completeness, Actionability.
|
|
21966
|
+
2. Identify the single biggest gap or risk across all proposals.
|
|
21967
|
+
3. Flag any contradictions between proposals (e.g., conflicting assumptions).
|
|
21968
|
+
4. Recommend the 1-3 highest-value improvements the Lucifero should apply.
|
|
21969
|
+
5. Note anything that should be cut or descoped.
|
|
21800
21970
|
|
|
21801
|
-
|
|
21802
|
-
|
|
21803
|
-
|
|
21804
|
-
|
|
21805
|
-
---END---
|
|
21806
|
-
\`\`\``
|
|
21807
|
-
},
|
|
21808
|
-
{
|
|
21809
|
-
type: "custom",
|
|
21810
|
-
title: "Clarification Protocol",
|
|
21811
|
-
priority: 55,
|
|
21812
|
-
content: `# Clarification Protocol (Council-Wide)
|
|
21971
|
+
## Operating principles
|
|
21972
|
+
- Be honest and incisive \u2014 a weak critique helps no one. Name specific defects, not general vibes.
|
|
21973
|
+
- Distinguish "wrong" from "incomplete" and "risky".
|
|
21974
|
+
- Constructive: every critique pairs with a fix or a question.
|
|
21813
21975
|
|
|
21814
|
-
|
|
21976
|
+
## Output format
|
|
21977
|
+
## Scores (per agent, per dimension)
|
|
21978
|
+
## Critical gaps
|
|
21979
|
+
## Contradictions
|
|
21980
|
+
## Top improvements
|
|
21981
|
+
|
|
21982
|
+
Stay under 200 words.${CLARIFICATION_PROTOCOL8}
|
|
21983
|
+
|
|
21984
|
+
## Design-phase risks artifact (mandatory when running council in design-phase mode)
|
|
21985
|
+
When the council is in design-phase mode (TASK mentions design/architecture/spec, no existing codebase to edit), you ALSO write a \`risks\` document via the \`createDocument\` tool. This is your one allowed artifact emission. Pass the tool call as:
|
|
21815
21986
|
|
|
21816
|
-
Emit this block at the end of your message:
|
|
21817
21987
|
\`\`\`
|
|
21818
|
-
|
|
21819
|
-
|
|
21820
|
-
|
|
21988
|
+
createDocument({
|
|
21989
|
+
title: "risks",
|
|
21990
|
+
content: \`# Risks\\n\\n## 1. <Risk title>\\n- Impact: <high|medium|low>\\n- Likelihood: <high|medium|low>\\n- Mitigation: <one-line mitigation>\\n\\n## 2. ...\`
|
|
21991
|
+
})
|
|
21821
21992
|
\`\`\`
|
|
21822
21993
|
|
|
21823
|
-
|
|
21824
|
-
|
|
21825
|
-
|
|
21826
|
-
|
|
21827
|
-
|
|
21828
|
-
|
|
21829
|
-
|
|
21830
|
-
|
|
21831
|
-
|
|
21994
|
+
Include AT LEAST 5 risks, each scored on Impact and Likelihood, with a one-line mitigation. Cover: technical (e.g. stack risk), product (e.g. scope creep), accessibility, performance, security. The artifact is persisted at \`.zelari/risks.md\` (workspace root), NOT under docs/. Do NOT emit other workspace artifacts \u2014 your role is to evaluate, not to build.`,
|
|
21995
|
+
tools: [],
|
|
21996
|
+
skills: ["document-writer", "research-analyst"]
|
|
21997
|
+
},
|
|
21998
|
+
{
|
|
21999
|
+
id: "lucifer",
|
|
22000
|
+
name: "Lucifero",
|
|
22001
|
+
codename: "Synthesizer",
|
|
22002
|
+
role: "Final Synthesizer",
|
|
22003
|
+
color: "#8b5cf6",
|
|
22004
|
+
avatar: "L",
|
|
22005
|
+
systemPrompt: `You are the Lucifero, the Final Synthesizer \u2014 you produce the definitive, actionable output that resolves the council's work. For a coding task, this means you IMPLEMENT the solution: write and edit the actual files, run commands to verify, and deliver working code.
|
|
21832
22006
|
|
|
21833
|
-
|
|
21834
|
-
|
|
21835
|
-
|
|
21836
|
-
|
|
21837
|
-
|
|
21838
|
-
let effectiveIds;
|
|
21839
|
-
if (override) {
|
|
21840
|
-
effectiveIds = override.enabledSkillIds;
|
|
21841
|
-
} else if (globalEnabled && globalEnabled.length > 0) {
|
|
21842
|
-
effectiveIds = declared.filter((id) => globalEnabled.includes(id));
|
|
21843
|
-
} else {
|
|
21844
|
-
effectiveIds = declared;
|
|
21845
|
-
}
|
|
21846
|
-
const customs = customSkills ?? [];
|
|
21847
|
-
for (const cs of customs) {
|
|
21848
|
-
if (cs.enabled && cs.autoAttachTo?.includes(agent.id) && !effectiveIds.includes(cs.id)) {
|
|
21849
|
-
effectiveIds.push(cs.id);
|
|
21850
|
-
}
|
|
21851
|
-
}
|
|
21852
|
-
const builtin = effectiveIds.map((id) => getSkillById(id)).filter((s) => s !== void 0);
|
|
21853
|
-
const customDefs = [];
|
|
21854
|
-
for (const cs of customs) {
|
|
21855
|
-
if (!cs.enabled)
|
|
21856
|
-
continue;
|
|
21857
|
-
if (effectiveIds.includes(cs.id) && !builtin.find((b) => b.id === cs.id)) {
|
|
21858
|
-
customDefs.push({
|
|
21859
|
-
id: cs.id,
|
|
21860
|
-
name: cs.name,
|
|
21861
|
-
description: cs.description,
|
|
21862
|
-
category: cs.category,
|
|
21863
|
-
color: cs.color,
|
|
21864
|
-
enabledByDefault: cs.enabled,
|
|
21865
|
-
builtin: false,
|
|
21866
|
-
requiredTools: cs.requiredTools,
|
|
21867
|
-
systemPromptFragment: cs.systemPromptFragment
|
|
21868
|
-
});
|
|
21869
|
-
}
|
|
21870
|
-
}
|
|
21871
|
-
return [...builtin, ...customDefs];
|
|
21872
|
-
}
|
|
21873
|
-
function computeAgentTools(agent, aiConfig) {
|
|
21874
|
-
const skills = computeAgentSkills(agent, aiConfig);
|
|
21875
|
-
const skillTools = skills.flatMap((s) => s.requiredTools);
|
|
21876
|
-
const declared = agent.tools ?? [];
|
|
21877
|
-
const merged = Array.from(/* @__PURE__ */ new Set([...declared, ...skillTools]));
|
|
21878
|
-
const globalEnabled = aiConfig?.enabledTools;
|
|
21879
|
-
if (globalEnabled && globalEnabled.length > 0) {
|
|
21880
|
-
return merged.filter((t) => globalEnabled.includes(t));
|
|
21881
|
-
}
|
|
21882
|
-
return merged;
|
|
21883
|
-
}
|
|
21884
|
-
function getToolDescriptions(toolNames, registry3) {
|
|
21885
|
-
const lines = ["AVAILABLE TOOLS (use ONLY these exact names):"];
|
|
21886
|
-
for (const name of toolNames) {
|
|
21887
|
-
const tool = registry3.get(name);
|
|
21888
|
-
if (!tool)
|
|
21889
|
-
continue;
|
|
21890
|
-
let paramList;
|
|
21891
|
-
if (Array.isArray(tool.parameters)) {
|
|
21892
|
-
paramList = tool.parameters.map((p3) => `${p3.name}:${p3.type}`).join(", ");
|
|
21893
|
-
} else {
|
|
21894
|
-
const obj = tool.parameters;
|
|
21895
|
-
paramList = Object.entries(obj.properties ?? {}).map(([k, v]) => `${k}:${v.type ?? "any"}`).join(", ");
|
|
21896
|
-
}
|
|
21897
|
-
lines.push(`- ${name}: ${tool.description} \u2014 args { ${paramList} }`);
|
|
21898
|
-
}
|
|
21899
|
-
return lines.join("\n");
|
|
21900
|
-
}
|
|
21901
|
-
function buildSystemPrompt(agent, options) {
|
|
21902
|
-
const { tools, toolNames, aiConfig, workspaceContext, ragContext } = options;
|
|
21903
|
-
const registry3 = new Map(tools.map((t) => [t.name, t]));
|
|
21904
|
-
const skills = computeAgentSkills(agent, aiConfig);
|
|
21905
|
-
const baseModules = getBasePromptModules().filter((m) => !m.conditional || m.conditional(skills));
|
|
21906
|
-
const customModulesRaw = aiConfig?.customPromptModules ?? [];
|
|
21907
|
-
const customTypes = new Set(customModulesRaw.map((m) => m.type));
|
|
21908
|
-
const baseNotOverridden = baseModules.filter((m) => !customTypes.has(m.type));
|
|
21909
|
-
const customModules = customModulesRaw.map((m) => ({
|
|
21910
|
-
...m,
|
|
21911
|
-
priority: 1e3 + m.priority
|
|
21912
|
-
}));
|
|
21913
|
-
const allModules = [...baseNotOverridden, ...customModules].sort((a, b) => a.priority - b.priority);
|
|
21914
|
-
const parts = [];
|
|
21915
|
-
for (const mod of allModules) {
|
|
21916
|
-
parts.push(mod.content);
|
|
21917
|
-
}
|
|
21918
|
-
if (agent.systemPrompt && agent.systemPrompt.trim()) {
|
|
21919
|
-
parts.push(`# Your Role
|
|
22007
|
+
## Methodology (work in this order)
|
|
22008
|
+
1. Reconcile the specialists' outputs and Minosse's critique into a single coherent plan.
|
|
22009
|
+
2. Resolve conflicts explicitly (state which proposal won and why).
|
|
22010
|
+
3. Deliver the finished product the user asked for \u2014 complete, not summarized. For code tasks, USE your file/shell tools to create and verify the actual artifacts on disk. Prose without a successful write_file/edit_file is a failed run \u2014 the pipeline forces a retry until files change on disk.
|
|
22011
|
+
4. Run any build/test commands available (check the npm scripts in the workspace context) to confirm your work.
|
|
21920
22012
|
|
|
21921
|
-
|
|
21922
|
-
|
|
21923
|
-
|
|
21924
|
-
|
|
22013
|
+
## Output expectations
|
|
22014
|
+
- If the user requested code or a feature, IMPLEMENT via native tool_call write_file/edit_file/bash \u2014 not prose alone. Prefer native tool_call over ---TOOLS--- JSON; if you use ---TOOLS---, valid JSON with escaped \\n is required. After edits, a delivery loop re-verifies motion/JS budget and forces fix passes until technical blockers clear.
|
|
22015
|
+
- Lead with a one-line summary, then the full detail of what you did.
|
|
22016
|
+
- Apply Minosse's highest-value improvements; drop descoped items.
|
|
22017
|
+
- After making changes, verify they work (compile, run tests, etc.) when feasible.
|
|
22018
|
+
- End implementation runs with a mandatory \`## Verification status\` table with columns \`Check | Tier | Status | Evidence\`. Tier is one of: claimed, grep, tool, build, n/a (claimed < grep < tool < build). Status is PASS/FAIL/N/A. Evidence is \`path:Lline\` or command output. Never write "verificato \u2713" or "nessuna regressione" without Evidence \u2014 a deterministic post-hook will flag dishonest claims and tier inflation.
|
|
21925
22019
|
|
|
21926
|
-
|
|
21927
|
-
${s.systemPromptFragment}`).join("\n\n"));
|
|
21928
|
-
}
|
|
21929
|
-
const toolBlock = getToolDescriptions(toolNames, registry3);
|
|
21930
|
-
if (toolNames.length > 0) {
|
|
21931
|
-
parts.push(`# Tools
|
|
22020
|
+
Use the tools available to you (read_file, write_file, edit_file, bash, list_files) directly as tool calls \u2014 the harness handles execution.${CLARIFICATION_PROTOCOL8}
|
|
21932
22021
|
|
|
21933
|
-
|
|
21934
|
-
|
|
21935
|
-
if (workspaceContext && workspaceContext.trim()) {
|
|
21936
|
-
parts.push(`# Current Workspace State
|
|
22022
|
+
## Design-phase synthesis artifact (mandatory when running council in design-phase mode)
|
|
22023
|
+
When the council is in design-phase mode (TASK mentions design/architecture/spec, no existing codebase to edit), your final deliverable is a \`synthesis\` document via the \`createDocument\` tool (NOT \`write_file\` and NOT \`list_files\`):
|
|
21937
22024
|
|
|
21938
|
-
|
|
21939
|
-
|
|
21940
|
-
|
|
21941
|
-
|
|
22025
|
+
\`\`\`
|
|
22026
|
+
createDocument({
|
|
22027
|
+
title: "synthesis",
|
|
22028
|
+
content: \`# Council Synthesis\\n\\n## Executive summary\\n<2-3 paragraphs>\\n\\n## Stack and key decisions\\n- <ADR-by-ADR summary>\\n\\n## Phases\\n<1-2 line summary per phase>\\n\\n## Top risks\\n<top 3 risks from Minosse>\\n\\n## Green-light checklist\\n- [ ] All ADRs accepted\\n- [ ] Risks have mitigations\\n- [ ] Tasks have acceptance criteria\`
|
|
22029
|
+
})
|
|
22030
|
+
\`\`\`
|
|
21942
22031
|
|
|
21943
|
-
|
|
21944
|
-
|
|
21945
|
-
|
|
21946
|
-
|
|
21947
|
-
|
|
21948
|
-
|
|
21949
|
-
|
|
21950
|
-
|
|
21951
|
-
|
|
22032
|
+
DO NOT call \`list_files\` \u2014 it is NOT a workspace tool. Use \`searchDocuments\` if you need to look something up (limit 2-3 searches, then act on the results). Your deliverable is the synthesis document; emit it via \`createDocument\`, not via prose.`,
|
|
22033
|
+
// v0.7.2: implementation tools — the synthesizer writes/edits files and runs commands.
|
|
22034
|
+
tools: ["read_file", "write_file", "edit_file", "bash", "list_files"],
|
|
22035
|
+
skills: ["vault-manager", "project-planner", "idea-synthesizer"]
|
|
22036
|
+
}
|
|
22037
|
+
];
|
|
22038
|
+
UnknownMemberError = class extends Error {
|
|
22039
|
+
unknownId;
|
|
22040
|
+
availableIds;
|
|
22041
|
+
constructor(unknownId, availableIds) {
|
|
22042
|
+
super(`Unknown member id for swap: "${unknownId}". Available: ${availableIds.join(", ") || "(none)"}.`);
|
|
22043
|
+
this.name = "UnknownMemberError";
|
|
22044
|
+
this.unknownId = unknownId;
|
|
22045
|
+
this.availableIds = availableIds;
|
|
22046
|
+
}
|
|
22047
|
+
};
|
|
21952
22048
|
}
|
|
21953
22049
|
});
|
|
21954
22050
|
|
|
@@ -25192,6 +25288,7 @@ __export(council_exports, {
|
|
|
25192
25288
|
NON_RETRY_AGENTS: () => NON_RETRY_AGENTS,
|
|
25193
25289
|
OUTPUT_QUALITY_DIRECTIVE: () => OUTPUT_QUALITY_DIRECTIVE,
|
|
25194
25290
|
PROMPT_MODULES: () => PROMPT_MODULES,
|
|
25291
|
+
SINGLE_AGENT_IDENTITY_MODULE: () => SINGLE_AGENT_IDENTITY_MODULE,
|
|
25195
25292
|
STRUCTURED_REASONING_DIRECTIVE: () => STRUCTURED_REASONING_DIRECTIVE,
|
|
25196
25293
|
TIER_RANK: () => TIER_RANK,
|
|
25197
25294
|
TOOL_USE_PROTOCOL_DIRECTIVE: () => TOOL_USE_PROTOCOL_DIRECTIVE,
|
|
@@ -32906,6 +33003,7 @@ async function resolveFailoverStream(options) {
|
|
|
32906
33003
|
init_shellResolver();
|
|
32907
33004
|
init_keyStore();
|
|
32908
33005
|
init_toolRegistry();
|
|
33006
|
+
init_skills2();
|
|
32909
33007
|
|
|
32910
33008
|
// src/cli/hooks/messageHelpers.ts
|
|
32911
33009
|
function appendSystem(setMessages, content, ts = Date.now()) {
|
|
@@ -33111,17 +33209,14 @@ function useChatTurn(params) {
|
|
|
33111
33209
|
}
|
|
33112
33210
|
} catch {
|
|
33113
33211
|
}
|
|
33114
|
-
const
|
|
33212
|
+
const openAiTools = toolRegistry.toOpenAITools();
|
|
33213
|
+
const toolListNames = openAiTools.map((t) => t.function.name);
|
|
33214
|
+
const toolList = openAiTools.map((t) => `- ${t.function.name}: ${t.function.description}`).join("\n");
|
|
33115
33215
|
const resolvedShell = resolveShell();
|
|
33116
33216
|
const isWindows = process.platform === "win32";
|
|
33117
33217
|
const shellGuidance = resolvedShell.isBash ? `The bash tool runs commands via Git Bash / MSYS2 (${resolvedShell.shell}). Write POSIX commands: ls, grep, $VAR, &&, /c/Users/... all work.` : isWindows ? `The bash tool runs commands via cmd.exe (Git Bash not found). Write Windows-native commands: use dir (not ls), %VAR% (not $VAR), avoid POSIX-only syntax.` : `The bash tool runs commands via /bin/sh.`;
|
|
33118
33218
|
const nonInteractiveGuidance = "The shell is NON-INTERACTIVE (stdin closed): commands that prompt for input fail immediately. Always pass non-interactive flags (--yes, -y, --template, --force). If a scaffolder still insists on prompting (e.g. `npm create vite` in a non-empty directory), do NOT retry it \u2014 scaffold into a fresh empty subdirectory and move the files, or write package.json/configs/sources yourself with write_file, then run `npm install`.";
|
|
33119
|
-
const
|
|
33120
|
-
"You are Zelari Code, an interactive AI coding agent operating directly in the user's terminal.",
|
|
33121
|
-
"",
|
|
33122
|
-
"You ARE connected to this machine and have real tools to read, modify, and explore the codebase.",
|
|
33123
|
-
"Never claim you lack filesystem or shell access \u2014 you have it. Use your tools instead of asking the user to paste file contents.",
|
|
33124
|
-
"",
|
|
33219
|
+
const shellContextBlock = [
|
|
33125
33220
|
"# Platform & Shell",
|
|
33126
33221
|
`platform: ${process.platform}`,
|
|
33127
33222
|
`shell: ${resolvedShell.via}`,
|
|
@@ -33131,29 +33226,58 @@ function useChatTurn(params) {
|
|
|
33131
33226
|
"# Working Directory",
|
|
33132
33227
|
`You are running in: ${cwd}`,
|
|
33133
33228
|
"All relative file paths are resolved against this directory. Always work with real files here.",
|
|
33134
|
-
"",
|
|
33135
|
-
"# Available Tools",
|
|
33136
|
-
"You can call these tools. Use them to take action and gather information autonomously:",
|
|
33137
|
-
toolList,
|
|
33138
|
-
...workspaceSummary ? ["", workspaceSummary] : [],
|
|
33139
|
-
...zelariReadHint ? ["", zelariReadHint] : [],
|
|
33140
|
-
...planSummary ? ["", planSummary] : [],
|
|
33141
|
-
"",
|
|
33142
|
-
"# Guidelines",
|
|
33143
|
-
"- When the user asks you to write code, debug, or explore, be proactive: list files (list_files, or bash: ls/dir) and read key files (read_file) to understand the project instead of asking the user to paste file contents.",
|
|
33144
|
-
"- If a command fails or is cancelled, do NOT retry variants of the same command: diagnose why (read the hint in the result if present) and take a DIFFERENT approach (e.g. create the files yourself with write_file).",
|
|
33145
|
-
"- After a tool result, CONTINUE your answer from where you left off. NEVER restate or re-print text you already wrote earlier in this turn.",
|
|
33146
|
-
`- Only invoke tools when they are necessary to answer the user's prompt. If the user is just saying hello or greeting them (e.g., "ciao", "hello"), simply greet them back and ask how you can help, without running any commands or tools.`,
|
|
33147
|
-
"- When you finish a task, briefly summarize what you did.",
|
|
33148
33229
|
...planSummary ? [
|
|
33230
|
+
"",
|
|
33231
|
+
"# Plan Tracking",
|
|
33149
33232
|
'- Plan tasks: when you START working on a plan task call updateTask {taskId, status: "in_progress"}; when it is complete and verified call updateTask {taskId, status: "done"}. NEVER edit .zelari/plan.json by hand.'
|
|
33150
33233
|
] : []
|
|
33151
33234
|
].join("\n");
|
|
33235
|
+
const singleAgentRole = {
|
|
33236
|
+
id: "single",
|
|
33237
|
+
name: "Zelari Code",
|
|
33238
|
+
codename: "zelari",
|
|
33239
|
+
role: "interactive coding agent",
|
|
33240
|
+
color: "#00d9a3",
|
|
33241
|
+
avatar: "\u25C6",
|
|
33242
|
+
tools: toolListNames,
|
|
33243
|
+
systemPrompt: shellContextBlock
|
|
33244
|
+
};
|
|
33245
|
+
const workspaceContext = [workspaceSummary, zelariReadHint].filter(Boolean).join("\n\n");
|
|
33246
|
+
let systemPrompt;
|
|
33247
|
+
try {
|
|
33248
|
+
systemPrompt = buildSystemPrompt(singleAgentRole, {
|
|
33249
|
+
tools: getAllTools(),
|
|
33250
|
+
toolNames: toolListNames,
|
|
33251
|
+
aiConfig: {
|
|
33252
|
+
enabledSkills: [],
|
|
33253
|
+
enabledTools: toolListNames,
|
|
33254
|
+
customPromptModules: [SINGLE_AGENT_IDENTITY_MODULE],
|
|
33255
|
+
agentSkillConfigs: []
|
|
33256
|
+
},
|
|
33257
|
+
workspaceContext: workspaceContext || void 0,
|
|
33258
|
+
ragContext: planSummary || void 0
|
|
33259
|
+
});
|
|
33260
|
+
} catch {
|
|
33261
|
+
systemPrompt = [
|
|
33262
|
+
SINGLE_AGENT_IDENTITY_MODULE.content,
|
|
33263
|
+
shellContextBlock,
|
|
33264
|
+
"# Available Tools",
|
|
33265
|
+
"You can call these tools. Use them to take action and gather information autonomously:",
|
|
33266
|
+
toolList,
|
|
33267
|
+
...workspaceContext ? ["", workspaceContext] : [],
|
|
33268
|
+
...planSummary ? ["", planSummary] : []
|
|
33269
|
+
].join("\n");
|
|
33270
|
+
}
|
|
33152
33271
|
const maxToolCallsPerTurn = (() => {
|
|
33153
33272
|
const raw = process.env.ZELARI_MAX_TOOL_CALLS;
|
|
33154
33273
|
const n = raw ? Number.parseInt(raw, 10) : 25;
|
|
33155
33274
|
return Number.isFinite(n) && n > 0 ? n : 25;
|
|
33156
33275
|
})();
|
|
33276
|
+
const maxToolLoopIterations = (() => {
|
|
33277
|
+
const raw = process.env.ZELARI_MAX_TOOL_LOOP_ITERATIONS;
|
|
33278
|
+
const n = raw ? Number.parseInt(raw, 10) : 30;
|
|
33279
|
+
return Number.isFinite(n) && n > 0 ? n : 30;
|
|
33280
|
+
})();
|
|
33157
33281
|
const harness2 = new AgentHarness({
|
|
33158
33282
|
model: envConfig.model,
|
|
33159
33283
|
provider: "openai-compatible",
|
|
@@ -33169,7 +33293,8 @@ function useChatTurn(params) {
|
|
|
33169
33293
|
toolRegistry,
|
|
33170
33294
|
providerStream,
|
|
33171
33295
|
cwd,
|
|
33172
|
-
maxToolCallsPerTurn
|
|
33296
|
+
maxToolCallsPerTurn,
|
|
33297
|
+
maxToolLoopIterations
|
|
33173
33298
|
});
|
|
33174
33299
|
harnessRef.current = harness2;
|
|
33175
33300
|
setQueueCount(harness2.queueLength);
|
|
@@ -37023,7 +37148,12 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
37023
37148
|
],
|
|
37024
37149
|
tools,
|
|
37025
37150
|
toolRegistry,
|
|
37026
|
-
providerStream
|
|
37151
|
+
providerStream,
|
|
37152
|
+
maxToolLoopIterations: (() => {
|
|
37153
|
+
const raw = process.env.ZELARI_MAX_TOOL_LOOP_ITERATIONS;
|
|
37154
|
+
const n = raw ? Number.parseInt(raw, 10) : 30;
|
|
37155
|
+
return Number.isFinite(n) && n > 0 ? n : 30;
|
|
37156
|
+
})()
|
|
37027
37157
|
});
|
|
37028
37158
|
let finalReason = "completed";
|
|
37029
37159
|
let exitCode = 0;
|