sparkecoder 0.1.137 → 0.1.139

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 (121) hide show
  1. package/dist/agent/index.d.ts +1 -1
  2. package/dist/agent/index.js +111 -8
  3. package/dist/agent/index.js.map +1 -1
  4. package/dist/cli.js +112 -9
  5. package/dist/cli.js.map +1 -1
  6. package/dist/{index-BM99kjgq.d.ts → index-BAsQWqZj.d.ts} +7 -0
  7. package/dist/index.d.ts +2 -2
  8. package/dist/index.js +112 -9
  9. package/dist/index.js.map +1 -1
  10. package/dist/server/index.js +112 -9
  11. package/dist/server/index.js.map +1 -1
  12. package/package.json +1 -1
  13. package/web/.next/BUILD_ID +1 -1
  14. package/web/.next/standalone/web/.next/BUILD_ID +1 -1
  15. package/web/.next/standalone/web/.next/build-manifest.json +2 -2
  16. package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
  17. package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page_client-reference-manifest.js +1 -1
  18. package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
  19. package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
  20. package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  21. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  22. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  23. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  24. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  25. package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
  26. package/web/.next/standalone/web/.next/server/app/_not-found.rsc +1 -1
  27. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  28. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  29. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  30. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  31. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  32. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  33. package/web/.next/standalone/web/.next/server/app/agents.html +1 -1
  34. package/web/.next/standalone/web/.next/server/app/agents.rsc +1 -1
  35. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents/__PAGE__.segment.rsc +1 -1
  36. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents.segment.rsc +1 -1
  37. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p.segment.rsc +1 -1
  38. package/web/.next/standalone/web/.next/server/app/agents.segments/_full.segment.rsc +1 -1
  39. package/web/.next/standalone/web/.next/server/app/agents.segments/_head.segment.rsc +1 -1
  40. package/web/.next/standalone/web/.next/server/app/agents.segments/_index.segment.rsc +1 -1
  41. package/web/.next/standalone/web/.next/server/app/agents.segments/_tree.segment.rsc +1 -1
  42. package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
  43. package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +1 -1
  44. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +1 -1
  45. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
  46. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +1 -1
  47. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
  48. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +1 -1
  49. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
  50. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +1 -1
  51. package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
  52. package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +1 -1
  53. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +1 -1
  54. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
  55. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +1 -1
  56. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
  57. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
  58. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
  59. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +1 -1
  60. package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
  61. package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +1 -1
  62. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +1 -1
  63. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
  64. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +1 -1
  65. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
  66. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +1 -1
  67. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
  68. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +1 -1
  69. package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
  70. package/web/.next/standalone/web/.next/server/app/docs.rsc +1 -1
  71. package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +1 -1
  72. package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
  73. package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +1 -1
  74. package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
  75. package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
  76. package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
  77. package/web/.next/standalone/web/.next/server/app/index.html +1 -1
  78. package/web/.next/standalone/web/.next/server/app/index.rsc +1 -1
  79. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +1 -1
  80. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +1 -1
  81. package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +1 -1
  82. package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  83. package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +1 -1
  84. package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  85. package/web/.next/standalone/web/.next/server/app/settings.html +1 -1
  86. package/web/.next/standalone/web/.next/server/app/settings.rsc +1 -1
  87. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings/__PAGE__.segment.rsc +1 -1
  88. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings.segment.rsc +1 -1
  89. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p.segment.rsc +1 -1
  90. package/web/.next/standalone/web/.next/server/app/settings.segments/_full.segment.rsc +1 -1
  91. package/web/.next/standalone/web/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  92. package/web/.next/standalone/web/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  93. package/web/.next/standalone/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  94. package/web/.next/standalone/web/.next/server/chunks/[root-of-the-server]__5b38d1a5._.js +1 -1
  95. package/web/.next/standalone/web/.next/server/chunks/[root-of-the-server]__78517719._.js +1 -1
  96. package/web/.next/standalone/web/.next/server/chunks/[root-of-the-server]__9d50fe63._.js +1 -1
  97. package/web/.next/standalone/web/.next/server/chunks/[root-of-the-server]__ce44139a._.js +1 -1
  98. package/web/.next/standalone/web/.next/server/chunks/ssr/[root-of-the-server]__e5911ea8._.js +1 -1
  99. package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
  100. package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
  101. package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
  102. package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
  103. package/web/.next/{static/chunks/3f50fe2a802aa800.js → standalone/web/.next/static/chunks/b0cae7e255cae74d.js} +1 -1
  104. package/web/.next/standalone/web/.next/static/{chunks/3f50fe2a802aa800.js → static/chunks/b0cae7e255cae74d.js} +1 -1
  105. package/web/.next/standalone/web/runtime-config.json +5 -5
  106. package/web/.next/standalone/web/src/app/api/config/route.ts +3 -3
  107. package/web/.next/standalone/web/src/app/api/diag/route.ts +5 -2
  108. package/web/.next/standalone/web/src/app/api/health/route.ts +2 -2
  109. package/web/.next/standalone/web/src/app/sfapi/[...path]/route.ts +2 -2
  110. package/web/.next/standalone/web/src/components/chat-interface.tsx +19 -2
  111. package/web/.next/standalone/web/src/lib/local-api.ts +49 -0
  112. package/web/.next/{standalone/web/.next/static/static/chunks/3f50fe2a802aa800.js → static/chunks/b0cae7e255cae74d.js} +1 -1
  113. /package/web/.next/standalone/web/.next/static/{static/wvsSqSLuE0FvQYeAvnmPm → rY6TfiRfMLnxUYYyNit1Q}/_buildManifest.js +0 -0
  114. /package/web/.next/standalone/web/.next/static/{static/wvsSqSLuE0FvQYeAvnmPm → rY6TfiRfMLnxUYYyNit1Q}/_clientMiddlewareManifest.json +0 -0
  115. /package/web/.next/standalone/web/.next/static/{static/wvsSqSLuE0FvQYeAvnmPm → rY6TfiRfMLnxUYYyNit1Q}/_ssgManifest.js +0 -0
  116. /package/web/.next/standalone/web/.next/static/{wvsSqSLuE0FvQYeAvnmPm → static/rY6TfiRfMLnxUYYyNit1Q}/_buildManifest.js +0 -0
  117. /package/web/.next/standalone/web/.next/static/{wvsSqSLuE0FvQYeAvnmPm → static/rY6TfiRfMLnxUYYyNit1Q}/_clientMiddlewareManifest.json +0 -0
  118. /package/web/.next/standalone/web/.next/static/{wvsSqSLuE0FvQYeAvnmPm → static/rY6TfiRfMLnxUYYyNit1Q}/_ssgManifest.js +0 -0
  119. /package/web/.next/static/{wvsSqSLuE0FvQYeAvnmPm → rY6TfiRfMLnxUYYyNit1Q}/_buildManifest.js +0 -0
  120. /package/web/.next/static/{wvsSqSLuE0FvQYeAvnmPm → rY6TfiRfMLnxUYYyNit1Q}/_clientMiddlewareManifest.json +0 -0
  121. /package/web/.next/static/{wvsSqSLuE0FvQYeAvnmPm → rY6TfiRfMLnxUYYyNit1Q}/_ssgManifest.js +0 -0
