sparkecoder 0.1.138 → 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.
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/index.js +111 -8
- package/dist/agent/index.js.map +1 -1
- package/dist/cli.js +112 -9
- package/dist/cli.js.map +1 -1
- package/dist/{index-BM99kjgq.d.ts → index-BAsQWqZj.d.ts} +7 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +112 -9
- package/dist/index.js.map +1 -1
- package/dist/server/index.js +112 -9
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.html +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/agents.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.html +1 -1
- package/web/.next/standalone/web/.next/server/app/index.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.html +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/[root-of-the-server]__e5911ea8._.js +1 -1
- package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
- package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
- package/web/.next/standalone/web/.next/static/{static/chunks/3f50fe2a802aa800.js → chunks/b0cae7e255cae74d.js} +1 -1
- package/web/.next/standalone/web/.next/static/{chunks/3f50fe2a802aa800.js → static/chunks/b0cae7e255cae74d.js} +1 -1
- package/web/.next/standalone/web/runtime-config.json +2 -2
- package/web/.next/standalone/web/src/components/chat-interface.tsx +19 -2
- package/web/.next/static/chunks/{3f50fe2a802aa800.js → b0cae7e255cae74d.js} +1 -1
- /package/web/.next/standalone/web/.next/static/{hJ9axFUPZg0HHJCXM9Oyx → rY6TfiRfMLnxUYYyNit1Q}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{hJ9axFUPZg0HHJCXM9Oyx → rY6TfiRfMLnxUYYyNit1Q}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{hJ9axFUPZg0HHJCXM9Oyx → rY6TfiRfMLnxUYYyNit1Q}/_ssgManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{hJ9axFUPZg0HHJCXM9Oyx → rY6TfiRfMLnxUYYyNit1Q}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{hJ9axFUPZg0HHJCXM9Oyx → rY6TfiRfMLnxUYYyNit1Q}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/static/{hJ9axFUPZg0HHJCXM9Oyx → rY6TfiRfMLnxUYYyNit1Q}/_ssgManifest.js +0 -0
- /package/web/.next/static/{hJ9axFUPZg0HHJCXM9Oyx → rY6TfiRfMLnxUYYyNit1Q}/_buildManifest.js +0 -0
- /package/web/.next/static/{hJ9axFUPZg0HHJCXM9Oyx → rY6TfiRfMLnxUYYyNit1Q}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{hJ9axFUPZg0HHJCXM9Oyx → rY6TfiRfMLnxUYYyNit1Q}/_ssgManifest.js +0 -0
|
@@ -797,6 +797,13 @@ declare class ContextManager {
|
|
|
797
797
|
* Get messages for the current context, applying the three-phase pipeline.
|
|
798
798
|
*/
|
|
799
799
|
getMessages(): Promise<ModelMessage[]>;
|
|
800
|
+
/**
|
|
801
|
+
* Drop oldest messages (and, as a last resort, hard-truncate text) until
|
|
802
|
+
* the prompt fits the model's context window. Preserves any leading
|
|
803
|
+
* summary system message and always keeps the most recent message, then
|
|
804
|
+
* repairs tool pairing so dropping can't orphan a tool result.
|
|
805
|
+
*/
|
|
806
|
+
private enforceHardCap;
|
|
800
807
|
/**
|
|
801
808
|
* Strip non-essential content from messages older than the most recent
|
|
802
809
|
* `recentCount`. Operates in-memory only — does not touch the DB.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as ResolvedConfig } from './index-
|
|
2
|
-
export { A as Agent, a as AgentOptions, b as AgentRunOptions, c as AgentStreamResult, S as SparkcoderConfig, T as ToolApprovalConfig } from './index-
|
|
1
|
+
import { R as ResolvedConfig } from './index-BAsQWqZj.js';
|
|
2
|
+
export { A as Agent, a as AgentOptions, b as AgentRunOptions, c as AgentStreamResult, S as SparkcoderConfig, T as ToolApprovalConfig } from './index-BAsQWqZj.js';
|
|
3
3
|
export { ServerOptions, createApp, startServer, stopServer } from './server/index.js';
|
|
4
4
|
export { checkpointQueries, closeDatabase, fileBackupQueries, getDb, initDatabase, messageQueries, sessionQueries, skillQueries, todoQueries, toolExecutionQueries } from './db/index.js';
|
|
5
5
|
import { F as FileBackup, C as Checkpoint } from './schema-Dz-wABVY.js';
|
package/dist/index.js
CHANGED
|
@@ -7686,7 +7686,11 @@ var init_model_limits = __esm({
|
|
|
7686
7686
|
MODEL_LIMITS = {
|
|
7687
7687
|
"claude-opus-4-8": { contextWindow: 2e5, rollingTarget: 15e4 },
|
|
7688
7688
|
"gpt-5.5": { contextWindow: 35e4, rollingTarget: 15e4 },
|
|
7689
|
-
"claude-fable-5": { contextWindow: 2e5, rollingTarget: 15e4 }
|
|
7689
|
+
"claude-fable-5": { contextWindow: 2e5, rollingTarget: 15e4 },
|
|
7690
|
+
// Claude Opus 4.7 advertises a 1M-token context. Keyed WITH the provider
|
|
7691
|
+
// prefix because getModelLimits() matches the full id (e.g.
|
|
7692
|
+
// "anthropic/claude-opus-4.7") before falling back to the prefix table.
|
|
7693
|
+
"anthropic/claude-opus-4.7": { contextWindow: 1e6, rollingTarget: 15e4 }
|
|
7690
7694
|
};
|
|
7691
7695
|
DEFAULT_LIMITS = { contextWindow: 2e5, rollingTarget: 15e4 };
|
|
7692
7696
|
PREFIX_DEFAULTS = {
|
|
@@ -7760,6 +7764,39 @@ var init_conversation_archive = __esm({
|
|
|
7760
7764
|
|
|
7761
7765
|
// src/agent/context.ts
|
|
7762
7766
|
import { generateText as generateText2 } from "ai";
|
|
7767
|
+
function truncateMiddle(s, cap) {
|
|
7768
|
+
if (s.length <= cap) return s;
|
|
7769
|
+
const half = Math.floor(cap / 2);
|
|
7770
|
+
return s.slice(0, half) + `
|
|
7771
|
+
...[truncated ${s.length - cap} chars to fit context]...
|
|
7772
|
+
` + s.slice(-half);
|
|
7773
|
+
}
|
|
7774
|
+
function truncateToolResultText(part) {
|
|
7775
|
+
const trunc = (r) => {
|
|
7776
|
+
if (typeof r === "string") return truncateMiddle(r, HARD_TRUNCATE_CHARS);
|
|
7777
|
+
if (r && typeof r === "object" && typeof r.text === "string") {
|
|
7778
|
+
return { ...r, text: truncateMiddle(r.text, HARD_TRUNCATE_CHARS) };
|
|
7779
|
+
}
|
|
7780
|
+
return r;
|
|
7781
|
+
};
|
|
7782
|
+
if (Array.isArray(part.result)) return { ...part, result: part.result.map(trunc) };
|
|
7783
|
+
if ("result" in part) return { ...part, result: trunc(part.result) };
|
|
7784
|
+
return part;
|
|
7785
|
+
}
|
|
7786
|
+
function hardTruncateMessageText(msg) {
|
|
7787
|
+
if (typeof msg.content === "string") {
|
|
7788
|
+
return { ...msg, content: truncateMiddle(msg.content, HARD_TRUNCATE_CHARS) };
|
|
7789
|
+
}
|
|
7790
|
+
if (!Array.isArray(msg.content)) return msg;
|
|
7791
|
+
const parts = msg.content.map((part) => {
|
|
7792
|
+
if (part?.type === "text" && typeof part.text === "string") {
|
|
7793
|
+
return { ...part, text: truncateMiddle(part.text, HARD_TRUNCATE_CHARS) };
|
|
7794
|
+
}
|
|
7795
|
+
if (part?.type === "tool-result") return truncateToolResultText(part);
|
|
7796
|
+
return part;
|
|
7797
|
+
});
|
|
7798
|
+
return { ...msg, content: parts };
|
|
7799
|
+
}
|
|
7763
7800
|
function stripBinaryContentForSummary(value) {
|
|
7764
7801
|
if (Array.isArray(value)) return value.map(stripBinaryContentForSummary);
|
|
7765
7802
|
if (!value || typeof value !== "object") return value;
|
|
@@ -7936,7 +7973,7 @@ function ensureEndsWithUserOrTool(messages) {
|
|
|
7936
7973
|
{ role: "user", content: [{ type: "text", text: "Please continue." }] }
|
|
7937
7974
|
];
|
|
7938
7975
|
}
|
|
7939
|
-
var TOOL_OUTPUT_TRIM_CHARS, COMPACTABLE_TOOLS, ContextManager;
|
|
7976
|
+
var TOOL_OUTPUT_TRIM_CHARS, COMPACTABLE_TOOLS, ContextManager, HARD_TRUNCATE_CHARS;
|
|
7940
7977
|
var init_context = __esm({
|
|
7941
7978
|
"src/agent/context.ts"() {
|
|
7942
7979
|
"use strict";
|
|
@@ -7997,8 +8034,41 @@ ${summaryContent}`
|
|
|
7997
8034
|
messages = ensureToolResultsFollowCalls(messages);
|
|
7998
8035
|
messages = ensureEndsWithUserOrTool(messages);
|
|
7999
8036
|
messages = capImageCount(messages);
|
|
8037
|
+
messages = this.enforceHardCap(messages);
|
|
8000
8038
|
return messages;
|
|
8001
8039
|
}
|
|
8040
|
+
/**
|
|
8041
|
+
* Drop oldest messages (and, as a last resort, hard-truncate text) until
|
|
8042
|
+
* the prompt fits the model's context window. Preserves any leading
|
|
8043
|
+
* summary system message and always keeps the most recent message, then
|
|
8044
|
+
* repairs tool pairing so dropping can't orphan a tool result.
|
|
8045
|
+
*/
|
|
8046
|
+
enforceHardCap(messages) {
|
|
8047
|
+
const { contextWindow } = getModelLimits(this.modelId);
|
|
8048
|
+
const ceiling = Math.max(2e4, Math.floor(contextWindow * 0.9));
|
|
8049
|
+
const tokens = messages.map((m) => this.messageTokens(m));
|
|
8050
|
+
let total = tokens.reduce((a, b) => a + b, 0);
|
|
8051
|
+
if (total <= ceiling) return messages;
|
|
8052
|
+
const hasLeadingSummary = messages.length > 0 && messages[0].role === "system";
|
|
8053
|
+
const firstBody = hasLeadingSummary ? 1 : 0;
|
|
8054
|
+
const lastIndex = messages.length - 1;
|
|
8055
|
+
let start = firstBody;
|
|
8056
|
+
while (start < lastIndex && total > ceiling) {
|
|
8057
|
+
total -= tokens[start];
|
|
8058
|
+
start += 1;
|
|
8059
|
+
}
|
|
8060
|
+
let out = hasLeadingSummary ? [messages[0], ...messages.slice(start)] : messages.slice(start);
|
|
8061
|
+
if (total > ceiling) {
|
|
8062
|
+
out = out.map((m) => hardTruncateMessageText(m));
|
|
8063
|
+
}
|
|
8064
|
+
out = repairToolPairing(out);
|
|
8065
|
+
out = ensureToolResultsFollowCalls(out);
|
|
8066
|
+
out = ensureEndsWithUserOrTool(out);
|
|
8067
|
+
console.warn(
|
|
8068
|
+
`[Context] hard cap engaged for ${this.modelId}: trimmed ${messages.length}\u2192${out.length} msgs (ceiling ${ceiling} tokens).`
|
|
8069
|
+
);
|
|
8070
|
+
return out;
|
|
8071
|
+
}
|
|
8002
8072
|
// ---------------------------------------------------------------------------
|
|
8003
8073
|
// Phase 1 – Compact
|
|
8004
8074
|
// ---------------------------------------------------------------------------
|
|
@@ -8225,6 +8295,7 @@ ${summaryContent}`
|
|
|
8225
8295
|
this.summaries = [];
|
|
8226
8296
|
}
|
|
8227
8297
|
};
|
|
8298
|
+
HARD_TRUNCATE_CHARS = 6e3;
|
|
8228
8299
|
}
|
|
8229
8300
|
});
|
|
8230
8301
|
|
|
@@ -9086,7 +9157,29 @@ function markRespondedForThread(slackChannel2, threadTs) {
|
|
|
9086
9157
|
}
|
|
9087
9158
|
}
|
|
9088
9159
|
function resolveBatchOnTurnEnd(events, ok) {
|
|
9089
|
-
if (!ok)
|
|
9160
|
+
if (!ok) {
|
|
9161
|
+
for (const ev of events) {
|
|
9162
|
+
const key2 = eventKey(ev);
|
|
9163
|
+
const entry2 = ledger.get(key2);
|
|
9164
|
+
if (!entry2 || TERMINAL.has(entry2.state)) continue;
|
|
9165
|
+
entry2.state = "failed";
|
|
9166
|
+
entry2.updatedAt = Date.now();
|
|
9167
|
+
if (entry2.channel === "slack" && entry2.slackChannel) {
|
|
9168
|
+
if (entry2.messageTs) fireResultReaction(entry2.slackChannel, entry2.messageTs, "failed");
|
|
9169
|
+
if (entry2.threadTs) maybePostFallback(entry2.slackChannel, entry2.threadTs);
|
|
9170
|
+
}
|
|
9171
|
+
recordEvent({
|
|
9172
|
+
source: "daemon",
|
|
9173
|
+
status: "failed",
|
|
9174
|
+
channel: entry2.channel,
|
|
9175
|
+
sessionId: entry2.sessionId,
|
|
9176
|
+
error: "turn failed; not replayed (avoids context-overflow spiral)",
|
|
9177
|
+
textSnippet: entry2.event.content.slice(0, 200),
|
|
9178
|
+
meta: { ackKey: entry2.key, ackState: "failed" }
|
|
9179
|
+
});
|
|
9180
|
+
}
|
|
9181
|
+
return;
|
|
9182
|
+
}
|
|
9090
9183
|
for (const ev of events) {
|
|
9091
9184
|
const key2 = eventKey(ev);
|
|
9092
9185
|
const entry2 = ledger.get(key2);
|
|
@@ -9138,11 +9231,7 @@ function failEntry(entry2) {
|
|
|
9138
9231
|
if (entry2.channel === "slack" && entry2.slackChannel && entry2.messageTs) {
|
|
9139
9232
|
fireResultReaction(entry2.slackChannel, entry2.messageTs, "failed");
|
|
9140
9233
|
if (entry2.threadTs) {
|
|
9141
|
-
|
|
9142
|
-
entry2.slackChannel,
|
|
9143
|
-
entry2.threadTs,
|
|
9144
|
-
`: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.`
|
|
9145
|
-
);
|
|
9234
|
+
maybePostFallback(entry2.slackChannel, entry2.threadTs);
|
|
9146
9235
|
}
|
|
9147
9236
|
}
|
|
9148
9237
|
recordEvent({
|
|
@@ -9185,6 +9274,17 @@ function fireFallback(channel, threadTs, text) {
|
|
|
9185
9274
|
} catch {
|
|
9186
9275
|
}
|
|
9187
9276
|
}
|
|
9277
|
+
function maybePostFallback(channel, threadTs) {
|
|
9278
|
+
const now = Date.now();
|
|
9279
|
+
const last = lastFallbackAt.get(channel) ?? 0;
|
|
9280
|
+
if (now - last < FALLBACK_COOLDOWN_MS) return;
|
|
9281
|
+
lastFallbackAt.set(channel, now);
|
|
9282
|
+
fireFallback(
|
|
9283
|
+
channel,
|
|
9284
|
+
threadTs,
|
|
9285
|
+
"\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."
|
|
9286
|
+
);
|
|
9287
|
+
}
|
|
9188
9288
|
function startReconciler() {
|
|
9189
9289
|
if (reconcileTimer) return;
|
|
9190
9290
|
reconcileTimer = setInterval(() => {
|
|
@@ -9206,8 +9306,9 @@ function __listAcks() {
|
|
|
9206
9306
|
}
|
|
9207
9307
|
function __resetAcks() {
|
|
9208
9308
|
ledger.clear();
|
|
9309
|
+
lastFallbackAt.clear();
|
|
9209
9310
|
}
|
|
9210
|
-
var REPLAY_AFTER_MS, RECONCILE_EVERY_MS, MAX_ATTEMPTS, PRUNE_AFTER_MS, MAX_ENTRIES, TERMINAL, SEP, ledger, reconcileTimer;
|
|
9311
|
+
var REPLAY_AFTER_MS, RECONCILE_EVERY_MS, MAX_ATTEMPTS, PRUNE_AFTER_MS, FALLBACK_COOLDOWN_MS, lastFallbackAt, MAX_ENTRIES, TERMINAL, SEP, ledger, reconcileTimer;
|
|
9211
9312
|
var init_inbox_acks = __esm({
|
|
9212
9313
|
"src/orchestrator/inbox-acks.ts"() {
|
|
9213
9314
|
"use strict";
|
|
@@ -9218,6 +9319,8 @@ var init_inbox_acks = __esm({
|
|
|
9218
9319
|
RECONCILE_EVERY_MS = 6e4;
|
|
9219
9320
|
MAX_ATTEMPTS = 2;
|
|
9220
9321
|
PRUNE_AFTER_MS = 60 * 6e4;
|
|
9322
|
+
FALLBACK_COOLDOWN_MS = 15 * 6e4;
|
|
9323
|
+
lastFallbackAt = /* @__PURE__ */ new Map();
|
|
9221
9324
|
MAX_ENTRIES = 5e3;
|
|
9222
9325
|
TERMINAL = /* @__PURE__ */ new Set(["responded", "skipped", "handed_off", "failed"]);
|
|
9223
9326
|
SEP = "\u241F";
|