@voybio/ace-swarm 0.1.0
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/CHANGELOG.md +109 -0
- package/LICENSE +186 -0
- package/README.md +229 -0
- package/assets/.agents/ACE/ACE-Init/AGENTS.md +210 -0
- package/assets/.agents/ACE/ACE-Init/instructions.md +118 -0
- package/assets/.agents/ACE/ACE_coders/AGENTS.md +154 -0
- package/assets/.agents/ACE/ACE_coders/INSTRUCTIONS.md +216 -0
- package/assets/.agents/ACE/AGENT_REGISTRY.md +70 -0
- package/assets/.agents/ACE/AGENT_REGISTRY_7.md +9 -0
- package/assets/.agents/ACE/DIRECTIVE_KERNEL.md +234 -0
- package/assets/.agents/ACE/UI/AGENTS.md +115 -0
- package/assets/.agents/ACE/UI/instructions.md +178 -0
- package/assets/.agents/ACE/VOS/ACE_VOS_MISSING_INFO_MATRIX.md +42 -0
- package/assets/.agents/ACE/VOS/AGENTS.md +72 -0
- package/assets/.agents/ACE/VOS/instructions.md +211 -0
- package/assets/.agents/ACE/agent-astgrep/AGENTS.md +123 -0
- package/assets/.agents/ACE/agent-astgrep/instructions.md +91 -0
- package/assets/.agents/ACE/agent-builder/AGENTS.md +172 -0
- package/assets/.agents/ACE/agent-builder/instructions.md +137 -0
- package/assets/.agents/ACE/agent-docs/AGENTS.md +159 -0
- package/assets/.agents/ACE/agent-docs/instructions.md +133 -0
- package/assets/.agents/ACE/agent-eval/AGENTS.md +46 -0
- package/assets/.agents/ACE/agent-eval/instructions.md +56 -0
- package/assets/.agents/ACE/agent-memory/AGENTS.md +49 -0
- package/assets/.agents/ACE/agent-memory/instructions.md +50 -0
- package/assets/.agents/ACE/agent-observability/AGENTS.md +46 -0
- package/assets/.agents/ACE/agent-observability/instructions.md +50 -0
- package/assets/.agents/ACE/agent-ops/AGENTS.md +201 -0
- package/assets/.agents/ACE/agent-ops/instructions.md +136 -0
- package/assets/.agents/ACE/agent-qa/AGENTS.md +189 -0
- package/assets/.agents/ACE/agent-qa/instructions.md +121 -0
- package/assets/.agents/ACE/agent-release/AGENTS.md +48 -0
- package/assets/.agents/ACE/agent-release/instructions.md +49 -0
- package/assets/.agents/ACE/agent-research/AGENTS.md +160 -0
- package/assets/.agents/ACE/agent-research/instructions.md +118 -0
- package/assets/.agents/ACE/agent-security/AGENTS.md +48 -0
- package/assets/.agents/ACE/agent-security/instructions.md +50 -0
- package/assets/.agents/ACE/agent-skeptic/AGENTS.md +178 -0
- package/assets/.agents/ACE/agent-skeptic/instructions.md +196 -0
- package/assets/.agents/ACE/agent-spec/AGENTS.md +169 -0
- package/assets/.agents/ACE/agent-spec/instructions.md +116 -0
- package/assets/.agents/ACE/orchestrator/AGENTS.md +365 -0
- package/assets/.agents/ACE/orchestrator/instructions.md +231 -0
- package/assets/.agents/skills/ace-orchestrator/SKILL.md +63 -0
- package/assets/.agents/skills/ace-orchestrator/references/engineering-bootstrap-playbook.md +360 -0
- package/assets/.agents/skills/astgrep-index/SKILL.md +58 -0
- package/assets/.agents/skills/codemunch/SKILL.md +65 -0
- package/assets/.agents/skills/codemunch/references/ast-driven-protocol.md +543 -0
- package/assets/.agents/skills/codesnipe/SKILL.md +64 -0
- package/assets/.agents/skills/codesnipe/references/dual-codebase-playbook.md +671 -0
- package/assets/.agents/skills/eval-harness/SKILL.md +203 -0
- package/assets/.agents/skills/handoff-lint/SKILL.md +164 -0
- package/assets/.agents/skills/incident-commander/SKILL.md +174 -0
- package/assets/.agents/skills/landing-review-watcher/SKILL.md +68 -0
- package/assets/.agents/skills/memory-curator/SKILL.md +179 -0
- package/assets/.agents/skills/problem-triage/SKILL.md +57 -0
- package/assets/.agents/skills/problem-triage/agents/openai.yaml +3 -0
- package/assets/.agents/skills/release-sentry/SKILL.md +189 -0
- package/assets/.agents/skills/risk-quant/SKILL.md +190 -0
- package/assets/.agents/skills/schema-forge/SKILL.md +174 -0
- package/assets/.agents/skills/skill-auditor/SKILL.md +52 -0
- package/assets/.agents/skills/state-auditor/SKILL.md +182 -0
- package/assets/.github/hooks/ace-copilot.json +68 -0
- package/assets/agent-state/ACE_WORKFLOW.md +131 -0
- package/assets/agent-state/ARTIFACT_MANIFEST.json +5 -0
- package/assets/agent-state/AST_GREP_COMMANDS.md +121 -0
- package/assets/agent-state/AST_GREP_INDEX.json +13 -0
- package/assets/agent-state/AST_GREP_INDEX.md +15 -0
- package/assets/agent-state/DECISIONS.md +7 -0
- package/assets/agent-state/EVIDENCE_LOG.md +7 -0
- package/assets/agent-state/HANDOFF.json +24 -0
- package/assets/agent-state/INTERFACE_REGISTRY.md +75 -0
- package/assets/agent-state/MODULES/gates/gate-autonomy.json +7 -0
- package/assets/agent-state/MODULES/gates/gate-completeness.json +7 -0
- package/assets/agent-state/MODULES/gates/gate-correctness.json +7 -0
- package/assets/agent-state/MODULES/gates/gate-evaluation.json +7 -0
- package/assets/agent-state/MODULES/gates/gate-operability.json +7 -0
- package/assets/agent-state/MODULES/gates/gate-security.json +7 -0
- package/assets/agent-state/MODULES/gates/gate-typescript-public-surface.json +7 -0
- package/assets/agent-state/MODULES/registry.json +41 -0
- package/assets/agent-state/MODULES/roles/capability-astgrep.json +49 -0
- package/assets/agent-state/MODULES/roles/capability-build.json +39 -0
- package/assets/agent-state/MODULES/roles/capability-docs.json +38 -0
- package/assets/agent-state/MODULES/roles/capability-eval.json +20 -0
- package/assets/agent-state/MODULES/roles/capability-memory.json +20 -0
- package/assets/agent-state/MODULES/roles/capability-observability.json +20 -0
- package/assets/agent-state/MODULES/roles/capability-ops.json +45 -0
- package/assets/agent-state/MODULES/roles/capability-qa.json +40 -0
- package/assets/agent-state/MODULES/roles/capability-release.json +21 -0
- package/assets/agent-state/MODULES/roles/capability-research.json +44 -0
- package/assets/agent-state/MODULES/roles/capability-security.json +21 -0
- package/assets/agent-state/MODULES/roles/capability-skeptic.json +48 -0
- package/assets/agent-state/MODULES/roles/capability-spec.json +42 -0
- package/assets/agent-state/MODULES/schemas/ACE_RUNTIME_PROFILE.schema.json +289 -0
- package/assets/agent-state/MODULES/schemas/ARTIFACT_MANIFEST.schema.json +185 -0
- package/assets/agent-state/MODULES/schemas/HANDOFF.agent-state.schema.json +124 -0
- package/assets/agent-state/MODULES/schemas/HANDOFF.schema.json +55 -0
- package/assets/agent-state/MODULES/schemas/RUNTIME_EXECUTOR_SESSION_REGISTRY.schema.json +290 -0
- package/assets/agent-state/MODULES/schemas/RUNTIME_TOOL_SPEC_REGISTRY.schema.json +144 -0
- package/assets/agent-state/MODULES/schemas/STATUS_EVENT.schema.json +84 -0
- package/assets/agent-state/MODULES/schemas/SWARM_HANDOFF.schema.json +138 -0
- package/assets/agent-state/MODULES/schemas/TRACKER_SNAPSHOT.schema.json +134 -0
- package/assets/agent-state/MODULES/schemas/VERICIFY_BRIDGE_SNAPSHOT.schema.json +157 -0
- package/assets/agent-state/MODULES/schemas/VERICIFY_PROCESS_POST_LOG.schema.json +93 -0
- package/assets/agent-state/MODULES/schemas/WORKSPACE_SESSION_REGISTRY.schema.json +133 -0
- package/assets/agent-state/PROVENANCE_LOG.md +28 -0
- package/assets/agent-state/QUALITY_GATES.md +15 -0
- package/assets/agent-state/RISKS.md +8 -0
- package/assets/agent-state/SCOPE.md +20 -0
- package/assets/agent-state/SKILL_CATALOG.md +48 -0
- package/assets/agent-state/STATUS.md +8 -0
- package/assets/agent-state/STATUS_EVENTS.ndjson +1 -0
- package/assets/agent-state/TASK.md +18 -0
- package/assets/agent-state/TEAL_CONFIG.md +117 -0
- package/assets/agent-state/handoff-registry.json +5 -0
- package/assets/agent-state/index-fingerprints.json +7 -0
- package/assets/agent-state/index.json +32 -0
- package/assets/agent-state/run-ledger.json +5 -0
- package/assets/agent-state/runtime-executor-sessions.json +5 -0
- package/assets/agent-state/runtime-tool-specs.json +5 -0
- package/assets/agent-state/runtime-workspaces.json +5 -0
- package/assets/agent-state/todo-state.json +7 -0
- package/assets/agent-state/tracker-snapshot.json +7 -0
- package/assets/agent-state/vericify/ace-bridge.json +60 -0
- package/assets/agent-state/vericify/process-posts.json +5 -0
- package/assets/instructions/ACE.instructions.md +187 -0
- package/assets/instructions/ACE_Coder.instructions.md +146 -0
- package/assets/instructions/ACE_UI.instructions.md +178 -0
- package/assets/instructions/ACE_VOS.instructions.md +211 -0
- package/assets/scripts/ace-hook-dispatch.mjs +538 -0
- package/assets/scripts/bootstrap-workspace.sh +27 -0
- package/assets/scripts/copilot-hook-dispatch.mjs +3 -0
- package/assets/scripts/eval-harness.sh +68 -0
- package/assets/scripts/render-mcp-configs.sh +396 -0
- package/assets/tasks/README.md +48 -0
- package/assets/tasks/SWARM_HANDOFF.example.json +53 -0
- package/assets/tasks/SWARM_HANDOFF.example_ui_to_coders.json +55 -0
- package/assets/tasks/SWARM_HANDOFF.example_vos_to_ui.json +55 -0
- package/assets/tasks/SWARM_HANDOFF.template.json +52 -0
- package/assets/tasks/cli_work_split.md +22 -0
- package/assets/tasks/lessons.md +17 -0
- package/assets/tasks/role_tasks.md +206 -0
- package/assets/tasks/todo.md +23 -0
- package/dist/ace-autonomy.d.ts +137 -0
- package/dist/ace-autonomy.js +472 -0
- package/dist/ace-context.d.ts +29 -0
- package/dist/ace-context.js +240 -0
- package/dist/ace-internal-tools.d.ts +8 -0
- package/dist/ace-internal-tools.js +76 -0
- package/dist/ace-server-instructions.d.ts +12 -0
- package/dist/ace-server-instructions.js +324 -0
- package/dist/agent-runtime/role-adapters.d.ts +29 -0
- package/dist/agent-runtime/role-adapters.js +573 -0
- package/dist/astgrep-index.d.ts +24 -0
- package/dist/astgrep-index.js +476 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +591 -0
- package/dist/git-ops.d.ts +53 -0
- package/dist/git-ops.js +238 -0
- package/dist/handoff-registry.d.ts +71 -0
- package/dist/handoff-registry.js +422 -0
- package/dist/helpers.d.ts +126 -0
- package/dist/helpers.js +1687 -0
- package/dist/index-store.d.ts +51 -0
- package/dist/index-store.js +328 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +7 -0
- package/dist/internal-tool-runtime.d.ts +21 -0
- package/dist/internal-tool-runtime.js +136 -0
- package/dist/job-scheduler.d.ts +175 -0
- package/dist/job-scheduler.js +1217 -0
- package/dist/kanban.d.ts +27 -0
- package/dist/kanban.js +339 -0
- package/dist/local-model-runtime.d.ts +40 -0
- package/dist/local-model-runtime.js +174 -0
- package/dist/model-bridge.d.ts +54 -0
- package/dist/model-bridge.js +587 -0
- package/dist/orchestrator-supervisor.d.ts +100 -0
- package/dist/orchestrator-supervisor.js +399 -0
- package/dist/problem-triage.d.ts +23 -0
- package/dist/problem-triage.js +448 -0
- package/dist/prompts.d.ts +7 -0
- package/dist/prompts.js +628 -0
- package/dist/public-surface.d.ts +30 -0
- package/dist/public-surface.js +316 -0
- package/dist/resources.d.ts +7 -0
- package/dist/resources.js +545 -0
- package/dist/run-ledger.d.ts +36 -0
- package/dist/run-ledger.js +257 -0
- package/dist/runtime-command.d.ts +18 -0
- package/dist/runtime-command.js +76 -0
- package/dist/runtime-executor.d.ts +104 -0
- package/dist/runtime-executor.js +985 -0
- package/dist/runtime-profile.d.ts +116 -0
- package/dist/runtime-profile.js +532 -0
- package/dist/runtime-tool-specs.d.ts +68 -0
- package/dist/runtime-tool-specs.js +527 -0
- package/dist/safe-edit.d.ts +52 -0
- package/dist/safe-edit.js +255 -0
- package/dist/schemas.d.ts +44 -0
- package/dist/schemas.js +830 -0
- package/dist/semantic-cache.d.ts +147 -0
- package/dist/semantic-cache.js +552 -0
- package/dist/semantic-hash.d.ts +83 -0
- package/dist/semantic-hash.js +346 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.js +46 -0
- package/dist/shared.d.ts +136 -0
- package/dist/shared.js +269 -0
- package/dist/skill-auditor.d.ts +26 -0
- package/dist/skill-auditor.js +184 -0
- package/dist/skill-catalog.d.ts +60 -0
- package/dist/skill-catalog.js +305 -0
- package/dist/status-events.d.ts +40 -0
- package/dist/status-events.js +269 -0
- package/dist/store/ace-packed-store.d.ts +69 -0
- package/dist/store/ace-packed-store.js +434 -0
- package/dist/store/bootstrap-store.d.ts +46 -0
- package/dist/store/bootstrap-store.js +242 -0
- package/dist/store/catalog-builder.d.ts +21 -0
- package/dist/store/catalog-builder.js +68 -0
- package/dist/store/importer.d.ts +19 -0
- package/dist/store/importer.js +157 -0
- package/dist/store/knowledge-bake.d.ts +59 -0
- package/dist/store/knowledge-bake.js +339 -0
- package/dist/store/materializers/hook-context-materializer.d.ts +25 -0
- package/dist/store/materializers/hook-context-materializer.js +100 -0
- package/dist/store/materializers/host-file-materializer.d.ts +37 -0
- package/dist/store/materializers/host-file-materializer.js +271 -0
- package/dist/store/materializers/todo-syncer.d.ts +30 -0
- package/dist/store/materializers/todo-syncer.js +140 -0
- package/dist/store/materializers/vericify-projector.d.ts +38 -0
- package/dist/store/materializers/vericify-projector.js +239 -0
- package/dist/store/repositories/discovery-repository.d.ts +24 -0
- package/dist/store/repositories/discovery-repository.js +58 -0
- package/dist/store/repositories/handoff-repository.d.ts +31 -0
- package/dist/store/repositories/handoff-repository.js +67 -0
- package/dist/store/repositories/ledger-repository.d.ts +26 -0
- package/dist/store/repositories/ledger-repository.js +49 -0
- package/dist/store/repositories/runtime-kv-repository.d.ts +16 -0
- package/dist/store/repositories/runtime-kv-repository.js +36 -0
- package/dist/store/repositories/scheduler-repository.d.ts +50 -0
- package/dist/store/repositories/scheduler-repository.js +123 -0
- package/dist/store/repositories/session-repository.d.ts +33 -0
- package/dist/store/repositories/session-repository.js +82 -0
- package/dist/store/repositories/todo-repository.d.ts +31 -0
- package/dist/store/repositories/todo-repository.js +77 -0
- package/dist/store/repositories/tracker-repository.d.ts +25 -0
- package/dist/store/repositories/tracker-repository.js +43 -0
- package/dist/store/repositories/vericify-repository.d.ts +32 -0
- package/dist/store/repositories/vericify-repository.js +58 -0
- package/dist/store/skills-install.d.ts +28 -0
- package/dist/store/skills-install.js +86 -0
- package/dist/store/state-reader.d.ts +49 -0
- package/dist/store/state-reader.js +111 -0
- package/dist/store/store-artifacts.d.ts +12 -0
- package/dist/store/store-artifacts.js +138 -0
- package/dist/store/store-snapshot.d.ts +19 -0
- package/dist/store/store-snapshot.js +140 -0
- package/dist/store/topology-bake.d.ts +15 -0
- package/dist/store/topology-bake.js +215 -0
- package/dist/store/types.d.ts +155 -0
- package/dist/store/types.js +35 -0
- package/dist/store/workspace-snapshot.d.ts +26 -0
- package/dist/store/workspace-snapshot.js +107 -0
- package/dist/store/write-queue.d.ts +7 -0
- package/dist/store/write-queue.js +26 -0
- package/dist/todo-state.d.ts +41 -0
- package/dist/todo-state.js +399 -0
- package/dist/tools-agent.d.ts +7 -0
- package/dist/tools-agent.js +1542 -0
- package/dist/tools-discovery.d.ts +6 -0
- package/dist/tools-discovery.js +178 -0
- package/dist/tools-drift.d.ts +13 -0
- package/dist/tools-drift.js +357 -0
- package/dist/tools-files.d.ts +6 -0
- package/dist/tools-files.js +679 -0
- package/dist/tools-framework.d.ts +7 -0
- package/dist/tools-framework.js +1414 -0
- package/dist/tools-git.d.ts +6 -0
- package/dist/tools-git.js +183 -0
- package/dist/tools-handoff.d.ts +32 -0
- package/dist/tools-handoff.js +489 -0
- package/dist/tools-lifecycle.d.ts +6 -0
- package/dist/tools-lifecycle.js +205 -0
- package/dist/tools-memory.d.ts +6 -0
- package/dist/tools-memory.js +260 -0
- package/dist/tools-scheduler.d.ts +6 -0
- package/dist/tools-scheduler.js +228 -0
- package/dist/tools-skills.d.ts +3 -0
- package/dist/tools-skills.js +104 -0
- package/dist/tools-todo.d.ts +6 -0
- package/dist/tools-todo.js +154 -0
- package/dist/tools.d.ts +9 -0
- package/dist/tools.js +33 -0
- package/dist/tracker-adapters.d.ts +74 -0
- package/dist/tracker-adapters.js +776 -0
- package/dist/tracker-sync.d.ts +10 -0
- package/dist/tracker-sync.js +84 -0
- package/dist/tui/agent-runner.d.ts +137 -0
- package/dist/tui/agent-runner.js +466 -0
- package/dist/tui/agent-worker.d.ts +10 -0
- package/dist/tui/agent-worker.js +347 -0
- package/dist/tui/chat.d.ts +84 -0
- package/dist/tui/chat.js +368 -0
- package/dist/tui/commands.d.ts +57 -0
- package/dist/tui/commands.js +432 -0
- package/dist/tui/dashboard.d.ts +24 -0
- package/dist/tui/dashboard.js +110 -0
- package/dist/tui/index.d.ts +114 -0
- package/dist/tui/index.js +1059 -0
- package/dist/tui/input.d.ts +49 -0
- package/dist/tui/input.js +336 -0
- package/dist/tui/layout.d.ts +116 -0
- package/dist/tui/layout.js +367 -0
- package/dist/tui/ollama.d.ts +116 -0
- package/dist/tui/ollama.js +192 -0
- package/dist/tui/openai-compatible.d.ts +63 -0
- package/dist/tui/openai-compatible.js +370 -0
- package/dist/tui/provider-discovery.d.ts +59 -0
- package/dist/tui/provider-discovery.js +530 -0
- package/dist/tui/renderer.d.ts +166 -0
- package/dist/tui/renderer.js +304 -0
- package/dist/tui/tabs.d.ts +70 -0
- package/dist/tui/tabs.js +208 -0
- package/dist/tui/telemetry.d.ts +56 -0
- package/dist/tui/telemetry.js +106 -0
- package/dist/vericify-bridge.d.ts +146 -0
- package/dist/vericify-bridge.js +571 -0
- package/dist/vericify-context.d.ts +10 -0
- package/dist/vericify-context.js +72 -0
- package/dist/workspace-manager.d.ts +107 -0
- package/dist/workspace-manager.js +636 -0
- package/package.json +83 -0
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { executeAceInternalTool, listAceInternalToolCatalog, } from "./ace-internal-tools.js";
|
|
5
|
+
import { appendVericifyProcessPostSafe, deriveWorkspaceVericifyRunRef, } from "./vericify-bridge.js";
|
|
6
|
+
import { buildToolPlan, renderAceContext } from "./ace-context.js";
|
|
7
|
+
function resolveProviderClient(input) {
|
|
8
|
+
const display = input.trim() || "ollama";
|
|
9
|
+
const normalized = display.toLowerCase();
|
|
10
|
+
return normalized === "ollama"
|
|
11
|
+
? { display, client: "ollama" }
|
|
12
|
+
: { display, client: "openai-compatible" };
|
|
13
|
+
}
|
|
14
|
+
function extractJsonEnvelope(raw) {
|
|
15
|
+
const trimmed = raw.trim();
|
|
16
|
+
if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
|
|
17
|
+
return trimmed;
|
|
18
|
+
}
|
|
19
|
+
const fenced = trimmed.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
20
|
+
if (fenced?.[1]) {
|
|
21
|
+
return fenced[1].trim();
|
|
22
|
+
}
|
|
23
|
+
const firstBrace = trimmed.indexOf("{");
|
|
24
|
+
if (firstBrace < 0) {
|
|
25
|
+
return trimmed;
|
|
26
|
+
}
|
|
27
|
+
let depth = 0;
|
|
28
|
+
let inString = false;
|
|
29
|
+
let escape = false;
|
|
30
|
+
for (let index = firstBrace; index < trimmed.length; index += 1) {
|
|
31
|
+
const ch = trimmed[index];
|
|
32
|
+
if (escape) {
|
|
33
|
+
escape = false;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
if (ch === "\\") {
|
|
37
|
+
escape = true;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (ch === '"') {
|
|
41
|
+
inString = !inString;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (inString)
|
|
45
|
+
continue;
|
|
46
|
+
if (ch === "{")
|
|
47
|
+
depth += 1;
|
|
48
|
+
if (ch === "}") {
|
|
49
|
+
depth -= 1;
|
|
50
|
+
if (depth === 0) {
|
|
51
|
+
return trimmed.slice(firstBrace, index + 1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return trimmed;
|
|
56
|
+
}
|
|
57
|
+
function parseEnvelope(raw) {
|
|
58
|
+
const candidate = extractJsonEnvelope(raw);
|
|
59
|
+
try {
|
|
60
|
+
const parsed = JSON.parse(candidate);
|
|
61
|
+
if (!parsed || typeof parsed !== "object") {
|
|
62
|
+
throw new Error("response is not an object");
|
|
63
|
+
}
|
|
64
|
+
if (!parsed.status) {
|
|
65
|
+
throw new Error("missing status");
|
|
66
|
+
}
|
|
67
|
+
return parsed;
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return {
|
|
71
|
+
status: "message",
|
|
72
|
+
message: raw.trim(),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function parseToolPlan(raw, catalog) {
|
|
77
|
+
const candidate = extractJsonEnvelope(raw);
|
|
78
|
+
const allowedTools = new Set(catalog.map((tool) => tool.name));
|
|
79
|
+
try {
|
|
80
|
+
const parsed = JSON.parse(candidate);
|
|
81
|
+
const selectedSource = parsed.selected_tools ?? parsed.tool_scope ?? parsed.tools;
|
|
82
|
+
const selected = Array.isArray(selectedSource)
|
|
83
|
+
? selectedSource
|
|
84
|
+
.filter((entry) => typeof entry === "string")
|
|
85
|
+
.map((entry) => entry.trim())
|
|
86
|
+
.filter((entry) => entry.length > 0 && allowedTools.has(entry))
|
|
87
|
+
: [];
|
|
88
|
+
return {
|
|
89
|
+
selected_tools: Array.from(new Set(selected)),
|
|
90
|
+
reasoning: typeof parsed.reasoning === "string" ? parsed.reasoning.trim() : undefined,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return { selected_tools: [] };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function summarizeToolText(result) {
|
|
98
|
+
if (!result || typeof result !== "object")
|
|
99
|
+
return "Tool returned no structured result.";
|
|
100
|
+
const textParts = Array.isArray(result.content)
|
|
101
|
+
? result.content
|
|
102
|
+
.filter((entry) => Boolean(entry) && typeof entry === "object" && entry.type === "text")
|
|
103
|
+
.map((entry) => String(entry.text ?? "").trim())
|
|
104
|
+
.filter(Boolean)
|
|
105
|
+
: [];
|
|
106
|
+
if (textParts.length > 0) {
|
|
107
|
+
return textParts.join("\n");
|
|
108
|
+
}
|
|
109
|
+
return String(result.summary ?? "Tool completed.");
|
|
110
|
+
}
|
|
111
|
+
function estimateTokenCount(text) {
|
|
112
|
+
return Math.max(1, Math.ceil(text.length / 4));
|
|
113
|
+
}
|
|
114
|
+
function messageText(message) {
|
|
115
|
+
return typeof message.content === "string" ? message.content : "";
|
|
116
|
+
}
|
|
117
|
+
function estimateMessageTokens(messages) {
|
|
118
|
+
return messages.reduce((total, message) => total + estimateTokenCount(`${message.role}: ${messageText(message)}`), 0);
|
|
119
|
+
}
|
|
120
|
+
function calculateContextBudget(numCtx) {
|
|
121
|
+
const reserve = Math.max(256, Math.min(2048, Math.floor(numCtx * 0.25)));
|
|
122
|
+
return Math.max(384, numCtx - reserve);
|
|
123
|
+
}
|
|
124
|
+
function summarizeSnippet(text, maxChars = 240) {
|
|
125
|
+
const normalized = text.replace(/\s+/g, " ").trim();
|
|
126
|
+
if (normalized.length <= maxChars)
|
|
127
|
+
return normalized;
|
|
128
|
+
return `${normalized.slice(0, Math.max(0, maxChars - 1)).trimEnd()}…`;
|
|
129
|
+
}
|
|
130
|
+
function buildHistorySummary(messages, maxChars) {
|
|
131
|
+
const lines = messages.slice(-8).map((message) => {
|
|
132
|
+
const content = summarizeSnippet(messageText(message).replace(/^Conversation summary:\s*/i, ""), 220);
|
|
133
|
+
return `- ${message.role}: ${content || "[empty]"}`;
|
|
134
|
+
});
|
|
135
|
+
const summary = [
|
|
136
|
+
"Conversation summary:",
|
|
137
|
+
...lines,
|
|
138
|
+
"Use the recent turns below as the source of truth for the next action.",
|
|
139
|
+
].join("\n");
|
|
140
|
+
if (summary.length <= maxChars)
|
|
141
|
+
return summary;
|
|
142
|
+
return `${summary.slice(0, Math.max(0, maxChars - 1)).trimEnd()}…`;
|
|
143
|
+
}
|
|
144
|
+
function compressConversationHistory(messages, numCtx) {
|
|
145
|
+
const promptTokens = estimateMessageTokens(messages);
|
|
146
|
+
const budget = calculateContextBudget(numCtx);
|
|
147
|
+
if (promptTokens <= budget || messages.length <= 3) {
|
|
148
|
+
return { messages, promptTokens, compressed: false };
|
|
149
|
+
}
|
|
150
|
+
const systemMessage = messages[0];
|
|
151
|
+
if (!systemMessage) {
|
|
152
|
+
return { messages, promptTokens, compressed: false };
|
|
153
|
+
}
|
|
154
|
+
let recentMessages = messages.slice(-2);
|
|
155
|
+
const olderMessages = messages.slice(1, -recentMessages.length);
|
|
156
|
+
if (olderMessages.length === 0) {
|
|
157
|
+
return { messages, promptTokens, compressed: false };
|
|
158
|
+
}
|
|
159
|
+
let summaryChars = Math.max(320, Math.min(1400, Math.floor((budget * 4) * 0.35)));
|
|
160
|
+
let summaryMessage = {
|
|
161
|
+
role: "system",
|
|
162
|
+
content: buildHistorySummary(olderMessages, summaryChars),
|
|
163
|
+
};
|
|
164
|
+
let compressed = [systemMessage, summaryMessage, ...recentMessages];
|
|
165
|
+
while (estimateMessageTokens(compressed) > budget && summaryChars > 240) {
|
|
166
|
+
summaryChars = Math.max(240, Math.floor(summaryChars * 0.75));
|
|
167
|
+
summaryMessage = {
|
|
168
|
+
role: "system",
|
|
169
|
+
content: buildHistorySummary(olderMessages, summaryChars),
|
|
170
|
+
};
|
|
171
|
+
compressed = [systemMessage, summaryMessage, ...recentMessages];
|
|
172
|
+
if (estimateMessageTokens(compressed) <= budget)
|
|
173
|
+
break;
|
|
174
|
+
if (recentMessages.length > 2) {
|
|
175
|
+
recentMessages = recentMessages.slice(-2);
|
|
176
|
+
compressed = [systemMessage, summaryMessage, ...recentMessages];
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
messages: compressed,
|
|
181
|
+
promptTokens: estimateMessageTokens(compressed),
|
|
182
|
+
compressed: true,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function buildTierFallbackOrder(tier) {
|
|
186
|
+
if (tier === "full")
|
|
187
|
+
return ["full", "compressed", "brief"];
|
|
188
|
+
if (tier === "compressed")
|
|
189
|
+
return ["compressed", "brief"];
|
|
190
|
+
return ["brief"];
|
|
191
|
+
}
|
|
192
|
+
function sanitizeToolName(tool) {
|
|
193
|
+
const normalized = tool.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-");
|
|
194
|
+
return normalized.length > 0 ? normalized.slice(0, 48) : "tool";
|
|
195
|
+
}
|
|
196
|
+
function truncateToolResult(result, workspace, maxChars = 3000) {
|
|
197
|
+
if (result.summary.length <= maxChars) {
|
|
198
|
+
return result;
|
|
199
|
+
}
|
|
200
|
+
const relativePath = `agent-state/bridge-results/${sanitizeToolName(result.tool)}-${Date.now()}.txt`;
|
|
201
|
+
const absolutePath = resolve(workspace, relativePath);
|
|
202
|
+
mkdirSync(dirname(absolutePath), { recursive: true });
|
|
203
|
+
writeFileSync(absolutePath, result.summary, "utf-8");
|
|
204
|
+
return {
|
|
205
|
+
...result,
|
|
206
|
+
summary: `${result.summary.slice(0, maxChars).trimEnd()}\n[truncated — full output: ${relativePath}]`,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
function formatErrorMessage(error) {
|
|
210
|
+
return error instanceof Error ? error.message : String(error);
|
|
211
|
+
}
|
|
212
|
+
function isRetryableProviderError(error) {
|
|
213
|
+
const message = formatErrorMessage(error).toLowerCase();
|
|
214
|
+
return !/(abort|aborted|cancelled|canceled|interrupted)/.test(message);
|
|
215
|
+
}
|
|
216
|
+
function formatToolFeedback(results) {
|
|
217
|
+
return [
|
|
218
|
+
"Tool execution results:",
|
|
219
|
+
...results.map((result) => `- ${result.tool}: ${result.ok ? "ok" : "error"} — ${result.summary}`),
|
|
220
|
+
"Continue with another JSON response.",
|
|
221
|
+
].join("\n");
|
|
222
|
+
}
|
|
223
|
+
async function collectOllamaResponse(client, model, messages, options) {
|
|
224
|
+
let combined = "";
|
|
225
|
+
for await (const chunk of client.chat({
|
|
226
|
+
model,
|
|
227
|
+
messages,
|
|
228
|
+
stream: true,
|
|
229
|
+
options: {
|
|
230
|
+
temperature: 0.2,
|
|
231
|
+
top_p: 0.9,
|
|
232
|
+
num_ctx: options?.num_ctx ?? 8192,
|
|
233
|
+
},
|
|
234
|
+
})) {
|
|
235
|
+
combined += chunk.message?.content ?? "";
|
|
236
|
+
if (chunk.done)
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
return combined;
|
|
240
|
+
}
|
|
241
|
+
async function collectOpenAiCompatibleResponse(client, provider, model, messages) {
|
|
242
|
+
let combined = "";
|
|
243
|
+
for await (const chunk of client.chat({
|
|
244
|
+
provider,
|
|
245
|
+
model,
|
|
246
|
+
messages,
|
|
247
|
+
temperature: 0.2,
|
|
248
|
+
topP: 0.9,
|
|
249
|
+
})) {
|
|
250
|
+
combined += chunk.text;
|
|
251
|
+
if (chunk.done)
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
return combined;
|
|
255
|
+
}
|
|
256
|
+
async function collectProviderResponse(clients, provider, options) {
|
|
257
|
+
return provider.client === "ollama"
|
|
258
|
+
? collectOllamaResponse(clients.ollama, options.model, options.messages, {
|
|
259
|
+
num_ctx: options.numCtx,
|
|
260
|
+
})
|
|
261
|
+
: collectOpenAiCompatibleResponse(clients.openai, provider.display, options.model, options.messages);
|
|
262
|
+
}
|
|
263
|
+
async function collectProviderResponseWithRetry(clients, provider, options, onThinking) {
|
|
264
|
+
try {
|
|
265
|
+
return await collectProviderResponse(clients, provider, options);
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
if (!isRetryableProviderError(error)) {
|
|
269
|
+
throw error;
|
|
270
|
+
}
|
|
271
|
+
onThinking?.(`Provider error, retrying once: ${formatErrorMessage(error)}`);
|
|
272
|
+
return collectProviderResponse(clients, provider, options);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
export class ModelBridge {
|
|
276
|
+
clients;
|
|
277
|
+
activeProviderClient = null;
|
|
278
|
+
bridgeId = randomUUID();
|
|
279
|
+
currentRunChildResults = null;
|
|
280
|
+
constructor(clients) {
|
|
281
|
+
this.clients = clients;
|
|
282
|
+
}
|
|
283
|
+
interrupt() {
|
|
284
|
+
if (this.activeProviderClient === "ollama") {
|
|
285
|
+
this.clients.ollama.abort();
|
|
286
|
+
}
|
|
287
|
+
else if (this.activeProviderClient) {
|
|
288
|
+
this.clients.openai.abort();
|
|
289
|
+
}
|
|
290
|
+
this.activeProviderClient = null;
|
|
291
|
+
}
|
|
292
|
+
async spawn(options) {
|
|
293
|
+
const refs = deriveWorkspaceVericifyRunRef({
|
|
294
|
+
session_id: this.bridgeId,
|
|
295
|
+
role: options.role,
|
|
296
|
+
});
|
|
297
|
+
await appendVericifyProcessPostSafe({
|
|
298
|
+
run_id: refs.run_id,
|
|
299
|
+
branch_id: refs.branch_id,
|
|
300
|
+
lane_id: refs.lane_id,
|
|
301
|
+
agent_id: `agent-${options.role}`,
|
|
302
|
+
kind: "handoff_note",
|
|
303
|
+
summary: `Spawned child bridge for ${options.role}: ${options.task}`,
|
|
304
|
+
tool_refs: [],
|
|
305
|
+
});
|
|
306
|
+
const child = new ModelBridge(this.clients);
|
|
307
|
+
const result = await child.run({
|
|
308
|
+
...options,
|
|
309
|
+
parentBridge: this.bridgeId,
|
|
310
|
+
});
|
|
311
|
+
if (this.currentRunChildResults) {
|
|
312
|
+
this.currentRunChildResults.push(result);
|
|
313
|
+
}
|
|
314
|
+
return result;
|
|
315
|
+
}
|
|
316
|
+
async selectToolScope(input) {
|
|
317
|
+
const plan = buildToolPlan({
|
|
318
|
+
task: input.task,
|
|
319
|
+
role: input.role,
|
|
320
|
+
workspace: "",
|
|
321
|
+
tier: input.tier,
|
|
322
|
+
});
|
|
323
|
+
if (plan.catalog.length === 0)
|
|
324
|
+
return undefined;
|
|
325
|
+
const selectionMessages = [
|
|
326
|
+
{ role: "system", content: plan.prompt },
|
|
327
|
+
{ role: "user", content: input.task },
|
|
328
|
+
];
|
|
329
|
+
try {
|
|
330
|
+
this.activeProviderClient = input.provider.client;
|
|
331
|
+
const rawSelection = await collectProviderResponse(this.clients, input.provider, {
|
|
332
|
+
model: input.model,
|
|
333
|
+
messages: selectionMessages,
|
|
334
|
+
numCtx: Math.min(input.numCtx, 8192),
|
|
335
|
+
});
|
|
336
|
+
const parsed = parseToolPlan(rawSelection, plan.catalog);
|
|
337
|
+
const scoped = parsed.selected_tools.slice(0, plan.selection_limit);
|
|
338
|
+
if (scoped.length === 0)
|
|
339
|
+
return undefined;
|
|
340
|
+
const thinking = parsed.reasoning?.trim();
|
|
341
|
+
input.onThinking?.(thinking
|
|
342
|
+
? `Tool plan: ${scoped.join(", ")}. ${thinking}`
|
|
343
|
+
: `Tool plan: ${scoped.join(", ")}`);
|
|
344
|
+
return scoped;
|
|
345
|
+
}
|
|
346
|
+
finally {
|
|
347
|
+
this.activeProviderClient = null;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
async run(options) {
|
|
351
|
+
const role = options.role.trim().toLowerCase().replace(/^agent-/, "");
|
|
352
|
+
const requestedTier = options.tier ?? "compressed";
|
|
353
|
+
const provider = resolveProviderClient(options.provider);
|
|
354
|
+
const numCtx = options.numCtx ??
|
|
355
|
+
(requestedTier === "brief" ? 4096 : requestedTier === "compressed" ? 8192 : 16384);
|
|
356
|
+
const explicitToolScope = options.toolScope?.map((tool) => tool.trim()).filter((tool) => tool.length > 0) ?? [];
|
|
357
|
+
const toolScopeLocked = explicitToolScope.length > 0;
|
|
358
|
+
const selectedToolScope = explicitToolScope.length > 0
|
|
359
|
+
? explicitToolScope
|
|
360
|
+
: await this.selectToolScope({
|
|
361
|
+
task: options.task,
|
|
362
|
+
role,
|
|
363
|
+
tier: requestedTier,
|
|
364
|
+
model: options.model,
|
|
365
|
+
numCtx,
|
|
366
|
+
provider,
|
|
367
|
+
onThinking: options.onThinking,
|
|
368
|
+
});
|
|
369
|
+
let aceContext = renderAceContext({
|
|
370
|
+
task: options.task,
|
|
371
|
+
role,
|
|
372
|
+
workspace: options.workspace,
|
|
373
|
+
tier: requestedTier,
|
|
374
|
+
tools: selectedToolScope,
|
|
375
|
+
});
|
|
376
|
+
const promptBudget = calculateContextBudget(numCtx);
|
|
377
|
+
for (const candidateTier of buildTierFallbackOrder(requestedTier)) {
|
|
378
|
+
const candidateContext = renderAceContext({
|
|
379
|
+
task: options.task,
|
|
380
|
+
role,
|
|
381
|
+
workspace: options.workspace,
|
|
382
|
+
tier: candidateTier,
|
|
383
|
+
tools: selectedToolScope,
|
|
384
|
+
});
|
|
385
|
+
aceContext = candidateContext;
|
|
386
|
+
if (candidateContext.tokenEstimate <= promptBudget || candidateTier === "brief") {
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
if (aceContext.tier !== requestedTier) {
|
|
391
|
+
options.onThinking?.(`Context tier fallback: ${requestedTier} -> ${aceContext.tier} (budget ~${promptBudget} tokens)`);
|
|
392
|
+
}
|
|
393
|
+
const messages = [
|
|
394
|
+
{ role: "system", content: aceContext.systemPrompt },
|
|
395
|
+
{ role: "user", content: options.task },
|
|
396
|
+
];
|
|
397
|
+
const toolResults = [];
|
|
398
|
+
const childResults = [];
|
|
399
|
+
const sessionId = this.bridgeId;
|
|
400
|
+
const refs = deriveWorkspaceVericifyRunRef({
|
|
401
|
+
session_id: this.bridgeId,
|
|
402
|
+
role,
|
|
403
|
+
});
|
|
404
|
+
const availableTools = new Set(listAceInternalToolCatalog().map((tool) => tool.name));
|
|
405
|
+
const allowedTools = new Set(aceContext.tools.map((tool) => tool.name));
|
|
406
|
+
this.currentRunChildResults = childResults;
|
|
407
|
+
try {
|
|
408
|
+
await appendVericifyProcessPostSafe({
|
|
409
|
+
run_id: refs.run_id,
|
|
410
|
+
branch_id: refs.branch_id,
|
|
411
|
+
lane_id: refs.lane_id,
|
|
412
|
+
agent_id: `agent-${role}`,
|
|
413
|
+
kind: "intent",
|
|
414
|
+
summary: `Bridge started for ${role} via ${provider.display}: ${options.task}`,
|
|
415
|
+
tool_refs: aceContext.tools.map((tool) => tool.name),
|
|
416
|
+
});
|
|
417
|
+
for (let turn = 1; turn <= options.maxTurns; turn += 1) {
|
|
418
|
+
const compressed = compressConversationHistory(messages, numCtx);
|
|
419
|
+
if (compressed.compressed) {
|
|
420
|
+
messages.splice(0, messages.length, ...compressed.messages);
|
|
421
|
+
options.onThinking?.(`Context window compressed to ~${compressed.promptTokens} tokens.`);
|
|
422
|
+
}
|
|
423
|
+
this.activeProviderClient = provider.client;
|
|
424
|
+
const rawResponse = await collectProviderResponseWithRetry(this.clients, provider, {
|
|
425
|
+
model: options.model,
|
|
426
|
+
messages,
|
|
427
|
+
numCtx,
|
|
428
|
+
}, options.onThinking);
|
|
429
|
+
this.activeProviderClient = null;
|
|
430
|
+
const envelope = parseEnvelope(rawResponse);
|
|
431
|
+
if (envelope.thinking) {
|
|
432
|
+
options.onThinking?.(envelope.thinking);
|
|
433
|
+
}
|
|
434
|
+
messages.push({ role: "assistant", content: rawResponse });
|
|
435
|
+
if (envelope.status === "tool" &&
|
|
436
|
+
Array.isArray(envelope.tool_calls) &&
|
|
437
|
+
envelope.tool_calls.length > 0) {
|
|
438
|
+
const requestedOutsideScope = envelope.tool_calls.filter((toolCall) => !allowedTools.has(toolCall.tool));
|
|
439
|
+
const amendedTools = [];
|
|
440
|
+
if (requestedOutsideScope.length > 0 && !toolScopeLocked) {
|
|
441
|
+
for (const toolCall of requestedOutsideScope) {
|
|
442
|
+
if (availableTools.has(toolCall.tool) && !allowedTools.has(toolCall.tool)) {
|
|
443
|
+
allowedTools.add(toolCall.tool);
|
|
444
|
+
amendedTools.push(toolCall.tool);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
if (amendedTools.length > 0) {
|
|
448
|
+
options.onThinking?.(`Tool scope amended: ${amendedTools.join(", ")}`);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
const blockedToolCalls = envelope.tool_calls.filter((toolCall) => !allowedTools.has(toolCall.tool));
|
|
452
|
+
if (blockedToolCalls.length > 0) {
|
|
453
|
+
const blockedResults = blockedToolCalls.map((toolCall) => {
|
|
454
|
+
const result = {
|
|
455
|
+
tool: toolCall.tool,
|
|
456
|
+
ok: false,
|
|
457
|
+
isError: true,
|
|
458
|
+
summary: toolScopeLocked
|
|
459
|
+
? `Tool '${toolCall.tool}' is outside the locked scope.`
|
|
460
|
+
: `Tool '${toolCall.tool}' is not available in the active ACE catalog.`,
|
|
461
|
+
};
|
|
462
|
+
options.onToolResult?.(toolCall.tool, result);
|
|
463
|
+
toolResults.push(result);
|
|
464
|
+
return result;
|
|
465
|
+
});
|
|
466
|
+
messages.push({
|
|
467
|
+
role: "user",
|
|
468
|
+
content: formatToolFeedback(blockedResults),
|
|
469
|
+
});
|
|
470
|
+
continue;
|
|
471
|
+
}
|
|
472
|
+
const executed = await Promise.all(envelope.tool_calls.map(async (toolCall) => {
|
|
473
|
+
const args = toolCall.input ?? {};
|
|
474
|
+
options.onToolCall?.(toolCall.tool, args);
|
|
475
|
+
const rawToolResult = await executeAceInternalTool(toolCall.tool, args, sessionId);
|
|
476
|
+
const result = truncateToolResult({
|
|
477
|
+
tool: toolCall.tool,
|
|
478
|
+
ok: !Boolean(rawToolResult?.isError),
|
|
479
|
+
isError: Boolean(rawToolResult?.isError),
|
|
480
|
+
summary: summarizeToolText(rawToolResult),
|
|
481
|
+
}, options.workspace);
|
|
482
|
+
options.onToolResult?.(toolCall.tool, result);
|
|
483
|
+
toolResults.push(result);
|
|
484
|
+
return result;
|
|
485
|
+
}));
|
|
486
|
+
messages.push({
|
|
487
|
+
role: "user",
|
|
488
|
+
content: amendedTools.length > 0
|
|
489
|
+
? `Tool scope amended to include: ${amendedTools.join(", ")}.\n${formatToolFeedback(executed)}`
|
|
490
|
+
: formatToolFeedback(executed),
|
|
491
|
+
});
|
|
492
|
+
continue;
|
|
493
|
+
}
|
|
494
|
+
if (envelope.status === "message") {
|
|
495
|
+
const message = envelope.message?.trim() || rawResponse.trim();
|
|
496
|
+
options.onOutput?.(message);
|
|
497
|
+
await appendVericifyProcessPostSafe({
|
|
498
|
+
run_id: refs.run_id,
|
|
499
|
+
branch_id: refs.branch_id,
|
|
500
|
+
lane_id: refs.lane_id,
|
|
501
|
+
agent_id: `agent-${role}`,
|
|
502
|
+
kind: "progress",
|
|
503
|
+
summary: message,
|
|
504
|
+
tool_refs: [],
|
|
505
|
+
});
|
|
506
|
+
return {
|
|
507
|
+
bridge_id: this.bridgeId,
|
|
508
|
+
role,
|
|
509
|
+
status: "completed",
|
|
510
|
+
summary: message,
|
|
511
|
+
turns: turn,
|
|
512
|
+
tool_calls: toolResults,
|
|
513
|
+
child_results: childResults,
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
if (envelope.status === "need_input") {
|
|
517
|
+
const message = envelope.message?.trim() || "Additional operator input required.";
|
|
518
|
+
options.onOutput?.(message);
|
|
519
|
+
await appendVericifyProcessPostSafe({
|
|
520
|
+
run_id: refs.run_id,
|
|
521
|
+
branch_id: refs.branch_id,
|
|
522
|
+
lane_id: refs.lane_id,
|
|
523
|
+
agent_id: `agent-${role}`,
|
|
524
|
+
kind: "blocker",
|
|
525
|
+
summary: message,
|
|
526
|
+
tool_refs: [],
|
|
527
|
+
});
|
|
528
|
+
return {
|
|
529
|
+
bridge_id: this.bridgeId,
|
|
530
|
+
role,
|
|
531
|
+
status: "needs_input",
|
|
532
|
+
summary: message,
|
|
533
|
+
turns: turn,
|
|
534
|
+
tool_calls: toolResults,
|
|
535
|
+
child_results: childResults,
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
if (envelope.status === "complete") {
|
|
539
|
+
const summary = envelope.summary?.trim() || "Bridge completed.";
|
|
540
|
+
options.onOutput?.(summary);
|
|
541
|
+
await appendVericifyProcessPostSafe({
|
|
542
|
+
run_id: refs.run_id,
|
|
543
|
+
branch_id: refs.branch_id,
|
|
544
|
+
lane_id: refs.lane_id,
|
|
545
|
+
agent_id: `agent-${role}`,
|
|
546
|
+
kind: "completion",
|
|
547
|
+
summary,
|
|
548
|
+
tool_refs: toolResults.map((entry) => entry.tool),
|
|
549
|
+
});
|
|
550
|
+
return {
|
|
551
|
+
bridge_id: this.bridgeId,
|
|
552
|
+
role,
|
|
553
|
+
status: "completed",
|
|
554
|
+
summary,
|
|
555
|
+
turns: turn,
|
|
556
|
+
tool_calls: toolResults,
|
|
557
|
+
child_results: childResults,
|
|
558
|
+
};
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
const summary = "Bridge stopped after reaching max turns.";
|
|
562
|
+
await appendVericifyProcessPostSafe({
|
|
563
|
+
run_id: refs.run_id,
|
|
564
|
+
branch_id: refs.branch_id,
|
|
565
|
+
lane_id: refs.lane_id,
|
|
566
|
+
agent_id: `agent-${role}`,
|
|
567
|
+
kind: "blocker",
|
|
568
|
+
summary,
|
|
569
|
+
tool_refs: toolResults.map((entry) => entry.tool),
|
|
570
|
+
});
|
|
571
|
+
return {
|
|
572
|
+
bridge_id: this.bridgeId,
|
|
573
|
+
role,
|
|
574
|
+
status: "max_turns",
|
|
575
|
+
summary,
|
|
576
|
+
turns: options.maxTurns,
|
|
577
|
+
tool_calls: toolResults,
|
|
578
|
+
child_results: childResults,
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
finally {
|
|
582
|
+
this.activeProviderClient = null;
|
|
583
|
+
this.currentRunChildResults = null;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
//# sourceMappingURL=model-bridge.js.map
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { BridgeResult } from "./model-bridge.js";
|
|
2
|
+
export type TaskStepStatus = "planned" | "running" | "done" | "failed" | "skipped" | "blocked";
|
|
3
|
+
export type TaskPlanStatus = "planning" | "executing" | "reviewing" | "blocked" | "done" | "failed";
|
|
4
|
+
export interface TaskStep {
|
|
5
|
+
step_id: string;
|
|
6
|
+
role: string;
|
|
7
|
+
task: string;
|
|
8
|
+
depends_on?: string[];
|
|
9
|
+
parallel_group?: string;
|
|
10
|
+
status: TaskStepStatus;
|
|
11
|
+
result_summary?: string;
|
|
12
|
+
evidence_refs?: string[];
|
|
13
|
+
tool_scope?: string[];
|
|
14
|
+
job_id?: string;
|
|
15
|
+
handoff_id?: string;
|
|
16
|
+
blocked_reason?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface TaskPlan {
|
|
19
|
+
plan_id: string;
|
|
20
|
+
task: string;
|
|
21
|
+
steps: TaskStep[];
|
|
22
|
+
status: TaskPlanStatus;
|
|
23
|
+
execution_mode: "sequential" | "scheduled";
|
|
24
|
+
vcx_cursor?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface TaskPlanAmendment {
|
|
27
|
+
steps_to_add?: Array<Omit<TaskStep, "step_id" | "status">>;
|
|
28
|
+
add_after_step_id?: string;
|
|
29
|
+
append_steps?: Array<Omit<TaskStep, "step_id" | "status">>;
|
|
30
|
+
prepend_steps?: Array<Omit<TaskStep, "step_id" | "status">>;
|
|
31
|
+
remove_step_ids?: string[];
|
|
32
|
+
update_steps?: Array<{
|
|
33
|
+
step_id: string;
|
|
34
|
+
patch: Partial<Omit<TaskStep, "step_id">>;
|
|
35
|
+
}>;
|
|
36
|
+
reorder_step_ids?: string[];
|
|
37
|
+
execution_mode?: TaskPlan["execution_mode"];
|
|
38
|
+
vcx_cursor?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface SupervisorHooks {
|
|
41
|
+
spawnStep: (step: TaskStep, plan: TaskPlan) => Promise<BridgeResult>;
|
|
42
|
+
createHandoff?: (input: {
|
|
43
|
+
step: TaskStep;
|
|
44
|
+
plan: TaskPlan;
|
|
45
|
+
}) => Promise<{
|
|
46
|
+
handoff_id: string;
|
|
47
|
+
}>;
|
|
48
|
+
ackHandoff?: (handoffId: string, status: "accepted" | "blocked" | "completed", note?: string) => Promise<void>;
|
|
49
|
+
getVericifyContext?: (plan: TaskPlan) => Promise<unknown>;
|
|
50
|
+
getVericifyDelta?: (since: string, context: {
|
|
51
|
+
plan: TaskPlan;
|
|
52
|
+
step: TaskStep;
|
|
53
|
+
result: BridgeResult;
|
|
54
|
+
}) => Promise<unknown>;
|
|
55
|
+
amendPlan?: (input: {
|
|
56
|
+
plan: TaskPlan;
|
|
57
|
+
step: TaskStep;
|
|
58
|
+
result: BridgeResult;
|
|
59
|
+
vericify_delta?: unknown;
|
|
60
|
+
}) => Promise<TaskPlan | TaskPlanAmendment | undefined> | TaskPlan | TaskPlanAmendment | undefined;
|
|
61
|
+
openCircuitBreaker?: (reason: string, context: {
|
|
62
|
+
plan: TaskPlan;
|
|
63
|
+
step: TaskStep;
|
|
64
|
+
result: BridgeResult;
|
|
65
|
+
}) => Promise<void>;
|
|
66
|
+
closeCircuitBreaker?: (reason: string, context: {
|
|
67
|
+
plan: TaskPlan;
|
|
68
|
+
}) => Promise<void>;
|
|
69
|
+
executeGates?: (plan: TaskPlan) => Promise<unknown>;
|
|
70
|
+
contextSnapshot?: (plan: TaskPlan) => Promise<void>;
|
|
71
|
+
emitStatusEvent?: (input: {
|
|
72
|
+
status: string;
|
|
73
|
+
summary: string;
|
|
74
|
+
step_id?: string;
|
|
75
|
+
}) => Promise<void>;
|
|
76
|
+
}
|
|
77
|
+
export interface SupervisorRunResult {
|
|
78
|
+
plan: TaskPlan;
|
|
79
|
+
handoff_ids: string[];
|
|
80
|
+
job_ids: string[];
|
|
81
|
+
circuit_opened: boolean;
|
|
82
|
+
final_gate?: unknown;
|
|
83
|
+
}
|
|
84
|
+
export declare function deriveTaskPlanStatus(plan: TaskPlan): TaskPlanStatus;
|
|
85
|
+
export declare function createTaskPlan(input: {
|
|
86
|
+
task: string;
|
|
87
|
+
steps: Array<Omit<TaskStep, "step_id" | "status">>;
|
|
88
|
+
execution_mode?: TaskPlan["execution_mode"];
|
|
89
|
+
vcx_cursor?: string;
|
|
90
|
+
}): TaskPlan;
|
|
91
|
+
export declare function getReadyTaskSteps(plan: TaskPlan): TaskStep[];
|
|
92
|
+
export declare function markTaskStepStatus(plan: TaskPlan, stepId: string, status: TaskStepStatus, patch?: Partial<Omit<TaskStep, "step_id" | "status">>): TaskPlan;
|
|
93
|
+
export declare function applyBridgeResultToStep(plan: TaskPlan, stepId: string, result: BridgeResult): TaskPlan;
|
|
94
|
+
export declare function amendTaskPlan(plan: TaskPlan, amendment: TaskPlanAmendment): TaskPlan;
|
|
95
|
+
export declare function promoteParallelGroupToScheduler(plan: TaskPlan, parallelGroup: string, owner?: string): Promise<{
|
|
96
|
+
plan: TaskPlan;
|
|
97
|
+
job_ids: string[];
|
|
98
|
+
}>;
|
|
99
|
+
export declare function superviseTaskPlan(inputPlan: TaskPlan, hooks: SupervisorHooks): Promise<SupervisorRunResult>;
|
|
100
|
+
//# sourceMappingURL=orchestrator-supervisor.d.ts.map
|