@@ -1,6 +1,6 @@
1
1
  import 'ai';
2
2
  import '../schema-Dz-wABVY.js';
3
- export { A as Agent, a as AgentOptions, b as AgentRunOptions, c as AgentStreamResult, C as ContextManager, M as MessageAttachment, d as buildSystemPrompt, e as buildTaskPromptAddendum } from '../index-BM99kjgq.js';
3
+ export { A as Agent, a as AgentOptions, b as AgentRunOptions, c as AgentStreamResult, C as ContextManager, M as MessageAttachment, d as buildSystemPrompt, e as buildTaskPromptAddendum } from '../index-BAsQWqZj.js';
4
4
  import '../search-CVVfuBPZ.js';
5
5
  import 'drizzle-orm/sqlite-core';
6
6
  import 'zod';
@@ -2220,7 +2220,29 @@ function markRespondedForThread(slackChannel2, threadTs) {
2220
2220
  }
2221
2221
  }
2222
2222
  function resolveBatchOnTurnEnd(events, ok) {
2223
- if (!ok) return;
2223
+ if (!ok) {
2224
+ for (const ev of events) {
2225
+ const key2 = eventKey(ev);
2226
+ const entry2 = ledger.get(key2);
2227
+ if (!entry2 || TERMINAL.has(entry2.state)) continue;
2228
+ entry2.state = "failed";
2229
+ entry2.updatedAt = Date.now();
2230
+ if (entry2.channel === "slack" && entry2.slackChannel) {
2231
+ if (entry2.messageTs) fireResultReaction(entry2.slackChannel, entry2.messageTs, "failed");
2232
+ if (entry2.threadTs) maybePostFallback(entry2.slackChannel, entry2.threadTs);
2233
+ }
2234
+ recordEvent({
2235
+ source: "daemon",
2236
+ status: "failed",
2237
+ channel: entry2.channel,
2238
+ sessionId: entry2.sessionId,
2239
+ error: "turn failed; not replayed (avoids context-overflow spiral)",
2240
+ textSnippet: entry2.event.content.slice(0, 200),
2241
+ meta: { ackKey: entry2.key, ackState: "failed" }
2242
+ });
2243
+ }
2244
+ return;
2245
+ }
2224
2246
  for (const ev of events) {
2225
2247
  const key2 = eventKey(ev);
2226
2248
  const entry2 = ledger.get(key2);
@@ -2272,11 +2294,7 @@ function failEntry(entry2) {
2272
2294
  if (entry2.channel === "slack" && entry2.slackChannel && entry2.messageTs) {
2273
2295
  fireResultReaction(entry2.slackChannel, entry2.messageTs, "failed");
2274
2296
  if (entry2.threadTs) {
2275
- fireFallback(
2276
- entry2.slackChannel,
2277
- entry2.threadTs,
2278
- `:warning: I wasn't able to handle this after ${entry2.attempts} attempt(s). It may need a human \u2014 flagging it here so it isn't lost.`
2279
- );
2297
+ maybePostFallback(entry2.slackChannel, entry2.threadTs);
2280
2298
  }
2281
2299
  }
2282
2300
  recordEvent({
@@ -2319,6 +2337,17 @@ function fireFallback(channel, threadTs, text) {
2319
2337
  } catch {
2320
2338
  }
2321
2339
  }
2340
+ function maybePostFallback(channel, threadTs) {
2341
+ const now = Date.now();
2342
+ const last = lastFallbackAt.get(channel) ?? 0;
2343
+ if (now - last < FALLBACK_COOLDOWN_MS) return;
2344
+ lastFallbackAt.set(channel, now);
2345
+ fireFallback(
2346
+ channel,
2347
+ threadTs,
2348
+ "\u26A0\uFE0F I'm having trouble processing messages right now (likely an overloaded context or a backend error). A human may need to check on me \u2014 I'll pick back up once it's resolved."
2349
+ );
2350
+ }
2322
2351
  function startReconciler() {
2323
2352
  if (reconcileTimer) return;
2324
2353
  reconcileTimer = setInterval(() => {
@@ -2340,8 +2369,9 @@ function __listAcks() {
2340
2369
  }
2341
2370
  function __resetAcks() {
2342
2371
  ledger.clear();
2372
+ lastFallbackAt.clear();
2343
2373
  }
2344
- var REPLAY_AFTER_MS, RECONCILE_EVERY_MS, MAX_ATTEMPTS, PRUNE_AFTER_MS, MAX_ENTRIES, TERMINAL, SEP, ledger, reconcileTimer;
2374
+ var REPLAY_AFTER_MS, RECONCILE_EVERY_MS, MAX_ATTEMPTS, PRUNE_AFTER_MS, FALLBACK_COOLDOWN_MS, lastFallbackAt, MAX_ENTRIES, TERMINAL, SEP, ledger, reconcileTimer;
2345
2375
  var init_inbox_acks = __esm({
2346
2376
  "src/orchestrator/inbox-acks.ts"() {
2347
2377
  "use strict";
@@ -2352,6 +2382,8 @@ var init_inbox_acks = __esm({
2352
2382
  RECONCILE_EVERY_MS = 6e4;
2353
2383
  MAX_ATTEMPTS = 2;
2354
2384
  PRUNE_AFTER_MS = 60 * 6e4;
2385
+ FALLBACK_COOLDOWN_MS = 15 * 6e4;
2386
+ lastFallbackAt = /* @__PURE__ */ new Map();
2355
2387
  MAX_ENTRIES = 5e3;
2356
2388
  TERMINAL = /* @__PURE__ */ new Set(["responded", "skipped", "handed_off", "failed"]);
2357
2389
  SEP = "\u241F";
@@ -7706,7 +7738,11 @@ function capImageCount(messages, max = MAX_IMAGES_IN_CONTEXT) {
7706
7738
  var MODEL_LIMITS = {
7707
7739
  "claude-opus-4-8": { contextWindow: 2e5, rollingTarget: 15e4 },
7708
7740
  "gpt-5.5": { contextWindow: 35e4, rollingTarget: 15e4 },
7709
- "claude-fable-5": { contextWindow: 2e5, rollingTarget: 15e4 }
7741
+ "claude-fable-5": { contextWindow: 2e5, rollingTarget: 15e4 },
7742
+ // Claude Opus 4.7 advertises a 1M-token context. Keyed WITH the provider
7743
+ // prefix because getModelLimits() matches the full id (e.g.
7744
+ // "anthropic/claude-opus-4.7") before falling back to the prefix table.
7745
+ "anthropic/claude-opus-4.7": { contextWindow: 1e6, rollingTarget: 15e4 }
7710
7746
  };
7711
7747
  var DEFAULT_LIMITS = { contextWindow: 2e5, rollingTarget: 15e4 };
7712
7748
  var PREFIX_DEFAULTS = {
@@ -7778,8 +7814,41 @@ ${summaryContent}`
7778
7814
  messages = ensureToolResultsFollowCalls(messages);
7779
7815
  messages = ensureEndsWithUserOrTool(messages);
7780
7816
  messages = capImageCount(messages);
7817
+ messages = this.enforceHardCap(messages);
7781
7818
  return messages;
7782
7819
  }
7820
+ /**
7821
+ * Drop oldest messages (and, as a last resort, hard-truncate text) until
7822
+ * the prompt fits the model's context window. Preserves any leading
7823
+ * summary system message and always keeps the most recent message, then
7824
+ * repairs tool pairing so dropping can't orphan a tool result.
7825
+ */
7826
+ enforceHardCap(messages) {
7827
+ const { contextWindow } = getModelLimits(this.modelId);
7828
+ const ceiling = Math.max(2e4, Math.floor(contextWindow * 0.9));
7829
+ const tokens = messages.map((m) => this.messageTokens(m));
7830
+ let total = tokens.reduce((a, b) => a + b, 0);
7831
+ if (total <= ceiling) return messages;
7832
+ const hasLeadingSummary = messages.length > 0 && messages[0].role === "system";
7833
+ const firstBody = hasLeadingSummary ? 1 : 0;
7834
+ const lastIndex = messages.length - 1;
7835
+ let start = firstBody;
7836
+ while (start < lastIndex && total > ceiling) {
7837
+ total -= tokens[start];
7838
+ start += 1;
7839
+ }
7840
+ let out = hasLeadingSummary ? [messages[0], ...messages.slice(start)] : messages.slice(start);
7841
+ if (total > ceiling) {
7842
+ out = out.map((m) => hardTruncateMessageText(m));
7843
+ }
7844
+ out = repairToolPairing(out);
7845
+ out = ensureToolResultsFollowCalls(out);
7846
+ out = ensureEndsWithUserOrTool(out);
7847
+ console.warn(
7848
+ `[Context] hard cap engaged for ${this.modelId}: trimmed ${messages.length}\u2192${out.length} msgs (ceiling ${ceiling} tokens).`
7849
+ );
7850
+ return out;
7851
+ }
7783
7852
  // ---------------------------------------------------------------------------
7784
7853
  // Phase 1 – Compact
7785
7854
  // ---------------------------------------------------------------------------
@@ -8006,6 +8075,40 @@ ${summaryContent}`
8006
8075
  this.summaries = [];
8007
8076
  }
8008
8077
  };
8078
+ var HARD_TRUNCATE_CHARS = 6e3;
8079
+ function truncateMiddle(s, cap) {
8080
+ if (s.length <= cap) return s;
8081
+ const half = Math.floor(cap / 2);
8082
+ return s.slice(0, half) + `
8083
+ ...[truncated ${s.length - cap} chars to fit context]...
8084
+ ` + s.slice(-half);
8085
+ }
8086
+ function truncateToolResultText(part) {
8087
+ const trunc = (r) => {
8088
+ if (typeof r === "string") return truncateMiddle(r, HARD_TRUNCATE_CHARS);
8089
+ if (r && typeof r === "object" && typeof r.text === "string") {
8090
+ return { ...r, text: truncateMiddle(r.text, HARD_TRUNCATE_CHARS) };
8091
+ }
8092
+ return r;
8093
+ };
8094
+ if (Array.isArray(part.result)) return { ...part, result: part.result.map(trunc) };
8095
+ if ("result" in part) return { ...part, result: trunc(part.result) };
8096
+ return part;
8097
+ }
8098
+ function hardTruncateMessageText(msg) {
8099
+ if (typeof msg.content === "string") {
8100
+ return { ...msg, content: truncateMiddle(msg.content, HARD_TRUNCATE_CHARS) };
8101
+ }
8102
+ if (!Array.isArray(msg.content)) return msg;
8103
+ const parts = msg.content.map((part) => {
8104
+ if (part?.type === "text" && typeof part.text === "string") {
8105
+ return { ...part, text: truncateMiddle(part.text, HARD_TRUNCATE_CHARS) };
8106
+ }
8107
+ if (part?.type === "tool-result") return truncateToolResultText(part);
8108
+ return part;
8109
+ });
8110
+ return { ...msg, content: parts };
8111
+ }
8009
8112
  function stripBinaryContentForSummary(value) {
8010
8113
  if (Array.isArray(value)) return value.map(stripBinaryContentForSummary);
8011
8114
  if (!value || typeof value !== "object") return value;