salmon-loop 0.3.2 → 0.5.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.
Files changed (227) hide show
  1. package/dist/cli/authorization/non-interactive.js +9 -13
  2. package/dist/cli/authorization/provider.js +2 -10
  3. package/dist/cli/chat.js +12 -6
  4. package/dist/cli/commands/allowlist.js +1 -1
  5. package/dist/cli/commands/chat.js +13 -13
  6. package/dist/cli/commands/config.js +2 -2
  7. package/dist/cli/commands/mode.js +2 -2
  8. package/dist/cli/commands/parallel.js +1 -1
  9. package/dist/cli/commands/run/handler.js +9 -4
  10. package/dist/cli/commands/run/loop-params.js +2 -0
  11. package/dist/cli/commands/run/parse-options.js +14 -26
  12. package/dist/cli/commands/run/runtime-llm.js +15 -12
  13. package/dist/cli/commands/run/runtime-options.js +3 -1
  14. package/dist/cli/config.js +0 -8
  15. package/dist/cli/headless/openai-responses-canonical-applier.js +1 -7
  16. package/dist/cli/locales/en.js +2 -2
  17. package/dist/cli/reporters/standard.js +12 -3
  18. package/dist/cli/reporters/stream-json.js +2 -1
  19. package/dist/cli/slash/runtime.js +2 -2
  20. package/dist/cli/ui/hooks/useLoopEvents.js +1 -1
  21. package/dist/cli/ui/hooks/useLoopState.js +1 -1
  22. package/dist/core/adapters/fs/file-adapter.js +3 -1
  23. package/dist/core/adapters/git/git-adapter.js +6 -3
  24. package/dist/core/adapters/git/git-runner.js +5 -2
  25. package/dist/core/adapters/git/lock-manager.js +7 -4
  26. package/dist/core/ast/parser.js +18 -9
  27. package/dist/core/checkpoint-domain/manifest-store.js +21 -13
  28. package/dist/core/checkpoint-domain/service.js +3 -1
  29. package/dist/core/config/limits.js +1 -1
  30. package/dist/core/config/model-pricing.js +61 -0
  31. package/dist/core/config/schema.js +738 -0
  32. package/dist/core/config/validate.js +11 -922
  33. package/dist/core/context/ast/skeleton-extractor.js +225 -0
  34. package/dist/core/context/ast/source-outline.js +24 -1
  35. package/dist/core/context/budget/dynamic-adjuster.js +20 -5
  36. package/dist/core/context/builder.js +7 -3
  37. package/dist/core/context/cache/store-factory.js +3 -1
  38. package/dist/core/context/dependencies.js +2 -1
  39. package/dist/core/context/effectiveness/persistence.js +50 -0
  40. package/dist/core/context/effectiveness/tracker.js +24 -0
  41. package/dist/core/context/gatherers/architecture-gatherer.js +2 -1
  42. package/dist/core/context/gatherers/artifact-gatherer.js +7 -4
  43. package/dist/core/context/gatherers/ast-gatherer.js +34 -40
  44. package/dist/core/context/gatherers/ghost-dependency-gatherer.js +0 -1
  45. package/dist/core/context/gatherers/git-history-gatherer.js +3 -1
  46. package/dist/core/context/gatherers/knowledge-gatherer.js +21 -2
  47. package/dist/core/context/gatherers/metadata-gatherer.js +12 -7
  48. package/dist/core/context/gatherers/ripgrep-gatherer.js +6 -3
  49. package/dist/core/context/service.js +12 -2
  50. package/dist/core/context/steps/context-gather.js +14 -3
  51. package/dist/core/context/steps/context-targets.js +1 -0
  52. package/dist/core/context/targeting/target-resolver.js +29 -11
  53. package/dist/core/context/token/cache.js +5 -2
  54. package/dist/core/context/token/encoding-registry.js +7 -6
  55. package/dist/core/context/truncation/strategies/json.js +5 -2
  56. package/dist/core/context/truncation/type-detector.js +3 -1
  57. package/dist/core/extensions/index.js +48 -3
  58. package/dist/core/extensions/load.js +3 -2
  59. package/dist/core/extensions/merge.js +5 -1
  60. package/dist/core/extensions/paths.js +8 -2
  61. package/dist/core/extensions/schemas.js +21 -0
  62. package/dist/core/facades/cli-authorization-provider.js +1 -0
  63. package/dist/core/facades/cli-command-chat.js +2 -0
  64. package/dist/core/facades/cli-run-handler.js +1 -0
  65. package/dist/core/facades/cli-utils-serialize.js +2 -0
  66. package/dist/core/feedback/parsers.js +290 -1
  67. package/dist/core/grizzco/dsl/llm-strategy.js +4 -3
  68. package/dist/core/grizzco/engine/observability/loop-telemetry.js +5 -2
  69. package/dist/core/grizzco/engine/outcome/loop-result-mapper.js +30 -13
  70. package/dist/core/grizzco/engine/pipeline/pipeline.js +149 -240
  71. package/dist/core/grizzco/engine/transaction/attempt-failure.js +49 -24
  72. package/dist/core/grizzco/engine/transaction/authorization-summary.js +2 -1
  73. package/dist/core/grizzco/engine/transaction/transaction-runner.js +40 -34
  74. package/dist/core/grizzco/execution/RejectionManager.js +7 -5
  75. package/dist/core/grizzco/runtime/apply-back-runtime.js +5 -2
  76. package/dist/core/grizzco/services/implementations/default/GitConfigService.js +2 -1
  77. package/dist/core/grizzco/services/registry.js +18 -0
  78. package/dist/core/grizzco/steps/audit.js +20 -10
  79. package/dist/core/grizzco/steps/autopilot.js +21 -32
  80. package/dist/core/grizzco/steps/display-report.js +4 -11
  81. package/dist/core/grizzco/steps/explore.js +14 -4
  82. package/dist/core/grizzco/steps/generateReview.js +3 -1
  83. package/dist/core/grizzco/steps/patch/prompt-input.js +4 -1
  84. package/dist/core/grizzco/steps/patch.js +1 -0
  85. package/dist/core/grizzco/steps/plan.js +58 -49
  86. package/dist/core/grizzco/steps/research.js +3 -1
  87. package/dist/core/grizzco/steps/tool-runtime.js +3 -0
  88. package/dist/core/grizzco/steps/verify.js +7 -1
  89. package/dist/core/grizzco/validation/AstValidationService.js +3 -1
  90. package/dist/core/grizzco/workers/strata-sync-worker.js +2 -1
  91. package/dist/core/history/input-history.js +3 -1
  92. package/dist/core/intent/chat-intent.js +3 -1
  93. package/dist/core/llm/ai-sdk/message-mapper.js +37 -26
  94. package/dist/core/llm/ai-sdk/request-params.js +2 -6
  95. package/dist/core/llm/ai-sdk/result-mapper.js +14 -8
  96. package/dist/core/llm/ai-sdk/retry-classifier.js +17 -7
  97. package/dist/core/llm/ai-sdk/retry-executor.js +1 -1
  98. package/dist/core/llm/contracts/repair.js +16 -8
  99. package/dist/core/llm/errors.js +18 -14
  100. package/dist/core/llm/output-policy.js +8 -0
  101. package/dist/core/llm/redact.js +1 -3
  102. package/dist/core/llm/retry-utils.js +8 -2
  103. package/dist/core/llm/stream-utils.js +5 -3
  104. package/dist/core/llm/sub-agent-factory.js +51 -0
  105. package/dist/core/llm/tool-calling-stub.js +48 -0
  106. package/dist/core/llm/utils.js +17 -6
  107. package/dist/core/mcp/bridge/prompt-command-provider.js +4 -3
  108. package/dist/core/mcp/bridge/resource-context-provider.js +3 -1
  109. package/dist/core/mcp/bridge/tool-bridge.js +5 -14
  110. package/dist/core/mcp/catalog/discovery.js +3 -1
  111. package/dist/core/mcp/client/connection-manager.js +7 -4
  112. package/dist/core/mcp/client/transport-factory.js +7 -3
  113. package/dist/core/mcp/host/sampling-provider.js +1 -1
  114. package/dist/core/mcp/schema/json-schema-to-zod.js +2 -1
  115. package/dist/core/memory/relevant-retrieval.js +6 -4
  116. package/dist/core/observability/audit-file.js +2 -1
  117. package/dist/core/observability/audit-trail.js +3 -1
  118. package/dist/core/observability/authorization-decisions.js +13 -12
  119. package/dist/core/observability/error-mapping.js +2 -1
  120. package/dist/core/observability/logger.js +2 -1
  121. package/dist/core/observability/monitor.js +24 -0
  122. package/dist/core/observability/run-outcome-reporter.js +1 -0
  123. package/dist/core/observability/token-usage.js +5 -4
  124. package/dist/core/permission-gate/default-gate.js +5 -8
  125. package/dist/core/plan/storage.js +7 -4
  126. package/dist/core/plugin/loader.js +8 -5
  127. package/dist/core/prompts/registry.js +12 -30
  128. package/dist/core/prompts/runtime.js +3 -1
  129. package/dist/core/prompts/templates/system/autopilot_system.hbs +28 -4
  130. package/dist/core/protocols/a2a/sdk/executor.js +3 -1
  131. package/dist/core/protocols/a2a/sdk/server.js +5 -4
  132. package/dist/core/protocols/acp/acp-command-runner.js +7 -6
  133. package/dist/core/protocols/acp/acp-session-persistence.js +13 -10
  134. package/dist/core/protocols/acp/formal-agent.js +13 -6
  135. package/dist/core/protocols/acp/permission-provider.js +3 -2
  136. package/dist/core/protocols/acp/stdio-server.js +6 -6
  137. package/dist/core/reflection/engine.js +114 -14
  138. package/dist/core/runtime/agent-server-runtime.js +3 -2
  139. package/dist/core/runtime/batch-runner.js +81 -0
  140. package/dist/core/runtime/initialize.js +71 -6
  141. package/dist/core/runtime/loop-finalize.js +3 -0
  142. package/dist/core/runtime/loop-session-runner.js +5 -0
  143. package/dist/core/runtime/loop.js +4 -0
  144. package/dist/core/runtime/paths.js +9 -6
  145. package/dist/core/runtime/spawn-interactive.js +5 -4
  146. package/dist/core/security/redaction.js +3 -2
  147. package/dist/core/session/compaction/index.js +4 -3
  148. package/dist/core/session/compression.js +3 -1
  149. package/dist/core/session/manager.js +26 -38
  150. package/dist/core/session/pruning-strategy.js +2 -1
  151. package/dist/core/session/token-tracker.js +27 -9
  152. package/dist/core/skills/parser.js +3 -2
  153. package/dist/core/skills/permissions.js +2 -2
  154. package/dist/core/skills/runtime/MicroTaskRunner.js +1 -1
  155. package/dist/core/skills/runtime/SkillRunner.js +5 -2
  156. package/dist/core/slash/steps/slash-execute.js +7 -5
  157. package/dist/core/slash/strategy.js +1 -1
  158. package/dist/core/strata/checkpoint/manager.js +16 -10
  159. package/dist/core/strata/checkpoint/snapshot-create.js +5 -4
  160. package/dist/core/strata/checkpoint/snapshot-write-tree.js +7 -3
  161. package/dist/core/strata/engine/shadow-merge-engine.js +4 -2
  162. package/dist/core/strata/interaction/file-system-provider.js +2 -1
  163. package/dist/core/strata/layers/file-state-resolver.js +9 -7
  164. package/dist/core/strata/layers/immutable-git-layer.js +3 -1
  165. package/dist/core/strata/layers/shadow-driver/readonly-lock.js +8 -6
  166. package/dist/core/strata/layers/shadow-driver/shadow-driver.js +2 -1
  167. package/dist/core/strata/layers/worktree.js +9 -10
  168. package/dist/core/strata/runtime/environment.js +2 -1
  169. package/dist/core/strata/runtime/synchronizer.js +28 -26
  170. package/dist/core/streaming/canonical/parts-from-llm-stream-chunk.js +1 -11
  171. package/dist/core/structured-output/json-extract.js +3 -1
  172. package/dist/core/structured-output/json-schema-validator.js +1 -13
  173. package/dist/core/sub-agent/artifacts/store.js +2 -1
  174. package/dist/core/sub-agent/context-snapshot.js +12 -6
  175. package/dist/core/sub-agent/controller.js +70 -1
  176. package/dist/core/sub-agent/core/loop.js +25 -3
  177. package/dist/core/sub-agent/core/manager.js +343 -117
  178. package/dist/core/sub-agent/registry-defaults.js +12 -0
  179. package/dist/core/sub-agent/registry.js +8 -0
  180. package/dist/core/sub-agent/summary.js +96 -0
  181. package/dist/core/sub-agent/team.js +98 -0
  182. package/dist/core/sub-agent/tools/task-await.js +109 -0
  183. package/dist/core/sub-agent/tools/task-spawn.js +52 -7
  184. package/dist/core/sub-agent/tools/team.js +92 -0
  185. package/dist/core/sub-agent/types.js +11 -2
  186. package/dist/core/target-runtime/profile.js +3 -1
  187. package/dist/core/tools/audit.js +3 -2
  188. package/dist/core/tools/budget.js +7 -12
  189. package/dist/core/tools/builtin/ast.js +144 -0
  190. package/dist/core/tools/builtin/code-search/backends/powershell.js +3 -1
  191. package/dist/core/tools/builtin/code-search/backends/rg.js +3 -1
  192. package/dist/core/tools/builtin/code-search/executor.js +46 -43
  193. package/dist/core/tools/builtin/code-search/parse/plain-grep.js +3 -1
  194. package/dist/core/tools/builtin/code-search/parse/rg-json.js +3 -1
  195. package/dist/core/tools/builtin/fs.js +90 -7
  196. package/dist/core/tools/builtin/git.js +242 -0
  197. package/dist/core/tools/builtin/glob.js +79 -0
  198. package/dist/core/tools/builtin/index.js +53 -111
  199. package/dist/core/tools/builtin/interaction.js +13 -15
  200. package/dist/core/tools/builtin/knowledge.js +146 -4
  201. package/dist/core/tools/builtin/proposal.js +14 -3
  202. package/dist/core/tools/builtin/verify.js +35 -3
  203. package/dist/core/tools/capability/executor.js +5 -5
  204. package/dist/core/tools/headless-payload.js +1 -3
  205. package/dist/core/tools/mapper.js +8 -42
  206. package/dist/core/tools/parallel/persistence.js +17 -5
  207. package/dist/core/tools/parallel/scheduler.js +23 -21
  208. package/dist/core/tools/permissions/permission-rules.js +69 -115
  209. package/dist/core/tools/plugins/loader.js +4 -3
  210. package/dist/core/tools/router.js +112 -58
  211. package/dist/core/tools/session.js +64 -102
  212. package/dist/core/tools/streaming/ToolCallAccumulator.js +1 -3
  213. package/dist/core/tools/tool-visibility.js +2 -1
  214. package/dist/core/tools/types.js +10 -0
  215. package/dist/core/types/batch.js +2 -0
  216. package/dist/core/utils/error.js +79 -0
  217. package/dist/core/utils/sanitizer.js +5 -2
  218. package/dist/core/utils/serialize.js +66 -0
  219. package/dist/core/utils/zod.js +29 -0
  220. package/dist/core/verification/detect-runner.js +86 -0
  221. package/dist/core/verification/runner.js +76 -0
  222. package/dist/core/version.js +3 -1
  223. package/dist/core/workspace/capabilities.js +3 -2
  224. package/dist/integrations/langfuse/litellm-langfuse-outcome-reporter.js +9 -8
  225. package/dist/languages/python/index.js +154 -0
  226. package/dist/locales/en.js +8 -1
  227. package/package.json +2 -1
