@sema-agent/core 1.452.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/agent-transcript-tool.d.ts +15 -0
- package/dist/agents/agent-transcript-tool.js +122 -0
- package/dist/agents/cascade.js +5 -8
- package/dist/agents/repair-loop.d.ts +1 -1
- package/dist/agents/repair-loop.js +1 -1
- package/dist/agents/retain-ledger.d.ts +60 -0
- package/dist/agents/retain-ledger.js +225 -0
- package/dist/agents/roster-store.d.ts +1 -0
- package/dist/agents/roster-store.js +9 -0
- package/dist/agents/send-message-tool.d.ts +41 -0
- package/dist/agents/send-message-tool.js +469 -0
- package/dist/agents/subagent.d.ts +33 -108
- package/dist/agents/subagent.js +22 -834
- package/dist/agents/teacher.d.ts +0 -1
- package/dist/agents/teacher.js +0 -9
- package/dist/bin/sema-tb.js +3 -3
- package/dist/brain/anthropic.js +15 -40
- package/dist/brain/openai.js +15 -40
- package/dist/brain/reasoning.d.ts +1 -1
- package/dist/brain/stream-engine.js +2 -2
- package/dist/brain/stream-shared.d.ts +17 -0
- package/dist/brain/stream-shared.js +50 -0
- package/dist/brain/timeout.d.ts +1 -1
- package/dist/brain/timeout.js +1 -1
- package/dist/config/catalog.js +1 -3
- package/dist/config/defaults.d.ts +6 -0
- package/dist/config/defaults.js +6 -0
- package/dist/core/ask-question.d.ts +1 -1
- package/dist/core/background-shell.d.ts +1 -1
- package/dist/core/checkpoint-store.d.ts +0 -1
- package/dist/core/exec-gate.d.ts +1 -1
- package/dist/core/exec-output-tail.d.ts +1 -0
- package/dist/core/exec-output-tail.js +6 -0
- package/dist/core/file-snapshot-store.d.ts +1 -1
- package/dist/core/fs-write-gate-policy.d.ts +1 -1
- package/dist/core/git-worktree-env.d.ts +1 -1
- package/dist/core/hooks.d.ts +1 -1
- package/dist/core/image-downsample.d.ts +44 -0
- package/dist/core/image-downsample.js +97 -0
- package/dist/core/lsp.d.ts +1 -1
- package/dist/core/mcp.d.ts +3 -45
- package/dist/core/mcp.js +2 -97
- package/dist/core/media-byte-cap.d.ts +1 -1
- package/dist/core/memory-recall.d.ts +0 -12
- package/dist/core/memory-recall.js +0 -222
- package/dist/core/memory.d.ts +0 -6
- package/dist/core/memory.js +0 -88
- package/dist/core/message-utils.d.ts +1 -1
- package/dist/core/oracle-isolation.d.ts +1 -1
- package/dist/core/remote-env.d.ts +1 -1
- package/dist/core/roles.d.ts +1 -1
- package/dist/core/runner/active-skill-scope.d.ts +1 -1
- package/dist/core/runner/assemble-result.d.ts +0 -2
- package/dist/core/runner/memory-consolidation.d.ts +1 -1
- package/dist/core/runner/prepare-memory.d.ts +16 -0
- package/dist/core/runner/prepare-memory.js +191 -0
- package/dist/core/runner/prepare-task.d.ts +4 -28
- package/dist/core/runner/prepare-task.js +19 -207
- package/dist/core/runner/prompt-suggestions.d.ts +1 -1
- package/dist/core/runner/runtask.d.ts +2 -3
- package/dist/core/runner/runtask.js +337 -529
- package/dist/core/runner/session-rule-policy.d.ts +1 -1
- package/dist/core/runner/synthetic-tools.d.ts +5 -5
- package/dist/core/runner/synthetic-tools.js +4 -4
- package/dist/core/runner/tool-disclosure.d.ts +3 -3
- package/dist/core/runner/tool-disclosure.js +2 -2
- package/dist/core/runner/tool-output-projection.d.ts +6 -0
- package/dist/core/runner/tool-output-projection.js +81 -0
- package/dist/core/runtime.d.ts +1 -1
- package/dist/core/scheduler.d.ts +1 -1
- package/dist/core/sensitive-path-policy.d.ts +1 -1
- package/dist/core/session-reconcile.d.ts +1 -1
- package/dist/core/session-store.d.ts +2 -1
- package/dist/core/session-store.js +2 -1
- package/dist/core/session.d.ts +0 -1
- package/dist/core/task-registry-agent.d.ts +115 -0
- package/dist/core/task-registry-agent.js +1163 -0
- package/dist/core/task-registry-monitor.d.ts +13 -0
- package/dist/core/task-registry-monitor.js +347 -0
- package/dist/core/task-registry-shared.d.ts +294 -0
- package/dist/core/task-registry-shared.js +271 -0
- package/dist/core/task-registry-workflow.d.ts +5 -0
- package/dist/core/task-registry-workflow.js +143 -0
- package/dist/core/task-registry.d.ts +51 -216
- package/dist/core/task-registry.js +127 -1940
- package/dist/core/task-tool-shape.d.ts +32 -0
- package/dist/core/task-tool-shape.js +83 -0
- package/dist/core/tool-policy.d.ts +1 -2
- package/dist/core/tool-result-budget.d.ts +1 -1
- package/dist/core/tool-result-store.d.ts +2 -2
- package/dist/core/tool-result-store.js +1 -1
- package/dist/core/tools.d.ts +2 -3
- package/dist/core/tools.js +1 -8
- package/dist/core/trace.d.ts +2 -2
- package/dist/core/types.d.ts +0 -29
- package/dist/core/workflow-run-store-contract.d.ts +1 -1
- package/dist/core/workflow-run-store-contract.js +19 -19
- package/dist/engine/execution-env/node-execution-env.d.ts +13 -0
- package/dist/engine/execution-env/node-execution-env.js +55 -25
- package/dist/engine/loop/agent-loop.d.ts +1 -1
- package/dist/engine/loop/agent-loop.js +10 -9
- package/dist/engine/lsp/frame-decoder.d.ts +1 -1
- package/dist/engine/lsp/frame-decoder.js +1 -1
- package/dist/engine/lsp/node-lsp-manager.d.ts +1 -1
- package/dist/engine/lsp/stdio-lsp-transport.js +2 -2
- package/dist/index.d.ts +16 -14
- package/dist/index.js +13 -11
- package/dist/internal/harness-types.d.ts +7 -0
- package/dist/internal/harness-types.js +1 -0
- package/dist/internal/harness.d.ts +1 -7
- package/dist/internal/harness.js +1 -0
- package/dist/orchestration/goal.js +2 -2
- package/dist/orchestration/run-workflow-tool.d.ts +1 -1
- package/dist/orchestration/workflow-types.d.ts +193 -0
- package/dist/orchestration/workflow-types.js +54 -0
- package/dist/orchestration/workflow.d.ts +3 -193
- package/dist/orchestration/workflow.js +7 -59
- package/dist/prompt-assembly/assemble.d.ts +3 -3
- package/dist/prompt-assembly/assemble.js +0 -16
- package/dist/prompt-assembly/explain.d.ts +1 -1
- package/dist/prompt-assembly/tool-catalog.d.ts +1 -1
- package/dist/prompts/default.d.ts +1 -6
- package/dist/prompts/default.js +3 -11
- package/dist/scenarios/env.d.ts +1 -1
- package/dist/scenarios/full-body.d.ts +0 -3
- package/dist/scenarios/full-body.js +0 -2
- package/dist/stores/file/background-agent-store.d.ts +2 -15
- package/dist/stores/file/background-agent-store.js +30 -100
- package/dist/stores/file/checkpoint-store.d.ts +1 -14
- package/dist/stores/file/checkpoint-store.js +47 -119
- package/dist/stores/file/file-snapshot-store.d.ts +1 -1
- package/dist/stores/file/mailbox-store.js +33 -2
- package/dist/stores/file/shared-ledger.d.ts +35 -0
- package/dist/stores/file/shared-ledger.js +94 -0
- package/dist/stores/file/workflow-run-store.d.ts +1 -14
- package/dist/stores/file/workflow-run-store.js +24 -93
- package/dist/tools/fs/bash-readonly-classifier.d.ts +8 -0
- package/dist/tools/fs/bash-readonly-classifier.js +166 -0
- package/dist/tools/fs/fs-bash.d.ts +31 -0
- package/dist/tools/fs/fs-bash.js +672 -0
- package/dist/tools/fs/fs-pdf.d.ts +22 -0
- package/dist/tools/fs/fs-pdf.js +236 -0
- package/dist/tools/fs/fs-read.d.ts +8 -0
- package/dist/tools/fs/fs-read.js +286 -0
- package/dist/tools/fs/fs-search-tools.d.ts +5 -0
- package/dist/tools/fs/fs-search-tools.js +175 -0
- package/dist/tools/fs/fs-shared.d.ts +56 -0
- package/dist/tools/fs/fs-shared.js +148 -0
- package/dist/tools/fs/fs-write.d.ts +8 -0
- package/dist/tools/fs/fs-write.js +421 -0
- package/dist/tools/fs/index.d.ts +12 -65
- package/dist/tools/fs/index.js +26 -2090
- package/dist/tools/fs/pdf.d.ts +1 -1
- package/dist/tools/fs/repo-map.d.ts +3 -3
- package/dist/tools/fs/repo-map.js +1 -1
- package/dist/tools/fs/safety.d.ts +4 -1
- package/dist/tools/fs/safety.js +7 -1
- package/dist/tools/fs/search.d.ts +2 -1
- package/dist/tools/fs/search.js +21 -3
- package/dist/tools/monitor.d.ts +1 -1
- package/dist/tools/scheduler-tools.d.ts +1 -1
- package/dist/tools/web.d.ts +2 -2
- package/dist/tools/web.js +46 -8
- package/dist/tools/worktree.d.ts +1 -1
- package/package.json +1 -1
- package/dist/core/dynamic-recall.d.ts +0 -32
- package/dist/core/dynamic-recall.js +0 -76
package/dist/agents/teacher.d.ts
CHANGED
package/dist/agents/teacher.js
CHANGED
|
@@ -82,7 +82,6 @@ async function runTeacherCore(runner, studentSpec, teacher) {
|
|
|
82
82
|
const escalations = [];
|
|
83
83
|
let studentTokens = 0;
|
|
84
84
|
let studentTurns = 0;
|
|
85
|
-
let studentCost = 0;
|
|
86
85
|
let studentCostMicro = 0;
|
|
87
86
|
let studentPrompt = 0;
|
|
88
87
|
let studentCached = 0;
|
|
@@ -98,10 +97,8 @@ async function runTeacherCore(runner, studentSpec, teacher) {
|
|
|
98
97
|
let studentNestedTurns = 0;
|
|
99
98
|
let studentNestedTasks = 0;
|
|
100
99
|
let studentNestedCostMicro = 0;
|
|
101
|
-
let studentNestedCost = 0;
|
|
102
100
|
let teacherTokens = 0;
|
|
103
101
|
let teacherTasks = 0;
|
|
104
|
-
let teacherCost = 0;
|
|
105
102
|
let teacherCostMicro = 0;
|
|
106
103
|
let teacherHrCount = 0;
|
|
107
104
|
let teacherHrWaitMs = 0;
|
|
@@ -175,7 +172,6 @@ async function runTeacherCore(runner, studentSpec, teacher) {
|
|
|
175
172
|
const s = r.stats;
|
|
176
173
|
studentTokens += s.tokens;
|
|
177
174
|
studentTurns += s.turns;
|
|
178
|
-
studentCost += s.costUsd ?? 0;
|
|
179
175
|
studentCostMicro += s.costMicroUsd ?? 0;
|
|
180
176
|
studentPrompt += s.promptTokens ?? 0;
|
|
181
177
|
studentCached += s.cachedTokens ?? 0;
|
|
@@ -196,13 +192,11 @@ async function runTeacherCore(runner, studentSpec, teacher) {
|
|
|
196
192
|
studentNestedTurns += s.nested.turns;
|
|
197
193
|
studentNestedTasks += s.nested.tasks;
|
|
198
194
|
studentNestedCostMicro += s.nested.costMicroUsd ?? 0;
|
|
199
|
-
studentNestedCost += s.nested.costUsd ?? 0;
|
|
200
195
|
}
|
|
201
196
|
};
|
|
202
197
|
const addTeacher = (r) => {
|
|
203
198
|
teacherTokens += r.stats.tokens + (r.stats.nested?.tokens ?? 0);
|
|
204
199
|
teacherTasks += 1;
|
|
205
|
-
teacherCost += (r.stats.costUsd ?? 0) + (r.stats.nested?.costUsd ?? 0);
|
|
206
200
|
teacherCostMicro += (r.stats.costMicroUsd ?? 0) + (r.stats.nested?.costMicroUsd ?? 0);
|
|
207
201
|
if (r.stats.humanReview) {
|
|
208
202
|
teacherHrCount += r.stats.humanReview.count;
|
|
@@ -422,7 +416,6 @@ async function runTeacherCore(runner, studentSpec, teacher) {
|
|
|
422
416
|
...result.stats,
|
|
423
417
|
tokens: studentTokens,
|
|
424
418
|
turns: studentTurns,
|
|
425
|
-
costUsd: studentCost || undefined,
|
|
426
419
|
costMicroUsd: studentCostMicro || undefined,
|
|
427
420
|
promptTokens: studentPrompt || undefined,
|
|
428
421
|
totalInputTokens: studentPrompt || undefined,
|
|
@@ -437,7 +430,6 @@ async function runTeacherCore(runner, studentSpec, teacher) {
|
|
|
437
430
|
turns: studentNestedTurns,
|
|
438
431
|
tasks: studentNestedTasks,
|
|
439
432
|
costMicroUsd: studentNestedCostMicro || undefined,
|
|
440
|
-
costUsd: studentNestedCost || undefined,
|
|
441
433
|
}
|
|
442
434
|
: undefined,
|
|
443
435
|
costBreakdown: {
|
|
@@ -452,7 +444,6 @@ async function runTeacherCore(runner, studentSpec, teacher) {
|
|
|
452
444
|
teacherStats: {
|
|
453
445
|
tokens: teacherTokens,
|
|
454
446
|
tasks: teacherTasks,
|
|
455
|
-
costUsd: teacherCost || undefined,
|
|
456
447
|
costMicroUsd: teacherCostMicro || undefined,
|
|
457
448
|
humanReview: teacherHrCount > 0 ? { count: teacherHrCount, totalWaitMs: teacherHrWaitMs, gates: teacherHrGates } : undefined,
|
|
458
449
|
},
|
package/dist/bin/sema-tb.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { readFileSync, realpathSync, createWriteStream } from "node:fs";
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
|
-
import { Runner, NodeExecutionEnv, createOpenAIBrain, createAnthropicBrain, CODE_SYSTEM_PROMPT, assembleCodeTools,
|
|
4
|
+
import { Runner, NodeExecutionEnv, createOpenAIBrain, createAnthropicBrain, CODE_SYSTEM_PROMPT, assembleCodeTools, createWebFetchSummarizer, } from "../index.js";
|
|
5
5
|
import { positiveIntFromEnv, tbModelInput } from "./tb-env.js";
|
|
6
6
|
import { inferMaxTokensField } from "../brain/openai.js";
|
|
7
7
|
function usage(code = 2) {
|
|
@@ -353,7 +353,7 @@ async function main() {
|
|
|
353
353
|
? {
|
|
354
354
|
systemPrompt: CODE_SYSTEM_PROMPT,
|
|
355
355
|
tools: assembleCodeTools({
|
|
356
|
-
...(process.env.TB_SUMMARIZE === "0" ? {} : { webFetch: { summarize:
|
|
356
|
+
...(process.env.TB_SUMMARIZE === "0" ? {} : { webFetch: { summarize: createWebFetchSummarizer(brain, model) } }),
|
|
357
357
|
...(process.env.TB_TASKLIST === "0" || process.env.TB_TASKLIST === "false" ? { taskList: false } : {}),
|
|
358
358
|
}),
|
|
359
359
|
}
|
|
@@ -426,7 +426,7 @@ async function main() {
|
|
|
426
426
|
const r = await stream.result();
|
|
427
427
|
const mech = r.stats.mechanisms;
|
|
428
428
|
line(`[done] status=${r.status} turns=${r.stats.turns} toolCalls=${r.stats.toolCalls ?? 0} ` +
|
|
429
|
-
`tokens=${r.stats.tokens}
|
|
429
|
+
`tokens=${r.stats.tokens} costMicroUsd=${r.stats.costMicroUsd ?? 0}` +
|
|
430
430
|
` model=${lastServedModel ?? model.id} degraded=${degradedTo ?? "no"}` +
|
|
431
431
|
(r.stats.cacheHitRate !== undefined ? ` cacheHitRate=${r.stats.cacheHitRate.toFixed(3)}` : "") +
|
|
432
432
|
(mech ? ` mech=${mech.finalizeInjected ? "finalize" : ""}${mech.nudgesSent ? `+nudges:${mech.nudgesSent}` : ""}${mech.capShrinks ? `+capShrinks:${mech.capShrinks}` : ""}${mech.callCutoffs ? `+callCutoffs:${mech.callCutoffs}` : ""}${mech.toolClamps ? `+toolClamps:${mech.toolClamps}` : ""}` : "") +
|
package/dist/brain/anthropic.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {} from "../internal/llm.js";
|
|
2
2
|
import { BrainError } from "./errors.js";
|
|
3
|
-
import { DEGENERATE_MESSAGE,
|
|
3
|
+
import { DEGENERATE_MESSAGE, trimDegenerateTail } from "./repetition.js";
|
|
4
|
+
import { createRepetitionPoll, createWalltimeGate } from "./stream-shared.js";
|
|
4
5
|
import { WALLTIME_CUTOFF_MESSAGE } from "./walltime.js";
|
|
5
6
|
import { emitBrainTelemetry } from "./status-sink.js";
|
|
6
7
|
import { ANTHROPIC_RESERVED, applyExtraBody, stripAuthHeaders } from "./request-params.js";
|
|
@@ -340,24 +341,8 @@ export function createAnthropicBrain(config = {}) {
|
|
|
340
341
|
let nextContentIndex = 0;
|
|
341
342
|
let degenerate = false;
|
|
342
343
|
let degenTextBlock;
|
|
343
|
-
|
|
344
|
-
const
|
|
345
|
-
const pollRepetition = (text) => {
|
|
346
|
-
const insp = inspectDegenerate(text);
|
|
347
|
-
for (const s of insp.spared) {
|
|
348
|
-
const k = `${s.rule} ${s.segment}`;
|
|
349
|
-
const prev = repSpared.get(k);
|
|
350
|
-
if (prev === undefined)
|
|
351
|
-
repSpared.set(k, s);
|
|
352
|
-
else if (s.reps > prev.reps)
|
|
353
|
-
prev.reps = s.reps;
|
|
354
|
-
}
|
|
355
|
-
if (insp.degenerate)
|
|
356
|
-
repCut = insp.cut;
|
|
357
|
-
return insp.degenerate;
|
|
358
|
-
};
|
|
359
|
-
let walltimeCut = false;
|
|
360
|
-
const callDeadlineMs = options?.callDeadlineMs;
|
|
344
|
+
const rep = createRepetitionPoll();
|
|
345
|
+
const walltime = createWalltimeGate({ callDeadlineMs: options?.callDeadlineMs, isDegenerate: () => degenerate, cancel: () => ctrl.cancel() });
|
|
361
346
|
let lastDegenCheck = 0;
|
|
362
347
|
let lastDegenCheckThinking = 0;
|
|
363
348
|
const detectRep = config.detectRepetition !== false;
|
|
@@ -416,7 +401,7 @@ export function createAnthropicBrain(config = {}) {
|
|
|
416
401
|
out.push({ type: "text_delta", contentIndex: idx, delta: d.text, partial: { ...partial } });
|
|
417
402
|
if (detectRep && !degenerate && acc.text.length - lastDegenCheck >= 64) {
|
|
418
403
|
lastDegenCheck = acc.text.length;
|
|
419
|
-
if (
|
|
404
|
+
if (rep.poll(acc.text)) {
|
|
420
405
|
degenerate = true;
|
|
421
406
|
degenTextBlock = acc;
|
|
422
407
|
ctrl.cancel();
|
|
@@ -430,7 +415,7 @@ export function createAnthropicBrain(config = {}) {
|
|
|
430
415
|
out.push({ type: "thinking_delta", contentIndex: idx, delta: d.thinking, partial: { ...partial } });
|
|
431
416
|
if (detectRep && !degenerate && acc.text.length - lastDegenCheckThinking >= 64) {
|
|
432
417
|
lastDegenCheckThinking = acc.text.length;
|
|
433
|
-
if (
|
|
418
|
+
if (rep.poll(acc.text)) {
|
|
434
419
|
degenerate = true;
|
|
435
420
|
ctrl.cancel();
|
|
436
421
|
}
|
|
@@ -512,19 +497,9 @@ export function createAnthropicBrain(config = {}) {
|
|
|
512
497
|
}
|
|
513
498
|
}
|
|
514
499
|
},
|
|
515
|
-
onDeadline()
|
|
516
|
-
if (degenerate)
|
|
517
|
-
return false;
|
|
518
|
-
walltimeCut = true;
|
|
519
|
-
return true;
|
|
520
|
-
},
|
|
500
|
+
onDeadline: () => walltime.onDeadline(),
|
|
521
501
|
onLine(rawLine) {
|
|
522
|
-
if (
|
|
523
|
-
walltimeCut = true;
|
|
524
|
-
ctrl.cancel();
|
|
525
|
-
return;
|
|
526
|
-
}
|
|
527
|
-
if (walltimeCut)
|
|
502
|
+
if (walltime.shouldDropLine())
|
|
528
503
|
return;
|
|
529
504
|
const line = rawLine.trim();
|
|
530
505
|
if (!line.startsWith("data:"))
|
|
@@ -559,7 +534,7 @@ export function createAnthropicBrain(config = {}) {
|
|
|
559
534
|
finalContent.push(block);
|
|
560
535
|
}
|
|
561
536
|
else if (acc.type === "text") {
|
|
562
|
-
const text = acc === degenTextBlock &&
|
|
537
|
+
const text = acc === degenTextBlock && rep.cut !== undefined ? trimDegenerateTail(acc.text, rep.cut) : acc.text;
|
|
563
538
|
if (text) {
|
|
564
539
|
finalContent.push({ type: "text", text });
|
|
565
540
|
if (text.trim())
|
|
@@ -593,9 +568,9 @@ export function createAnthropicBrain(config = {}) {
|
|
|
593
568
|
const staticReasoningCut = truncatedEmpty && !dynamicCut && reasoningSeen && options?.staticReasoningCutDowngrade === true;
|
|
594
569
|
const safetyCut = stopReason === "refusal";
|
|
595
570
|
const contextWindowExceeded = stopReason === "model_context_window_exceeded";
|
|
596
|
-
const emptyNoFinish = noUsableContent && stopReason == null && !degenerate && !
|
|
571
|
+
const emptyNoFinish = noUsableContent && stopReason == null && !degenerate && !walltime.cut;
|
|
597
572
|
const maxTokensNote = `effective max_tokens=${sentMaxTokens ?? "?"} (from ${sentMaxTokensLane === "options" ? "options.maxTokens" : sentMaxTokensLane === "model" ? "model.maxTokens" : "config default"})`;
|
|
598
|
-
const errorMessage =
|
|
573
|
+
const errorMessage = walltime.cut
|
|
599
574
|
? WALLTIME_CUTOFF_MESSAGE
|
|
600
575
|
: degenerate
|
|
601
576
|
? DEGENERATE_MESSAGE
|
|
@@ -613,14 +588,14 @@ export function createAnthropicBrain(config = {}) {
|
|
|
613
588
|
: emptyNoFinish
|
|
614
589
|
? `[stream_torn] model stream ended with no content and no stop_reason — the response was lost (a torn stream or an in-band provider error frame)`
|
|
615
590
|
: undefined));
|
|
616
|
-
const errored =
|
|
591
|
+
const errored = walltime.cut ||
|
|
617
592
|
degenerate ||
|
|
618
593
|
safetyCut ||
|
|
619
594
|
contextWindowExceeded ||
|
|
620
595
|
emptyNoFinish ||
|
|
621
596
|
(toolError !== undefined && noUsableContent) ||
|
|
622
597
|
(truncatedEmpty && !dynamicCut && !staticReasoningCut);
|
|
623
|
-
const errorKind = !
|
|
598
|
+
const errorKind = !walltime.cut && !degenerate && !safetyCut && toolError === undefined && truncatedEmpty && !dynamicCut && !staticReasoningCut
|
|
624
599
|
? "length_empty"
|
|
625
600
|
: undefined;
|
|
626
601
|
const finalMessage = {
|
|
@@ -632,8 +607,8 @@ export function createAnthropicBrain(config = {}) {
|
|
|
632
607
|
timestamp: Date.now(),
|
|
633
608
|
...(errorMessage ? { errorMessage } : {}),
|
|
634
609
|
...(errorKind ? { errorKind } : {}),
|
|
635
|
-
...(
|
|
636
|
-
? { repetition: { ...(
|
|
610
|
+
...(rep.cut !== undefined || rep.spared.length > 0
|
|
611
|
+
? { repetition: { ...(rep.cut !== undefined ? { cut: rep.cut } : {}), ...(rep.spared.length > 0 ? { spared: rep.spared } : {}) } }
|
|
637
612
|
: {}),
|
|
638
613
|
...(staticReasoningCut ? { staticReasoningCut: true } : {}),
|
|
639
614
|
...(stopDetails
|
package/dist/brain/openai.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {} from "../internal/llm.js";
|
|
2
2
|
import { repairTextToolCalls } from "./tool-call-repair.js";
|
|
3
|
-
import { DEGENERATE_MESSAGE,
|
|
3
|
+
import { DEGENERATE_MESSAGE, trimDegenerateTail } from "./repetition.js";
|
|
4
|
+
import { createRepetitionPoll, createWalltimeGate } from "./stream-shared.js";
|
|
4
5
|
import { WALLTIME_CUTOFF_MESSAGE } from "./walltime.js";
|
|
5
6
|
import { emitBrainTelemetry } from "./status-sink.js";
|
|
6
7
|
import { OPENAI_RESERVED, applyExtraBody, stripAuthHeaders } from "./request-params.js";
|
|
@@ -343,24 +344,8 @@ export function createOpenAIBrain(config = {}) {
|
|
|
343
344
|
let accumRefusal = "";
|
|
344
345
|
let degenerate = false;
|
|
345
346
|
let degenFace;
|
|
346
|
-
|
|
347
|
-
const
|
|
348
|
-
const pollRepetition = (text) => {
|
|
349
|
-
const insp = inspectDegenerate(text);
|
|
350
|
-
for (const s of insp.spared) {
|
|
351
|
-
const k = `${s.rule} ${s.segment}`;
|
|
352
|
-
const prev = repSpared.get(k);
|
|
353
|
-
if (prev === undefined)
|
|
354
|
-
repSpared.set(k, s);
|
|
355
|
-
else if (s.reps > prev.reps)
|
|
356
|
-
prev.reps = s.reps;
|
|
357
|
-
}
|
|
358
|
-
if (insp.degenerate)
|
|
359
|
-
repCut = insp.cut;
|
|
360
|
-
return insp.degenerate;
|
|
361
|
-
};
|
|
362
|
-
let walltimeCut = false;
|
|
363
|
-
const callDeadlineMs = options?.callDeadlineMs;
|
|
347
|
+
const rep = createRepetitionPoll();
|
|
348
|
+
const walltime = createWalltimeGate({ callDeadlineMs: options?.callDeadlineMs, isDegenerate: () => degenerate, cancel: () => ctrl.cancel() });
|
|
364
349
|
let lastDegenCheck = 0;
|
|
365
350
|
let lastDegenCheckReasoning = 0;
|
|
366
351
|
const detectRep = config.detectRepetition !== false;
|
|
@@ -389,7 +374,7 @@ export function createOpenAIBrain(config = {}) {
|
|
|
389
374
|
out.push({ type: "thinking_delta", contentIndex: 0, delta, partial: { ...partial } });
|
|
390
375
|
if (detectRep && !degenerate && accumReasoning.length - lastDegenCheckReasoning >= 64) {
|
|
391
376
|
lastDegenCheckReasoning = accumReasoning.length;
|
|
392
|
-
if (
|
|
377
|
+
if (rep.poll(accumReasoning)) {
|
|
393
378
|
degenerate = true;
|
|
394
379
|
degenFace = "reasoning";
|
|
395
380
|
ctrl.cancel();
|
|
@@ -418,7 +403,7 @@ export function createOpenAIBrain(config = {}) {
|
|
|
418
403
|
out.push({ type: "text_delta", contentIndex: textIndex, delta, partial: { ...partial } });
|
|
419
404
|
if (detectRep && !degenerate && accumText.length - lastDegenCheck >= 64) {
|
|
420
405
|
lastDegenCheck = accumText.length;
|
|
421
|
-
if (
|
|
406
|
+
if (rep.poll(accumText)) {
|
|
422
407
|
degenerate = true;
|
|
423
408
|
degenFace = "text";
|
|
424
409
|
ctrl.cancel();
|
|
@@ -438,19 +423,9 @@ export function createOpenAIBrain(config = {}) {
|
|
|
438
423
|
sealForRetry() {
|
|
439
424
|
closeThinking();
|
|
440
425
|
},
|
|
441
|
-
onDeadline()
|
|
442
|
-
if (degenerate)
|
|
443
|
-
return false;
|
|
444
|
-
walltimeCut = true;
|
|
445
|
-
return true;
|
|
446
|
-
},
|
|
426
|
+
onDeadline: () => walltime.onDeadline(),
|
|
447
427
|
onLine(rawLine) {
|
|
448
|
-
if (
|
|
449
|
-
walltimeCut = true;
|
|
450
|
-
ctrl.cancel();
|
|
451
|
-
return;
|
|
452
|
-
}
|
|
453
|
-
if (walltimeCut)
|
|
428
|
+
if (walltime.shouldDropLine())
|
|
454
429
|
return;
|
|
455
430
|
const line = rawLine.trim();
|
|
456
431
|
if (!line.startsWith("data:"))
|
|
@@ -518,7 +493,7 @@ export function createOpenAIBrain(config = {}) {
|
|
|
518
493
|
const finalContent = [];
|
|
519
494
|
if (accumReasoning)
|
|
520
495
|
finalContent.push({ type: "thinking", thinking: accumReasoning });
|
|
521
|
-
const textFace = degenerate && degenFace === "text" &&
|
|
496
|
+
const textFace = degenerate && degenFace === "text" && rep.cut !== undefined ? trimDegenerateTail(accumText, rep.cut) : accumText;
|
|
522
497
|
if (textFace)
|
|
523
498
|
finalContent.push({ type: "text", text: textFace });
|
|
524
499
|
const toolCalls = [];
|
|
@@ -564,11 +539,11 @@ export function createOpenAIBrain(config = {}) {
|
|
|
564
539
|
const dynamicCut = truncatedEmpty && options?.maxTokensDynamic === true;
|
|
565
540
|
const safetyCut = finishReason === "content_filter";
|
|
566
541
|
const refused = accumRefusal.trim().length > 0;
|
|
567
|
-
const emptyNoFinish = noUsableContent && finishReason == null && !degenerate && !
|
|
542
|
+
const emptyNoFinish = noUsableContent && finishReason == null && !degenerate && !walltime.cut;
|
|
568
543
|
const maxTokensNote = sentMaxTokens !== undefined
|
|
569
544
|
? `effective max_tokens=${sentMaxTokens} (from ${sentMaxTokensLane === "options" ? "options.maxTokens" : "model.maxTokens"})`
|
|
570
545
|
: "max_tokens not set (neither options.maxTokens nor model.maxTokens — the provider's default cap applied)";
|
|
571
|
-
const errorMessage =
|
|
546
|
+
const errorMessage = walltime.cut
|
|
572
547
|
? WALLTIME_CUTOFF_MESSAGE
|
|
573
548
|
: degenerate
|
|
574
549
|
? DEGENERATE_MESSAGE
|
|
@@ -584,14 +559,14 @@ export function createOpenAIBrain(config = {}) {
|
|
|
584
559
|
: emptyNoFinish
|
|
585
560
|
? `[stream_torn] model stream ended with no content and no finish_reason — the response was lost (a torn stream or an in-band provider error frame)`
|
|
586
561
|
: undefined));
|
|
587
|
-
const errored =
|
|
562
|
+
const errored = walltime.cut ||
|
|
588
563
|
degenerate ||
|
|
589
564
|
safetyCut ||
|
|
590
565
|
refused ||
|
|
591
566
|
emptyNoFinish ||
|
|
592
567
|
(toolError !== undefined && noUsableContent) ||
|
|
593
568
|
(truncatedEmpty && !dynamicCut);
|
|
594
|
-
const errorKind = !
|
|
569
|
+
const errorKind = !walltime.cut && !degenerate && !safetyCut && !refused && toolError === undefined && truncatedEmpty && !dynamicCut
|
|
595
570
|
? "length_empty"
|
|
596
571
|
: undefined;
|
|
597
572
|
const finalMessage = {
|
|
@@ -603,8 +578,8 @@ export function createOpenAIBrain(config = {}) {
|
|
|
603
578
|
timestamp: Date.now(),
|
|
604
579
|
...(errorMessage ? { errorMessage } : {}),
|
|
605
580
|
...(errorKind ? { errorKind } : {}),
|
|
606
|
-
...(
|
|
607
|
-
? { repetition: { ...(
|
|
581
|
+
...(rep.cut !== undefined || rep.spared.length > 0
|
|
582
|
+
? { repetition: { ...(rep.cut !== undefined ? { cut: rep.cut } : {}), ...(rep.spared.length > 0 ? { spared: rep.spared } : {}) } }
|
|
608
583
|
: {}),
|
|
609
584
|
};
|
|
610
585
|
if (errored) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ThinkingLevel } from "../internal/harness.js";
|
|
1
|
+
import type { ThinkingLevel } from "../internal/harness-types.js";
|
|
2
2
|
export type ReasoningIntensity = ThinkingLevel;
|
|
3
3
|
export declare function isThinkingLevel(v: unknown): v is ThinkingLevel;
|
|
4
4
|
export declare function rankOf(level: ThinkingLevel): number;
|
|
@@ -2,7 +2,7 @@ import { createAssistantMessageEventStream, } from "../internal/llm.js";
|
|
|
2
2
|
import { BrainError, classifyHttp } from "./errors.js";
|
|
3
3
|
import { retryBackoffMs } from "./retry.js";
|
|
4
4
|
import { emitBrainStatus, emitBrainTelemetry } from "./status-sink.js";
|
|
5
|
-
import {
|
|
5
|
+
import { createConnectController } from "./timeout.js";
|
|
6
6
|
import { WALLTIME_CUTOFF_MESSAGE } from "./walltime.js";
|
|
7
7
|
const EMPTY_USAGE = {
|
|
8
8
|
input: 0,
|
|
@@ -80,7 +80,7 @@ export function runStreamingBrain(args) {
|
|
|
80
80
|
if (callDeadlineMs !== undefined && Date.now() >= callDeadlineMs) {
|
|
81
81
|
throw new Error(WALLTIME_CUTOFF_MESSAGE);
|
|
82
82
|
}
|
|
83
|
-
const cc =
|
|
83
|
+
const cc = createConnectController(connectTimeoutMs, signal, callDeadlineMs);
|
|
84
84
|
let r;
|
|
85
85
|
let netErr;
|
|
86
86
|
try {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type RepetitionEvent } from "./repetition.js";
|
|
2
|
+
export interface RepetitionPoll {
|
|
3
|
+
poll(text: string): boolean;
|
|
4
|
+
readonly cut: RepetitionEvent | undefined;
|
|
5
|
+
readonly spared: RepetitionEvent[];
|
|
6
|
+
}
|
|
7
|
+
export declare function createRepetitionPoll(): RepetitionPoll;
|
|
8
|
+
export interface WalltimeGate {
|
|
9
|
+
onDeadline(): boolean;
|
|
10
|
+
shouldDropLine(): boolean;
|
|
11
|
+
readonly cut: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function createWalltimeGate(deps: {
|
|
14
|
+
callDeadlineMs: number | undefined;
|
|
15
|
+
isDegenerate: () => boolean;
|
|
16
|
+
cancel: () => void;
|
|
17
|
+
}): WalltimeGate;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { inspectDegenerate } from "./repetition.js";
|
|
2
|
+
export function createRepetitionPoll() {
|
|
3
|
+
let repCut;
|
|
4
|
+
const repSpared = new Map();
|
|
5
|
+
return {
|
|
6
|
+
get cut() {
|
|
7
|
+
return repCut;
|
|
8
|
+
},
|
|
9
|
+
get spared() {
|
|
10
|
+
return [...repSpared.values()];
|
|
11
|
+
},
|
|
12
|
+
poll(text) {
|
|
13
|
+
const insp = inspectDegenerate(text);
|
|
14
|
+
for (const s of insp.spared) {
|
|
15
|
+
const k = `${s.rule} ${s.segment}`;
|
|
16
|
+
const prev = repSpared.get(k);
|
|
17
|
+
if (prev === undefined)
|
|
18
|
+
repSpared.set(k, s);
|
|
19
|
+
else if (s.reps > prev.reps)
|
|
20
|
+
prev.reps = s.reps;
|
|
21
|
+
}
|
|
22
|
+
if (insp.degenerate)
|
|
23
|
+
repCut = insp.cut;
|
|
24
|
+
return insp.degenerate;
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export function createWalltimeGate(deps) {
|
|
29
|
+
const { callDeadlineMs, isDegenerate, cancel } = deps;
|
|
30
|
+
let walltimeCut = false;
|
|
31
|
+
return {
|
|
32
|
+
get cut() {
|
|
33
|
+
return walltimeCut;
|
|
34
|
+
},
|
|
35
|
+
onDeadline() {
|
|
36
|
+
if (isDegenerate())
|
|
37
|
+
return false;
|
|
38
|
+
walltimeCut = true;
|
|
39
|
+
return true;
|
|
40
|
+
},
|
|
41
|
+
shouldDropLine() {
|
|
42
|
+
if (callDeadlineMs !== undefined && !walltimeCut && !isDegenerate() && Date.now() >= callDeadlineMs) {
|
|
43
|
+
walltimeCut = true;
|
|
44
|
+
cancel();
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
return walltimeCut;
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
package/dist/brain/timeout.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export interface BrainTimeoutConfig {
|
|
|
3
3
|
firstTokenTimeoutMs?: number;
|
|
4
4
|
idleTimeoutMs?: number;
|
|
5
5
|
}
|
|
6
|
-
export declare function
|
|
6
|
+
export declare function createConnectController(connectTimeoutMs: number | undefined, outerSignal: AbortSignal | undefined, deadlineAtMs?: number): {
|
|
7
7
|
signal: AbortSignal;
|
|
8
8
|
timedOut: () => boolean;
|
|
9
9
|
deadlineHit: () => boolean;
|
package/dist/brain/timeout.js
CHANGED
package/dist/config/catalog.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { DEFAULT_MAX_TURNS } from "
|
|
2
|
-
import { FORK_DEFAULT_MAX_TURNS, SESSION_BG_DEFAULT_TIMEOUT_SEC, RETAIN_DEFAULT_TTL_MS, RETAIN_DEFAULT_MAX } from "../agents/subagent.js";
|
|
3
|
-
import { SESSION_DEFAULT_TTL_DAYS } from "../core/session-store.js";
|
|
1
|
+
import { DEFAULT_MAX_TURNS, FORK_DEFAULT_MAX_TURNS, SESSION_BG_DEFAULT_TIMEOUT_SEC, RETAIN_DEFAULT_TTL_MS, RETAIN_DEFAULT_MAX, SESSION_DEFAULT_TTL_DAYS } from "./defaults.js";
|
|
4
2
|
export const CONFIG_CATALOG_VERSION = "sema-config@1";
|
|
5
3
|
export function describeConfigCatalog() {
|
|
6
4
|
const knobs = [
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const DEFAULT_MAX_TURNS = 1000;
|
|
2
|
+
export declare const FORK_DEFAULT_MAX_TURNS = 200;
|
|
3
|
+
export declare const SESSION_BG_DEFAULT_TIMEOUT_SEC: number;
|
|
4
|
+
export declare const RETAIN_DEFAULT_TTL_MS: number;
|
|
5
|
+
export declare const RETAIN_DEFAULT_MAX = 16;
|
|
6
|
+
export declare const SESSION_DEFAULT_TTL_DAYS = 7;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const DEFAULT_MAX_TURNS = 1000;
|
|
2
|
+
export const FORK_DEFAULT_MAX_TURNS = 200;
|
|
3
|
+
export const SESSION_BG_DEFAULT_TIMEOUT_SEC = 30 * 60;
|
|
4
|
+
export const RETAIN_DEFAULT_TTL_MS = 30 * 60 * 1000;
|
|
5
|
+
export const RETAIN_DEFAULT_MAX = 16;
|
|
6
|
+
export const SESSION_DEFAULT_TTL_DAYS = 7;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentTool } from "../internal/harness.js";
|
|
1
|
+
import type { AgentTool } from "../internal/harness-types.js";
|
|
2
2
|
import type { ToolPolicy } from "./tool-policy.js";
|
|
3
3
|
export declare const ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion";
|
|
4
4
|
export interface AskQuestionOption {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExecutionEnv, ExecutionEnvExecOptions, Result } from "../internal/harness.js";
|
|
1
|
+
import type { ExecutionEnv, ExecutionEnvExecOptions, Result } from "../internal/harness-types.js";
|
|
2
2
|
export type BackgroundShellId = string & {
|
|
3
3
|
readonly __brand: "BackgroundShellId";
|
|
4
4
|
};
|
package/dist/core/exec-gate.d.ts
CHANGED
|
@@ -30,3 +30,4 @@ export declare function sliceStreamIncrement(s: StreamCursorState, terminal: boo
|
|
|
30
30
|
droppedBeforeCursor: number;
|
|
31
31
|
};
|
|
32
32
|
export declare function markTruncated(text: string, droppedBytes: number): string;
|
|
33
|
+
export declare function markLiveSpoolRotations(text: string, liveRotations: number): string;
|
|
@@ -73,3 +73,9 @@ export function markTruncated(text, droppedBytes) {
|
|
|
73
73
|
? `[... ${droppedBytes} earlier byte(s) truncated; showing last ${Buffer.byteLength(text, "utf8")} ...]\n${text}`
|
|
74
74
|
: text;
|
|
75
75
|
}
|
|
76
|
+
export function markLiveSpoolRotations(text, liveRotations) {
|
|
77
|
+
if (liveRotations <= 0)
|
|
78
|
+
return text;
|
|
79
|
+
const note = `[spool reclaimed ${liveRotations} time(s) while the process was still writing; bytes appended during those windows may be missing beyond any counted truncation]`;
|
|
80
|
+
return text === "" ? note : `${text}${text.endsWith("\n") ? "" : "\n"}${note}`;
|
|
81
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ExecutionEnv } from "../internal/harness.js";
|
|
1
|
+
import type { ExecutionEnv } from "../internal/harness-types.js";
|
|
2
2
|
export interface FileSnapshotError {
|
|
3
3
|
code: "too_large" | "enumerate_failed" | "read_failed" | "restore_failed" | "not_found" | "aborted";
|
|
4
4
|
message: string;
|
package/dist/core/hooks.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DocumentContent, ImageContent, TextContent } from "../internal/llm.js";
|
|
2
|
-
import type { SessionTreeEntry } from "../internal/harness.js";
|
|
2
|
+
import type { SessionTreeEntry } from "../internal/harness-types.js";
|
|
3
3
|
import type { PermissionResult, ResolvedAsk, ToolCallRequest } from "./tool-policy.js";
|
|
4
4
|
export interface Hooks {
|
|
5
5
|
preToolUse?(toolName: string, input: unknown, ctx: HookToolContext): PreToolUseResult | undefined | Promise<PreToolUseResult | undefined>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export declare const MCP_IMAGE_MAX_BASE64: number;
|
|
2
|
+
export declare const IMAGE_TARGET_RAW_SIZE: number;
|
|
3
|
+
export declare const IMAGE_MAX_WIDTH = 2000;
|
|
4
|
+
export declare const IMAGE_MAX_HEIGHT = 2000;
|
|
5
|
+
export type McpImageResizer = (base64: string, mimeType: string) => Promise<{
|
|
6
|
+
base64: string;
|
|
7
|
+
mimeType: string;
|
|
8
|
+
} | undefined>;
|
|
9
|
+
export interface ImageDimensions {
|
|
10
|
+
originalWidth: number;
|
|
11
|
+
originalHeight: number;
|
|
12
|
+
displayWidth: number;
|
|
13
|
+
displayHeight: number;
|
|
14
|
+
}
|
|
15
|
+
export interface DownsampledImage {
|
|
16
|
+
base64: string;
|
|
17
|
+
mimeType: string;
|
|
18
|
+
dimensions?: ImageDimensions;
|
|
19
|
+
}
|
|
20
|
+
export type ImageDownsampler = (input: Buffer, mimeType: string) => Promise<DownsampledImage | undefined>;
|
|
21
|
+
type SharpFactory = (input: Buffer) => SharpOps;
|
|
22
|
+
interface SharpOps {
|
|
23
|
+
metadata: () => Promise<{
|
|
24
|
+
width?: number;
|
|
25
|
+
height?: number;
|
|
26
|
+
format?: string;
|
|
27
|
+
}>;
|
|
28
|
+
resize: (w: number, h: number, o: {
|
|
29
|
+
fit: "inside";
|
|
30
|
+
withoutEnlargement: boolean;
|
|
31
|
+
}) => SharpOps;
|
|
32
|
+
jpeg: (o: {
|
|
33
|
+
quality: number;
|
|
34
|
+
}) => SharpOps;
|
|
35
|
+
png: (o: {
|
|
36
|
+
compressionLevel: number;
|
|
37
|
+
palette: boolean;
|
|
38
|
+
}) => SharpOps;
|
|
39
|
+
toBuffer: () => Promise<Buffer>;
|
|
40
|
+
}
|
|
41
|
+
export declare function createImageDownsampler(sharp: SharpFactory): ImageDownsampler;
|
|
42
|
+
export declare function sharpImageDownsampler(): Promise<ImageDownsampler | undefined>;
|
|
43
|
+
export declare function sharpImageResizer(): Promise<McpImageResizer | undefined>;
|
|
44
|
+
export {};
|