@voybio/ace-swarm 0.2.5 → 2.4.1
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 +19 -1
- package/README.md +21 -13
- package/assets/.agents/ACE/agent-qa/instructions.md +11 -0
- package/assets/agent-state/EVIDENCE_LOG.md +1 -1
- package/assets/agent-state/MODULES/roles/capability-framework.json +41 -0
- package/assets/agent-state/MODULES/roles/capability-git.json +33 -0
- package/assets/agent-state/MODULES/roles/capability-safety.json +37 -0
- package/assets/agent-state/MODULES/schemas/ACE_RUNTIME_PROFILE.schema.json +21 -0
- package/assets/agent-state/MODULES/schemas/RUNTIME_EXECUTOR_SESSION_REGISTRY.schema.json +43 -0
- package/assets/agent-state/MODULES/schemas/RUNTIME_TOOL_SPEC_REGISTRY.schema.json +43 -0
- package/assets/agent-state/MODULES/schemas/WORKSPACE_SESSION_REGISTRY.schema.json +11 -0
- package/assets/agent-state/STATUS.md +2 -2
- package/assets/agent-state/runtime-tool-specs.json +70 -2
- package/assets/instructions/ACE_Coder.instructions.md +13 -0
- package/assets/instructions/ACE_UI.instructions.md +11 -0
- package/assets/scripts/ace-hook-dispatch.mjs +70 -6
- package/assets/scripts/render-mcp-configs.sh +19 -5
- package/dist/ace-context.js +91 -11
- package/dist/ace-internal-tools.d.ts +3 -1
- package/dist/ace-internal-tools.js +10 -2
- package/dist/ace-server-instructions.js +3 -3
- package/dist/ace-state-resolver.js +5 -3
- package/dist/agent-runtime/role-adapters.d.ts +18 -1
- package/dist/agent-runtime/role-adapters.js +49 -5
- package/dist/astgrep-index.d.ts +57 -1
- package/dist/astgrep-index.js +140 -4
- package/dist/cli.js +232 -35
- package/dist/discovery-runtime-wrappers.d.ts +108 -0
- package/dist/discovery-runtime-wrappers.js +615 -0
- package/dist/handoff-registry.js +5 -5
- package/dist/helpers/artifacts.d.ts +19 -0
- package/dist/helpers/artifacts.js +152 -0
- package/dist/helpers/bootstrap.d.ts +24 -0
- package/dist/helpers/bootstrap.js +894 -0
- package/dist/helpers/constants.d.ts +53 -0
- package/dist/helpers/constants.js +295 -0
- package/dist/helpers/drift.d.ts +13 -0
- package/dist/helpers/drift.js +45 -0
- package/dist/helpers/path-utils.d.ts +24 -0
- package/dist/helpers/path-utils.js +123 -0
- package/dist/helpers/store-resolution.d.ts +19 -0
- package/dist/helpers/store-resolution.js +305 -0
- package/dist/helpers/workspace-root.d.ts +3 -0
- package/dist/helpers/workspace-root.js +80 -0
- package/dist/helpers.d.ts +8 -125
- package/dist/helpers.js +8 -1768
- package/dist/job-scheduler.js +33 -7
- package/dist/json-sanitizer.d.ts +16 -0
- package/dist/json-sanitizer.js +26 -0
- package/dist/local-model-policy.d.ts +27 -0
- package/dist/local-model-policy.js +84 -0
- package/dist/local-model-runtime.d.ts +6 -0
- package/dist/local-model-runtime.js +33 -21
- package/dist/model-bridge.d.ts +13 -1
- package/dist/model-bridge.js +410 -23
- package/dist/orchestrator-supervisor.d.ts +56 -0
- package/dist/orchestrator-supervisor.js +179 -1
- package/dist/plan-proposal.d.ts +115 -0
- package/dist/plan-proposal.js +1073 -0
- package/dist/run-ledger.js +3 -3
- package/dist/runtime-command.d.ts +8 -0
- package/dist/runtime-command.js +38 -6
- package/dist/runtime-executor.d.ts +20 -1
- package/dist/runtime-executor.js +737 -172
- package/dist/runtime-profile.d.ts +32 -0
- package/dist/runtime-profile.js +89 -13
- package/dist/runtime-tool-specs.d.ts +39 -0
- package/dist/runtime-tool-specs.js +144 -28
- package/dist/safe-edit.d.ts +7 -0
- package/dist/safe-edit.js +163 -37
- package/dist/schemas.js +48 -1
- package/dist/server.js +51 -0
- package/dist/shared.d.ts +3 -2
- package/dist/shared.js +2 -0
- package/dist/status-events.js +9 -6
- package/dist/store/ace-packed-store.d.ts +3 -2
- package/dist/store/ace-packed-store.js +188 -110
- package/dist/store/bootstrap-store.d.ts +2 -1
- package/dist/store/bootstrap-store.js +102 -83
- package/dist/store/cache-workspace.js +11 -5
- package/dist/store/materializers/context-snapshot-materializer.js +6 -2
- package/dist/store/materializers/hook-context-materializer.d.ts +6 -9
- package/dist/store/materializers/hook-context-materializer.js +11 -21
- package/dist/store/materializers/host-file-materializer.js +6 -0
- package/dist/store/materializers/projection-manager.d.ts +0 -1
- package/dist/store/materializers/projection-manager.js +5 -13
- package/dist/store/materializers/scheduler-projection-materializer.js +1 -1
- package/dist/store/materializers/vericify-projector.d.ts +7 -7
- package/dist/store/materializers/vericify-projector.js +11 -11
- package/dist/store/repositories/local-model-runtime-repository.d.ts +120 -3
- package/dist/store/repositories/local-model-runtime-repository.js +242 -6
- package/dist/store/repositories/vericify-repository.d.ts +1 -1
- package/dist/store/skills-install.d.ts +4 -0
- package/dist/store/skills-install.js +21 -12
- package/dist/store/state-reader.d.ts +2 -0
- package/dist/store/state-reader.js +20 -0
- package/dist/store/store-artifacts.d.ts +7 -0
- package/dist/store/store-artifacts.js +27 -1
- package/dist/store/store-authority-audit.d.ts +18 -1
- package/dist/store/store-authority-audit.js +115 -5
- package/dist/store/store-snapshot.d.ts +3 -0
- package/dist/store/store-snapshot.js +22 -2
- package/dist/store/workspace-store-paths.d.ts +39 -0
- package/dist/store/workspace-store-paths.js +94 -0
- package/dist/store/write-coordinator.d.ts +65 -0
- package/dist/store/write-coordinator.js +386 -0
- package/dist/todo-state.js +5 -5
- package/dist/tools-agent.d.ts +20 -0
- package/dist/tools-agent.js +789 -25
- package/dist/tools-discovery.js +136 -1
- package/dist/tools-files.d.ts +7 -0
- package/dist/tools-files.js +1002 -11
- package/dist/tools-framework.js +105 -66
- package/dist/tools-handoff.js +2 -2
- package/dist/tools-lifecycle.js +4 -4
- package/dist/tools-memory.js +6 -6
- package/dist/tools-todo.js +2 -2
- package/dist/tracker-adapters.d.ts +1 -1
- package/dist/tracker-adapters.js +13 -18
- package/dist/tracker-sync.js +5 -3
- package/dist/tui/agent-runner.js +3 -1
- package/dist/tui/chat.js +103 -7
- package/dist/tui/dashboard.d.ts +1 -0
- package/dist/tui/dashboard.js +43 -0
- package/dist/tui/index.js +10 -1
- package/dist/tui/layout.d.ts +20 -0
- package/dist/tui/layout.js +31 -1
- package/dist/tui/local-model-contract.d.ts +6 -2
- package/dist/tui/local-model-contract.js +16 -3
- package/dist/tui/ollama.d.ts +8 -1
- package/dist/tui/ollama.js +53 -12
- package/dist/tui/openai-compatible.d.ts +13 -0
- package/dist/tui/openai-compatible.js +305 -5
- package/dist/tui/provider-discovery.d.ts +1 -0
- package/dist/tui/provider-discovery.js +35 -11
- package/dist/vericify-bridge.d.ts +6 -1
- package/dist/vericify-bridge.js +27 -3
- package/dist/workspace-manager.d.ts +30 -3
- package/dist/workspace-manager.js +257 -27
- package/package.json +1 -2
- package/dist/internal-tool-runtime.d.ts +0 -21
- package/dist/internal-tool-runtime.js +0 -136
- package/dist/store/workspace-snapshot.d.ts +0 -26
- package/dist/store/workspace-snapshot.js +0 -107
package/dist/job-scheduler.js
CHANGED
|
@@ -9,7 +9,7 @@ import { openStore } from "./store/ace-packed-store.js";
|
|
|
9
9
|
import { ProjectionManager } from "./store/materializers/projection-manager.js";
|
|
10
10
|
import { SchedulerRepository } from "./store/repositories/scheduler-repository.js";
|
|
11
11
|
import { getWorkspaceStorePath, readStoreJsonSync, storeExistsSync, } from "./store/store-snapshot.js";
|
|
12
|
-
import {
|
|
12
|
+
import { withStoreWriteCoordinator } from "./store/write-coordinator.js";
|
|
13
13
|
// ── Buffered transition-event infrastructure ────────────────────────
|
|
14
14
|
// Events are collected during the scheduler lock and flushed after
|
|
15
15
|
// the lock is released. Emission is failure-tolerant: a broken
|
|
@@ -114,6 +114,30 @@ function defaultJobLockFile() {
|
|
|
114
114
|
locks: [],
|
|
115
115
|
};
|
|
116
116
|
}
|
|
117
|
+
function coerceJobQueueFile(value) {
|
|
118
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
119
|
+
return undefined;
|
|
120
|
+
const candidate = value;
|
|
121
|
+
if (candidate.version !== 1)
|
|
122
|
+
return undefined;
|
|
123
|
+
return {
|
|
124
|
+
version: 1,
|
|
125
|
+
updated_at: typeof candidate.updated_at === "string" ? candidate.updated_at : nowIso(),
|
|
126
|
+
jobs: Array.isArray(candidate.jobs) ? candidate.jobs : [],
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
function coerceJobLockTableFile(value) {
|
|
130
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
131
|
+
return undefined;
|
|
132
|
+
const candidate = value;
|
|
133
|
+
if (candidate.version !== 1)
|
|
134
|
+
return undefined;
|
|
135
|
+
return {
|
|
136
|
+
version: 1,
|
|
137
|
+
updated_at: typeof candidate.updated_at === "string" ? candidate.updated_at : nowIso(),
|
|
138
|
+
locks: Array.isArray(candidate.locks) ? candidate.locks : [],
|
|
139
|
+
};
|
|
140
|
+
}
|
|
117
141
|
function defaultLease(owner = "scheduler") {
|
|
118
142
|
const now = new Date();
|
|
119
143
|
const expires = new Date(now.getTime() + 30_000);
|
|
@@ -278,8 +302,9 @@ export function readJobQueue() {
|
|
|
278
302
|
const root = resolveWorkspaceRoot();
|
|
279
303
|
if (storeExistsSync(root)) {
|
|
280
304
|
const stored = readStoreJsonSync(root, "state/scheduler/queue");
|
|
281
|
-
|
|
282
|
-
|
|
305
|
+
const normalized = coerceJobQueueFile(stored);
|
|
306
|
+
if (normalized)
|
|
307
|
+
return normalized;
|
|
283
308
|
}
|
|
284
309
|
const raw = safeRead(JOB_QUEUE_REL);
|
|
285
310
|
if (isReadError(raw))
|
|
@@ -290,8 +315,9 @@ export function readJobLockTable() {
|
|
|
290
315
|
const root = resolveWorkspaceRoot();
|
|
291
316
|
if (storeExistsSync(root)) {
|
|
292
317
|
const stored = readStoreJsonSync(root, "state/scheduler/locks");
|
|
293
|
-
|
|
294
|
-
|
|
318
|
+
const normalized = coerceJobLockTableFile(stored);
|
|
319
|
+
if (normalized)
|
|
320
|
+
return normalized;
|
|
295
321
|
}
|
|
296
322
|
const raw = safeRead(JOB_LOCK_TABLE_REL);
|
|
297
323
|
if (isReadError(raw))
|
|
@@ -319,7 +345,7 @@ async function persistSchedulerState(input) {
|
|
|
319
345
|
return;
|
|
320
346
|
}
|
|
321
347
|
const storePath = getWorkspaceStorePath(root);
|
|
322
|
-
await
|
|
348
|
+
await withStoreWriteCoordinator(storePath, async () => {
|
|
323
349
|
const store = await openStore(storePath);
|
|
324
350
|
try {
|
|
325
351
|
const repo = new SchedulerRepository(store);
|
|
@@ -331,7 +357,7 @@ async function persistSchedulerState(input) {
|
|
|
331
357
|
finally {
|
|
332
358
|
await store.close();
|
|
333
359
|
}
|
|
334
|
-
});
|
|
360
|
+
}, { operation_label: "persistSchedulerState" });
|
|
335
361
|
}
|
|
336
362
|
function compareJobs(a, b) {
|
|
337
363
|
const priorityCmp = PRIORITY_WEIGHT[a.priority] - PRIORITY_WEIGHT[b.priority];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface JsonTextSanitizationResult {
|
|
2
|
+
text: string;
|
|
3
|
+
removed_control_bytes: number;
|
|
4
|
+
had_bom: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function sanitizeJsonLikeText(raw: string): JsonTextSanitizationResult;
|
|
7
|
+
export declare function parseJsonLikeText(raw: string): {
|
|
8
|
+
ok: true;
|
|
9
|
+
value: unknown;
|
|
10
|
+
sanitized: JsonTextSanitizationResult;
|
|
11
|
+
} | {
|
|
12
|
+
ok: false;
|
|
13
|
+
error: string;
|
|
14
|
+
sanitized: JsonTextSanitizationResult;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=json-sanitizer.d.ts.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export function sanitizeJsonLikeText(raw) {
|
|
2
|
+
const hadBom = raw.startsWith("\uFEFF");
|
|
3
|
+
let removed = 0;
|
|
4
|
+
const text = raw
|
|
5
|
+
.replace(/^\uFEFF/, "")
|
|
6
|
+
.replace(/\r\n?/g, "\n")
|
|
7
|
+
.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]/g, () => {
|
|
8
|
+
removed += 1;
|
|
9
|
+
return "";
|
|
10
|
+
});
|
|
11
|
+
return { text, removed_control_bytes: removed, had_bom: hadBom };
|
|
12
|
+
}
|
|
13
|
+
export function parseJsonLikeText(raw) {
|
|
14
|
+
const sanitized = sanitizeJsonLikeText(raw);
|
|
15
|
+
try {
|
|
16
|
+
return { ok: true, value: JSON.parse(sanitized.text), sanitized };
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
return {
|
|
20
|
+
ok: false,
|
|
21
|
+
error: error instanceof Error ? error.message : String(error),
|
|
22
|
+
sanitized,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=json-sanitizer.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { AceContextTier } from "./ace-context.js";
|
|
2
|
+
import { type RuntimeModelClass } from "./runtime-profile.js";
|
|
3
|
+
export interface LocalModelPolicyInput {
|
|
4
|
+
provider: string;
|
|
5
|
+
model: string;
|
|
6
|
+
role: string;
|
|
7
|
+
task?: string;
|
|
8
|
+
requested_tier?: "auto" | AceContextTier;
|
|
9
|
+
requested_model_class?: RuntimeModelClass;
|
|
10
|
+
}
|
|
11
|
+
export interface LocalModelExecutionPolicy {
|
|
12
|
+
model_class: RuntimeModelClass;
|
|
13
|
+
tier: AceContextTier;
|
|
14
|
+
mutation_lane: "structural_edit" | "raw_write_allowed";
|
|
15
|
+
structural_tools_required: boolean;
|
|
16
|
+
read_file_lines_max_lines: number | null;
|
|
17
|
+
}
|
|
18
|
+
export declare function resolveLocalModelClass(input: {
|
|
19
|
+
provider: string;
|
|
20
|
+
model: string;
|
|
21
|
+
requested_model_class?: RuntimeModelClass;
|
|
22
|
+
}): RuntimeModelClass;
|
|
23
|
+
export declare function tierForModelClass(role: string, modelClass: RuntimeModelClass, requestedTier?: "auto" | AceContextTier): AceContextTier;
|
|
24
|
+
export declare function defaultTurnsForPolicy(role: string, policy: LocalModelExecutionPolicy): number;
|
|
25
|
+
export declare function defaultToolScopeForPolicy(role: string, policy: LocalModelExecutionPolicy): string[] | undefined;
|
|
26
|
+
export declare function resolveLocalModelExecutionPolicy(input: LocalModelPolicyInput): LocalModelExecutionPolicy;
|
|
27
|
+
//# sourceMappingURL=local-model-policy.d.ts.map
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { DEFAULT_SURGICAL_READ_BUDGETS, } from "./runtime-profile.js";
|
|
2
|
+
const FRONTIER_MODEL_PATTERN = /\b(70b|72b|90b|405b|claude|gpt-|codex|gemini|o[1345])\b/i;
|
|
3
|
+
const SMALL_LOCAL_MODEL_PATTERN = /\b(1\.5b|2b|3b|4b|5b|6b|7b|8b|mini|small|phi|tiny|qwen2\.5-coder|llama-3\.2-3b)\b/i;
|
|
4
|
+
const LOCAL_PROVIDER_PATTERN = /\b(ollama|llama\.cpp|llamacpp|openai-compatible|local)\b/i;
|
|
5
|
+
const HOSTED_PROVIDER_PATTERN = /\b(codex|claude|gemini|copilot)\b/i;
|
|
6
|
+
function normalize(value) {
|
|
7
|
+
return (value ?? "").trim().toLowerCase();
|
|
8
|
+
}
|
|
9
|
+
function isMutationTask(task, role) {
|
|
10
|
+
if (role === "coders" || role === "builder")
|
|
11
|
+
return true;
|
|
12
|
+
return /\b(write|create|mutate|edit|patch|modify|persist|save|generate|implement)\b/i.test(task ?? "");
|
|
13
|
+
}
|
|
14
|
+
export function resolveLocalModelClass(input) {
|
|
15
|
+
if (input.requested_model_class)
|
|
16
|
+
return input.requested_model_class;
|
|
17
|
+
const provider = normalize(input.provider);
|
|
18
|
+
const model = normalize(input.model);
|
|
19
|
+
const joined = `${provider} ${model}`;
|
|
20
|
+
if (FRONTIER_MODEL_PATTERN.test(joined) || HOSTED_PROVIDER_PATTERN.test(provider) || provider === "openai") {
|
|
21
|
+
return "frontier";
|
|
22
|
+
}
|
|
23
|
+
if (SMALL_LOCAL_MODEL_PATTERN.test(model)) {
|
|
24
|
+
return "small_local";
|
|
25
|
+
}
|
|
26
|
+
if (LOCAL_PROVIDER_PATTERN.test(provider)) {
|
|
27
|
+
return "mid";
|
|
28
|
+
}
|
|
29
|
+
return "mid";
|
|
30
|
+
}
|
|
31
|
+
export function tierForModelClass(role, modelClass, requestedTier) {
|
|
32
|
+
if (requestedTier && requestedTier !== "auto")
|
|
33
|
+
return requestedTier;
|
|
34
|
+
if (role === "orchestrator")
|
|
35
|
+
return "compressed";
|
|
36
|
+
if (modelClass === "frontier")
|
|
37
|
+
return "full";
|
|
38
|
+
if (modelClass === "small_local")
|
|
39
|
+
return "brief";
|
|
40
|
+
return "compressed";
|
|
41
|
+
}
|
|
42
|
+
export function defaultTurnsForPolicy(role, policy) {
|
|
43
|
+
if (role === "orchestrator")
|
|
44
|
+
return 6;
|
|
45
|
+
return policy.model_class === "small_local" ? 4 : 4;
|
|
46
|
+
}
|
|
47
|
+
export function defaultToolScopeForPolicy(role, policy) {
|
|
48
|
+
if (!policy.structural_tools_required || !(role === "coders" || role === "builder")) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
return [
|
|
52
|
+
"outline_file",
|
|
53
|
+
"astgrep_query",
|
|
54
|
+
"astgrep_locate",
|
|
55
|
+
"read_file_lines",
|
|
56
|
+
"compile_structural_edit",
|
|
57
|
+
"preview_structural_edit",
|
|
58
|
+
"astgrep_rewrite",
|
|
59
|
+
"safe_edit_file",
|
|
60
|
+
"write_workspace_file",
|
|
61
|
+
"run_tests",
|
|
62
|
+
"git_diff",
|
|
63
|
+
"git_status",
|
|
64
|
+
"execute_gates",
|
|
65
|
+
];
|
|
66
|
+
}
|
|
67
|
+
export function resolveLocalModelExecutionPolicy(input) {
|
|
68
|
+
const role = normalize(input.role);
|
|
69
|
+
const modelClass = resolveLocalModelClass({
|
|
70
|
+
provider: input.provider,
|
|
71
|
+
model: input.model,
|
|
72
|
+
requested_model_class: input.requested_model_class,
|
|
73
|
+
});
|
|
74
|
+
const mutationIntent = isMutationTask(input.task, role);
|
|
75
|
+
const structuralToolsRequired = modelClass === "small_local" && mutationIntent;
|
|
76
|
+
return {
|
|
77
|
+
model_class: modelClass,
|
|
78
|
+
tier: tierForModelClass(role, modelClass, input.requested_tier),
|
|
79
|
+
mutation_lane: structuralToolsRequired ? "structural_edit" : "raw_write_allowed",
|
|
80
|
+
structural_tools_required: structuralToolsRequired,
|
|
81
|
+
read_file_lines_max_lines: DEFAULT_SURGICAL_READ_BUDGETS[modelClass],
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=local-model-policy.js.map
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { type BridgeResult, type ModelBridgeClients } from "./model-bridge.js";
|
|
2
2
|
import type { AceContextTier } from "./ace-context.js";
|
|
3
|
+
import { type LocalModelExecutionPolicy } from "./local-model-policy.js";
|
|
4
|
+
import type { RuntimeModelClass } from "./runtime-profile.js";
|
|
3
5
|
export interface LocalModelRuntimeConfig {
|
|
4
6
|
workspaceRoot: string;
|
|
5
7
|
provider: string;
|
|
@@ -19,6 +21,7 @@ export interface RunLocalModelTaskOptions {
|
|
|
19
21
|
ollamaUrl?: string;
|
|
20
22
|
maxTurns?: number;
|
|
21
23
|
tier?: AceContextTier | "auto";
|
|
24
|
+
modelClass?: RuntimeModelClass;
|
|
22
25
|
toolScope?: string[];
|
|
23
26
|
clients?: ModelBridgeClients;
|
|
24
27
|
}
|
|
@@ -26,8 +29,10 @@ export interface RunLocalModelTaskResult {
|
|
|
26
29
|
runtime: LocalModelRuntimeConfig;
|
|
27
30
|
role: string;
|
|
28
31
|
routingSummary?: string;
|
|
32
|
+
policy: LocalModelExecutionPolicy;
|
|
29
33
|
result: BridgeResult;
|
|
30
34
|
}
|
|
35
|
+
export declare function resolveTier(requested: RunLocalModelTaskOptions["tier"], provider: string, model: string, role: string): AceContextTier;
|
|
31
36
|
export declare function createDefaultModelBridgeClients(runtime: Pick<LocalModelRuntimeConfig, "providerBaseUrls">): ModelBridgeClients;
|
|
32
37
|
export declare function resolveLocalModelRuntime(input: {
|
|
33
38
|
workspaceRoot?: string;
|
|
@@ -37,4 +42,5 @@ export declare function resolveLocalModelRuntime(input: {
|
|
|
37
42
|
ollamaUrl?: string;
|
|
38
43
|
}): LocalModelRuntimeConfig;
|
|
39
44
|
export declare function runLocalModelTask(options: RunLocalModelTaskOptions): Promise<RunLocalModelTaskResult>;
|
|
45
|
+
export { resolveLocalModelExecutionPolicy, resolveLocalModelClass } from "./local-model-policy.js";
|
|
40
46
|
//# sourceMappingURL=local-model-runtime.d.ts.map
|
|
@@ -6,6 +6,7 @@ import { ModelBridge } from "./model-bridge.js";
|
|
|
6
6
|
import { OllamaClient } from "./tui/ollama.js";
|
|
7
7
|
import { OpenAICompatibleClient, diagnoseChatRuntimeConfig, } from "./tui/openai-compatible.js";
|
|
8
8
|
import { discoverProviderContext } from "./tui/provider-discovery.js";
|
|
9
|
+
import { defaultToolScopeForPolicy, defaultTurnsForPolicy, resolveLocalModelExecutionPolicy, } from "./local-model-policy.js";
|
|
9
10
|
function extractTextContent(result) {
|
|
10
11
|
if (!result || typeof result !== "object")
|
|
11
12
|
return "";
|
|
@@ -18,6 +19,14 @@ function extractTextContent(result) {
|
|
|
18
19
|
.filter(Boolean)
|
|
19
20
|
.join("\n");
|
|
20
21
|
}
|
|
22
|
+
function extractRoutedRole(result) {
|
|
23
|
+
const structured = result?.structuredContent;
|
|
24
|
+
if (!structured || typeof structured !== "object")
|
|
25
|
+
return undefined;
|
|
26
|
+
const suggestedRole = structured
|
|
27
|
+
.suggested_execution_role;
|
|
28
|
+
return typeof suggestedRole === "string" ? normalizeRoleCandidate(suggestedRole) : undefined;
|
|
29
|
+
}
|
|
21
30
|
function normalizeRoleCandidate(input) {
|
|
22
31
|
if (!input)
|
|
23
32
|
return undefined;
|
|
@@ -37,24 +46,18 @@ async function resolveRole(task, sessionId, requestedRole) {
|
|
|
37
46
|
}
|
|
38
47
|
const routing = await executeAceInternalTool("route_task", { description: task, domain: "unknown" }, sessionId);
|
|
39
48
|
const routingSummary = extractTextContent(routing);
|
|
40
|
-
return {
|
|
49
|
+
return {
|
|
50
|
+
role: extractRoutedRole(routing) ?? fallbackRoleForTask(),
|
|
51
|
+
routingSummary,
|
|
52
|
+
};
|
|
41
53
|
}
|
|
42
|
-
function resolveTier(requested, provider, model, role) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if (normalizedProvider !== "ollama")
|
|
50
|
-
return "full";
|
|
51
|
-
if (/(70b|72b|90b|405b|claude|gpt-|codex|gemini|o[1345])/.test(normalizedModel)) {
|
|
52
|
-
return "full";
|
|
53
|
-
}
|
|
54
|
-
if (/(7b|8b|mini|small|phi|tiny)/.test(normalizedModel)) {
|
|
55
|
-
return "brief";
|
|
56
|
-
}
|
|
57
|
-
return "compressed";
|
|
54
|
+
export function resolveTier(requested, provider, model, role) {
|
|
55
|
+
return resolveLocalModelExecutionPolicy({
|
|
56
|
+
provider,
|
|
57
|
+
model,
|
|
58
|
+
role,
|
|
59
|
+
requested_tier: requested,
|
|
60
|
+
}).tier;
|
|
58
61
|
}
|
|
59
62
|
export function createDefaultModelBridgeClients(runtime) {
|
|
60
63
|
const providerConfigs = {};
|
|
@@ -108,22 +111,31 @@ export async function runLocalModelTask(options) {
|
|
|
108
111
|
});
|
|
109
112
|
const bridge = new ModelBridge(options.clients ?? createDefaultModelBridgeClients(runtime));
|
|
110
113
|
const { role, routingSummary } = await resolveRole(options.task, undefined, options.role);
|
|
111
|
-
const
|
|
114
|
+
const policy = resolveLocalModelExecutionPolicy({
|
|
115
|
+
provider: runtime.provider,
|
|
116
|
+
model: runtime.model,
|
|
117
|
+
role,
|
|
118
|
+
task: options.task,
|
|
119
|
+
requested_tier: options.tier,
|
|
120
|
+
requested_model_class: options.modelClass,
|
|
121
|
+
});
|
|
112
122
|
const result = await bridge.run({
|
|
113
123
|
task: options.task,
|
|
114
124
|
role,
|
|
115
125
|
workspace: runtime.workspaceRoot,
|
|
116
|
-
tier,
|
|
117
|
-
maxTurns: options.maxTurns ?? (role
|
|
126
|
+
tier: policy.tier,
|
|
127
|
+
maxTurns: options.maxTurns ?? defaultTurnsForPolicy(role, policy),
|
|
118
128
|
provider: runtime.provider,
|
|
119
129
|
model: runtime.model,
|
|
120
|
-
toolScope: options.toolScope,
|
|
130
|
+
toolScope: options.toolScope ?? defaultToolScopeForPolicy(role, policy),
|
|
121
131
|
});
|
|
122
132
|
return {
|
|
123
133
|
runtime,
|
|
124
134
|
role,
|
|
125
135
|
routingSummary,
|
|
136
|
+
policy,
|
|
126
137
|
result,
|
|
127
138
|
};
|
|
128
139
|
}
|
|
140
|
+
export { resolveLocalModelExecutionPolicy, resolveLocalModelClass } from "./local-model-policy.js";
|
|
129
141
|
//# sourceMappingURL=local-model-runtime.js.map
|
package/dist/model-bridge.d.ts
CHANGED
|
@@ -11,14 +11,21 @@ export interface BridgeToolResult {
|
|
|
11
11
|
summary: string;
|
|
12
12
|
isError: boolean;
|
|
13
13
|
}
|
|
14
|
+
export interface BridgeProgressEvent {
|
|
15
|
+
kind: "model_chunk" | "tool_start" | "tool_finish" | "process_post" | "output" | "thinking";
|
|
16
|
+
at: number;
|
|
17
|
+
detail?: Record<string, unknown>;
|
|
18
|
+
}
|
|
14
19
|
export interface BridgeResult {
|
|
15
20
|
bridge_id: string;
|
|
16
21
|
role: string;
|
|
17
|
-
status: "completed" | "needs_input" | "failed" | "max_turns";
|
|
22
|
+
status: "completed" | "blocked" | "needs_input" | "failed" | "max_turns";
|
|
18
23
|
summary: string;
|
|
19
24
|
turns: number;
|
|
20
25
|
tool_calls: BridgeToolResult[];
|
|
21
26
|
child_results: BridgeResult[];
|
|
27
|
+
evidence_refs?: string[];
|
|
28
|
+
reason_code?: string;
|
|
22
29
|
}
|
|
23
30
|
export interface ModelBridgeClients {
|
|
24
31
|
ollama: Pick<OllamaClient, "chat" | "abort">;
|
|
@@ -34,11 +41,16 @@ export interface ModelBridgeRunOptions {
|
|
|
34
41
|
provider: string;
|
|
35
42
|
model: string;
|
|
36
43
|
toolScope?: string[];
|
|
44
|
+
expectedArtifacts?: {
|
|
45
|
+
path: string;
|
|
46
|
+
required?: boolean;
|
|
47
|
+
}[];
|
|
37
48
|
parentBridge?: string;
|
|
38
49
|
onToolCall?: (tool: string, args: Record<string, unknown>) => void;
|
|
39
50
|
onToolResult?: (tool: string, result: BridgeToolResult) => void;
|
|
40
51
|
onOutput?: (text: string) => void;
|
|
41
52
|
onThinking?: (text: string) => void;
|
|
53
|
+
onProgress?: (event: BridgeProgressEvent) => void;
|
|
42
54
|
}
|
|
43
55
|
export declare class ModelBridge {
|
|
44
56
|
private clients;
|