@@ -96,8 +96,9 @@ export class FileHandleManager {
96
96
  const fs = await import('fs/promises');
97
97
  await fs.unlink(lockFile);
98
98
  }
99
- catch {
100
- // Ignore
99
+ catch (error) {
100
+ // Ignore - best-effort force unlock
101
+ getLogger().debug(`[LockManager] force unlock failed: ${error instanceof Error ? error.message : String(error)}`);
101
102
  }
102
103
  }
103
104
  while (Date.now() - start < LIMITS.lockWaitTimeoutMs) {
@@ -142,9 +143,10 @@ export class FileHandleManager {
142
143
  continue; // Retry immediately after removing stale lock
143
144
  }
144
145
  }
145
- catch {
146
+ catch (error) {
146
147
  // If the lock file is unreadable, we cannot safely determine ownership.
147
148
  // Do not auto-remove in this path; rely on timeout-based recovery instead.
149
+ getLogger().debug(`[LockManager] lock file unreadable during stale check: ${error instanceof Error ? error.message : String(error)}`);
148
150
  }
149
151
  // Exponential backoff: delay increases with retry count, capped at 2000ms
150
152
  retryCount++;
@@ -159,8 +161,9 @@ export class FileHandleManager {
159
161
  await mkdir(repoPath, { recursive: true });
160
162
  continue; // Retry immediately
161
163
  }
162
- catch {
164
+ catch (error) {
163
165
  // If mkdir fails, just wait and retry
166
+ getLogger().debug(`[LockManager] mkdir fallback failed: ${error instanceof Error ? error.message : String(error)}`);
164
167
  }
165
168
  await this.abortableDelay(LIMITS.retry.io.initialDelayMs, hardAbort.signal);
166
169
  }
@@ -24,39 +24,48 @@ export class AstParser {
24
24
  static state = InitState.Idle;
25
25
  static initPromise = null;
26
26
  /**
27
- * Get the Parser class from web-tree-sitter, handling different API versions
27
+ * Get the Parser class from web-tree-sitter, handling different API versions.
28
+ * Uses `as unknown as` for CJS/ESM interop — the runtime module shape varies
29
+ * across bundler configurations.
28
30
  */
29
31
  static getParserClass() {
32
+ const mod = TreeSitter;
30
33
  try {
31
- return TreeSitter.Parser || TreeSitter.default?.Parser || TreeSitter;
34
+ return (mod.Parser ??
35
+ mod.default?.Parser ??
36
+ TreeSitter);
32
37
  }
33
38
  catch (_error) {
34
39
  getLogger().degrade(text.ast.degradedApi);
35
- return TreeSitter.default || TreeSitter;
40
+ return (mod.default ?? TreeSitter);
36
41
  }
37
42
  }
38
43
  /**
39
- * Get the Language class from web-tree-sitter, handling different API versions
44
+ * Get the Language class from web-tree-sitter, handling different API versions.
45
+ * Uses `as unknown as` for CJS/ESM interop.
40
46
  */
41
47
  static getLanguageClass() {
48
+ const mod = TreeSitter;
42
49
  try {
43
- return TreeSitter.Language || TreeSitter.default?.Language;
50
+ return (mod.Language ?? mod.default?.Language);
44
51
  }
45
52
  catch (_error) {
46
53
  getLogger().degrade(text.ast.degradedApi);
47
- return TreeSitter.default?.Language;
54
+ return mod.default?.Language;
48
55
  }
49
56
  }
50
57
  /**
51
- * Get the Query class from web-tree-sitter, handling different API versions
58
+ * Get the Query class from web-tree-sitter, handling different API versions.
59
+ * Uses `as unknown as` for CJS/ESM interop.
52
60
  */
53
61
  static getQueryClass() {
62
+ const mod = TreeSitter;
54
63
  try {
55
- return TreeSitter.Query || TreeSitter.default?.Query;
64
+ return (mod.Query ?? mod.default?.Query);
56
65
  }
57
66
  catch (_error) {
58
67
  getLogger().degrade(text.ast.degradedApi);
59
- return TreeSitter.default?.Query;
68
+ return mod.default?.Query;
60
69
  }
61
70
  }
62
71
  static languages = new Map();
@@ -2,6 +2,7 @@ import { createHash } from 'crypto';
2
2
  import { mkdir, open, readFile, rename, stat, unlink, writeFile } from '../adapters/fs/node-fs.js';
3
3
  import { defaultPathAdapter } from '../adapters/path/path-adapter.js';
4
4
  import { recordAuditEvent } from '../observability/audit-trail.js';
5
+ import { getLogger } from '../observability/logger.js';
5
6
  import { getUserCheckpointManifestDir } from '../runtime/paths.js';
6
7
  const CHECKPOINT_MANIFEST_FILENAME_V2 = 'manifest.v2.json';
7
8
  const CHECKPOINT_MANIFEST_FILENAME_V1 = 'manifest.v1.json';
@@ -131,7 +132,8 @@ async function withManifestLock(repoPath, operation, lockPolicy) {
131
132
  lockPathHash,
132
133
  }, { source: 'runtime', severity: 'low', scope: 'session', phase: 'PREFLIGHT' });
133
134
  }
