@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.
Files changed (144) hide show
  1. package/CHANGELOG.md +19 -1
  2. package/README.md +21 -13
  3. package/assets/.agents/ACE/agent-qa/instructions.md +11 -0
  4. package/assets/agent-state/EVIDENCE_LOG.md +1 -1
  5. package/assets/agent-state/MODULES/roles/capability-framework.json +41 -0
  6. package/assets/agent-state/MODULES/roles/capability-git.json +33 -0
  7. package/assets/agent-state/MODULES/roles/capability-safety.json +37 -0
  8. package/assets/agent-state/MODULES/schemas/ACE_RUNTIME_PROFILE.schema.json +21 -0
  9. package/assets/agent-state/MODULES/schemas/RUNTIME_EXECUTOR_SESSION_REGISTRY.schema.json +43 -0
  10. package/assets/agent-state/MODULES/schemas/RUNTIME_TOOL_SPEC_REGISTRY.schema.json +43 -0
  11. package/assets/agent-state/MODULES/schemas/WORKSPACE_SESSION_REGISTRY.schema.json +11 -0
  12. package/assets/agent-state/STATUS.md +2 -2
  13. package/assets/agent-state/runtime-tool-specs.json +70 -2
  14. package/assets/instructions/ACE_Coder.instructions.md +13 -0
  15. package/assets/instructions/ACE_UI.instructions.md +11 -0
  16. package/assets/scripts/ace-hook-dispatch.mjs +70 -6
  17. package/assets/scripts/render-mcp-configs.sh +19 -5
  18. package/dist/ace-context.js +91 -11
  19. package/dist/ace-internal-tools.d.ts +3 -1
  20. package/dist/ace-internal-tools.js +10 -2
  21. package/dist/ace-server-instructions.js +3 -3
  22. package/dist/ace-state-resolver.js +5 -3
  23. package/dist/agent-runtime/role-adapters.d.ts +18 -1
  24. package/dist/agent-runtime/role-adapters.js +49 -5
  25. package/dist/astgrep-index.d.ts +57 -1
  26. package/dist/astgrep-index.js +140 -4
  27. package/dist/cli.js +232 -35
  28. package/dist/discovery-runtime-wrappers.d.ts +108 -0
  29. package/dist/discovery-runtime-wrappers.js +615 -0
  30. package/dist/handoff-registry.js +5 -5
  31. package/dist/helpers/artifacts.d.ts +19 -0
  32. package/dist/helpers/artifacts.js +152 -0
  33. package/dist/helpers/bootstrap.d.ts +24 -0
  34. package/dist/helpers/bootstrap.js +894 -0
  35. package/dist/helpers/constants.d.ts +53 -0
  36. package/dist/helpers/constants.js +295 -0
  37. package/dist/helpers/drift.d.ts +13 -0
  38. package/dist/helpers/drift.js +45 -0
  39. package/dist/helpers/path-utils.d.ts +24 -0
  40. package/dist/helpers/path-utils.js +123 -0
  41. package/dist/helpers/store-resolution.d.ts +19 -0
  42. package/dist/helpers/store-resolution.js +305 -0
  43. package/dist/helpers/workspace-root.d.ts +3 -0
  44. package/dist/helpers/workspace-root.js +80 -0
  45. package/dist/helpers.d.ts +8 -125
  46. package/dist/helpers.js +8 -1768
  47. package/dist/job-scheduler.js +33 -7
  48. package/dist/json-sanitizer.d.ts +16 -0
  49. package/dist/json-sanitizer.js +26 -0
  50. package/dist/local-model-policy.d.ts +27 -0
  51. package/dist/local-model-policy.js +84 -0
  52. package/dist/local-model-runtime.d.ts +6 -0
  53. package/dist/local-model-runtime.js +33 -21
  54. package/dist/model-bridge.d.ts +13 -1
  55. package/dist/model-bridge.js +410 -23
  56. package/dist/orchestrator-supervisor.d.ts +56 -0
  57. package/dist/orchestrator-supervisor.js +179 -1
  58. package/dist/plan-proposal.d.ts +115 -0
  59. package/dist/plan-proposal.js +1073 -0
  60. package/dist/run-ledger.js +3 -3
  61. package/dist/runtime-command.d.ts +8 -0
  62. package/dist/runtime-command.js +38 -6
  63. package/dist/runtime-executor.d.ts +20 -1
  64. package/dist/runtime-executor.js +737 -172
  65. package/dist/runtime-profile.d.ts +32 -0
  66. package/dist/runtime-profile.js +89 -13
  67. package/dist/runtime-tool-specs.d.ts +39 -0
  68. package/dist/runtime-tool-specs.js +144 -28
  69. package/dist/safe-edit.d.ts +7 -0
  70. package/dist/safe-edit.js +163 -37
  71. package/dist/schemas.js +48 -1
  72. package/dist/server.js +51 -0
  73. package/dist/shared.d.ts +3 -2
  74. package/dist/shared.js +2 -0
  75. package/dist/status-events.js +9 -6
  76. package/dist/store/ace-packed-store.d.ts +3 -2
  77. package/dist/store/ace-packed-store.js +188 -110
  78. package/dist/store/bootstrap-store.d.ts +2 -1
  79. package/dist/store/bootstrap-store.js +102 -83
  80. package/dist/store/cache-workspace.js +11 -5
  81. package/dist/store/materializers/context-snapshot-materializer.js +6 -2
  82. package/dist/store/materializers/hook-context-materializer.d.ts +6 -9
  83. package/dist/store/materializers/hook-context-materializer.js +11 -21
  84. package/dist/store/materializers/host-file-materializer.js +6 -0
  85. package/dist/store/materializers/projection-manager.d.ts +0 -1
  86. package/dist/store/materializers/projection-manager.js +5 -13
  87. package/dist/store/materializers/scheduler-projection-materializer.js +1 -1
  88. package/dist/store/materializers/vericify-projector.d.ts +7 -7
  89. package/dist/store/materializers/vericify-projector.js +11 -11
  90. package/dist/store/repositories/local-model-runtime-repository.d.ts +120 -3
  91. package/dist/store/repositories/local-model-runtime-repository.js +242 -6
  92. package/dist/store/repositories/vericify-repository.d.ts +1 -1
  93. package/dist/store/skills-install.d.ts +4 -0
  94. package/dist/store/skills-install.js +21 -12
  95. package/dist/store/state-reader.d.ts +2 -0
  96. package/dist/store/state-reader.js +20 -0
  97. package/dist/store/store-artifacts.d.ts +7 -0
  98. package/dist/store/store-artifacts.js +27 -1
  99. package/dist/store/store-authority-audit.d.ts +18 -1
  100. package/dist/store/store-authority-audit.js +115 -5
  101. package/dist/store/store-snapshot.d.ts +3 -0
  102. package/dist/store/store-snapshot.js +22 -2
  103. package/dist/store/workspace-store-paths.d.ts +39 -0
  104. package/dist/store/workspace-store-paths.js +94 -0
  105. package/dist/store/write-coordinator.d.ts +65 -0
  106. package/dist/store/write-coordinator.js +386 -0
  107. package/dist/todo-state.js +5 -5
  108. package/dist/tools-agent.d.ts +20 -0
  109. package/dist/tools-agent.js +789 -25
  110. package/dist/tools-discovery.js +136 -1
  111. package/dist/tools-files.d.ts +7 -0
  112. package/dist/tools-files.js +1002 -11
  113. package/dist/tools-framework.js +105 -66
  114. package/dist/tools-handoff.js +2 -2
  115. package/dist/tools-lifecycle.js +4 -4
  116. package/dist/tools-memory.js +6 -6
  117. package/dist/tools-todo.js +2 -2
  118. package/dist/tracker-adapters.d.ts +1 -1
  119. package/dist/tracker-adapters.js +13 -18
  120. package/dist/tracker-sync.js +5 -3
  121. package/dist/tui/agent-runner.js +3 -1
  122. package/dist/tui/chat.js +103 -7
  123. package/dist/tui/dashboard.d.ts +1 -0
  124. package/dist/tui/dashboard.js +43 -0
  125. package/dist/tui/index.js +10 -1
  126. package/dist/tui/layout.d.ts +20 -0
  127. package/dist/tui/layout.js +31 -1
  128. package/dist/tui/local-model-contract.d.ts +6 -2
  129. package/dist/tui/local-model-contract.js +16 -3
  130. package/dist/tui/ollama.d.ts +8 -1
  131. package/dist/tui/ollama.js +53 -12
  132. package/dist/tui/openai-compatible.d.ts +13 -0
  133. package/dist/tui/openai-compatible.js +305 -5
  134. package/dist/tui/provider-discovery.d.ts +1 -0
  135. package/dist/tui/provider-discovery.js +35 -11
  136. package/dist/vericify-bridge.d.ts +6 -1
  137. package/dist/vericify-bridge.js +27 -3
  138. package/dist/workspace-manager.d.ts +30 -3
  139. package/dist/workspace-manager.js +257 -27
  140. package/package.json +1 -2
  141. package/dist/internal-tool-runtime.d.ts +0 -21
  142. package/dist/internal-tool-runtime.js +0 -136
  143. package/dist/store/workspace-snapshot.d.ts +0 -26
  144. package/dist/store/workspace-snapshot.js +0 -107
@@ -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 { withStoreWriteQueue } from "./store/write-queue.js";
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
- if (stored)
282
- return stored;
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
- if (stored)
294
- return stored;
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 withStoreWriteQueue(storePath, async () => {
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 { role: fallbackRoleForTask(), routingSummary };
49
+ return {
50
+ role: extractRoutedRole(routing) ?? fallbackRoleForTask(),
51
+ routingSummary,
52
+ };
41
53
  }
42
- function resolveTier(requested, provider, model, role) {
43
- if (requested && requested !== "auto")
44
- return requested;
45
- const normalizedProvider = provider.trim().toLowerCase();
46
- const normalizedModel = model.trim().toLowerCase();
47
- if (role === "orchestrator")
48
- return "compressed";
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 tier = resolveTier(options.tier, runtime.provider, runtime.model, role);
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 === "orchestrator" ? 6 : 4),
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
@@ -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;