134
- catch {
135
+ catch (error) {
136
+ getLogger().debug(`[ManifestStore] Stale lock reclaim failed: ${error instanceof Error ? error.message : String(error)}`);
135
137
  try {
136
138
  const lockStat = await stat(lockPath);
137
139
  const ageMs = Date.now() - lockStat.mtimeMs;
@@ -144,8 +146,9 @@ async function withManifestLock(repoPath, operation, lockPolicy) {
144
146
  }, { source: 'runtime', severity: 'medium', scope: 'session', phase: 'PREFLIGHT' });
145
147
  }
146
148
  }
147
- catch {
149
+ catch (error) {
148
150
  // Ignore lock probe failures; retry loop handles contention.
151
+ getLogger().debug(`[ManifestStore] Lock probe failed: ${error instanceof Error ? error.message : String(error)}`);
149
152
  }
150
153
  }
151
154
  };
@@ -156,7 +159,8 @@ async function withManifestLock(repoPath, operation, lockPolicy) {
156
159
  await handle.writeFile(JSON.stringify({ pid: process.pid, createdAtMs: Date.now() }), 'utf8');
157
160
  break;
158
161
  }
159
- catch {
162
+ catch (error) {
163
+ getLogger().debug(`[ManifestStore] Lock acquisition attempt failed: ${error instanceof Error ? error.message : String(error)}`);
160
164
  await tryClearStaleLock();
161
165
  await new Promise((resolve) => setTimeout(resolve, 30 * (attempt + 1)));
162
166
  }
@@ -185,14 +189,14 @@ async function withManifestLock(repoPath, operation, lockPolicy) {
185
189
  try {
186
190
  await handle.close();
187
191
  }
188
- catch {
189
- // ignore
192
+ catch (error) {
193
+ getLogger().debug(`[ManifestStore] Failed to close lock handle: ${error instanceof Error ? error.message : String(error)}`);
190
194
  }
191
195
  try {
192
196
  await unlink(lockPath);
193
197
  }
194
- catch {
195
- // ignore
198
+ catch (error) {
199
+ getLogger().debug(`[ManifestStore] Failed to unlink lock file: ${error instanceof Error ? error.message : String(error)}`);
196
200
  }
197
201
  }
198
202
  }
@@ -204,7 +208,8 @@ export async function readCheckpointManifest(repoPath) {
204
208
  try {
205
209
  return normalizeManifest(JSON.parse(raw));
206
210
  }
207
- catch {
211
+ catch (error) {
212
+ getLogger().warn(`[ManifestStore] v2 manifest parse error, triggering self-heal: ${error instanceof Error ? error.message : String(error)}`);
208
213
  await selfHealCorruptedManifest({
209
214
  repoPath,
210
215
  manifestPath: manifestV2Path,
@@ -214,15 +219,16 @@ export async function readCheckpointManifest(repoPath) {
214
219
  });
215
220
  }
216
221
  }
217
- catch {
218
- // fallback to legacy v1 file
222
+ catch (error) {
223
+ getLogger().debug(`[ManifestStore] v2 manifest read failed, falling back to v1: ${error instanceof Error ? error.message : String(error)}`);
219
224
  }
220
225
  try {
221
226
  const raw = await readFile(manifestV1Path, 'utf8');
222
227
  try {
223
228
  return normalizeManifest(JSON.parse(raw));
224
229
  }
225
- catch {
230
+ catch (error) {
231
+ getLogger().warn(`[ManifestStore] v1 manifest parse error, triggering self-heal: ${error instanceof Error ? error.message : String(error)}`);
226
232
  await selfHealCorruptedManifest({
227
233
  repoPath,
228
234
  manifestPath: manifestV1Path,
@@ -233,7 +239,8 @@ export async function readCheckpointManifest(repoPath) {
233
239
  return createEmptyManifest();
234
240
  }
235
241
  }
236
- catch {
242
+ catch (error) {
243
+ getLogger().debug(`[ManifestStore] v1 manifest read failed, returning empty manifest: ${error instanceof Error ? error.message : String(error)}`);
237
244
  return createEmptyManifest();
238
245
  }
239
246
  return createEmptyManifest();
@@ -333,7 +340,8 @@ export async function probeCheckpointHandle(repoPath, checkpointId) {
333
340
  return { handle: null, reason: 'not_found' };
334
341
  return { handle, reason: 'ok' };
335
342
  }
336
- catch {
343
+ catch (error) {
344
+ getLogger().debug(`[ManifestStore] Manifest parse failed during probe: ${error instanceof Error ? error.message : String(error)}`);
337
345
  return { handle: null, reason: 'manifest_parse_error' };
338
346
  }
339
347
  }
@@ -1,3 +1,4 @@
1
+ import { getLogger } from '../observability/logger.js';
1
2
  import { CheckpointManager } from '../strata/checkpoint/manager.js';
2
3
  import { garbageCollectManifest, linkSessionToCheckpoint, probeCheckpointHandle, readCheckpointManifest, removeCheckpointHandle, upsertCheckpointHandle, } from './manifest-store.js';
3
4
  export class GitSnapshotCheckpointService {
@@ -74,8 +75,9 @@ export class GitSnapshotCheckpointService {
74
75
  await this.checkpointManager.deleteSnapshot(input.repoPath, checkpointId);
75
76
  refsRemoved += 1;
76
77
  }
77
- catch {
78
+ catch (error) {
78
79
  // Best-effort ref reconciliation; manifest remains source of truth.
80
+ getLogger().debug(`[CheckpointService] snapshot ref cleanup failed for ${checkpointId}: ${error instanceof Error ? error.message : String(error)}`);
79
81
  }
80
82
  }
81
83
  return { removed: manifestGc.removed, refsRemoved };
@@ -2,7 +2,7 @@ export const LIMITS = {
2
2
  // Patch safety
3
3
  maxFilesChanged: 2,
4
4
  maxDiffLines: 200,
5
- maxRetries: 2,
5
+ maxRetries: 5,
6
6
  // Context budget (token-based, with char fallback)
7
7
  maxContextTokens: 7500, // ~30k chars equivalent
8
8
  minContextTokens: 1250, // ~5k chars equivalent
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Per-model token pricing (USD per 1M tokens).
3
+ *
4
+ * Used to estimate run cost from token counts.
5
+ * Prices are approximate and should be updated when providers change rates.
6
+ */
7
+ // prettier-ignore
8
+ export const MODEL_PRICING = {
9
+ // Anthropic Claude
10
+ 'claude-opus-4-7': { inputPer1M: 15, outputPer1M: 75 },
11
+ 'claude-opus-4-6': { inputPer1M: 15, outputPer1M: 75 },
12
+ 'claude-sonnet-4-6': { inputPer1M: 3, outputPer1M: 15 },
13
+ 'claude-sonnet-4-5': { inputPer1M: 3, outputPer1M: 15 },
14
+ 'claude-haiku-4-5': { inputPer1M: 0.80, outputPer1M: 4 },
15
+ 'claude-haiku-4-5-20251001': { inputPer1M: 0.80, outputPer1M: 4 },
16
+ 'claude-3-opus': { inputPer1M: 15, outputPer1M: 75 },
17
+ 'claude-3-sonnet': { inputPer1M: 3, outputPer1M: 15 },
18
+ 'claude-3-haiku': { inputPer1M: 0.25, outputPer1M: 1.25 },
19
+ // OpenAI
20
+ 'gpt-4o': { inputPer1M: 2.50, outputPer1M: 10 },
21
+ 'gpt-4o-mini': { inputPer1M: 0.15, outputPer1M: 0.60 },
22
+ 'gpt-4-turbo': { inputPer1M: 10, outputPer1M: 30 },
23
+ 'gpt-4': { inputPer1M: 30, outputPer1M: 60 },
24
+ 'o1': { inputPer1M: 15, outputPer1M: 60 },
25
+ 'o1-mini': { inputPer1M: 3, outputPer1M: 12 },
26
+ 'o3-mini': { inputPer1M: 1.10, outputPer1M: 4.40 },
27
+ // Google Gemini
28
+ 'gemini-2.5-pro': { inputPer1M: 1.25, outputPer1M: 10 },
29
+ 'gemini-2.5-flash': { inputPer1M: 0.15, outputPer1M: 0.60 },
30
+ 'gemini-2.0-flash': { inputPer1M: 0.10, outputPer1M: 0.40 },
31
+ };
32
+ /**
33
+ * Look up pricing for a model ID.
34
+ * Tries exact match first, then prefix match (e.g. "claude-sonnet-4-6-20250514" matches "claude-sonnet-4-6").
35
+ * Returns undefined if no pricing is available.
36
+ */
37
+ export function getModelPricing(modelId) {
38
+ if (!modelId)
39
+ return undefined;
40
+ // Exact match
41
+ if (MODEL_PRICING[modelId])
42
+ return MODEL_PRICING[modelId];
43
+ // Prefix match — try longest prefix first
44
+ const normalized = modelId.toLowerCase();
45
+ for (const key of Object.keys(MODEL_PRICING)) {
46
+ if (normalized.startsWith(key))
47
+ return MODEL_PRICING[key];
48
+ }
49
+ return undefined;
50
+ }
51
+ /**
52
+ * Estimate cost in USD from token counts and model ID.
53
+ */
54
+ export function estimateCost(inputTokens, outputTokens, modelId) {
55
+ const pricing = getModelPricing(modelId);
56
+ if (!pricing)
57
+ return undefined;
58
+ return ((inputTokens / 1_000_000) * pricing.inputPer1M +
59
+ (outputTokens / 1_000_000) * pricing.outputPer1M);
60
+ }
61
+ //# sourceMappingURL=model-pricing.js.map