scream-code 0.16.9 → 0.17.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.
- package/dist/{app-BJSym649.mjs → app-BL4emsvp.mjs} +9 -9
- package/dist/{dispatch-ChbwC2I5.mjs → dispatch-DXj2tzeV.mjs} +1 -1
- package/dist/{dispatch-CIOuINvn.mjs → dispatch-IFcnZsGX.mjs} +251 -176
- package/dist/main.mjs +1 -1
- package/dist/{markit-DG5XsAGz.mjs → markit-Dga2W6G6.mjs} +9 -9
- package/dist/public/assets/{index-DMGV8LA-.js → index-CKa_o5qA.js} +2 -2
- package/dist/public/assets/{index-DMGV8LA-.js.map → index-CKa_o5qA.js.map} +1 -1
- package/dist/public/assets/{index-DdPmkwIL.css → index-CVXe8l3P.css} +1 -1
- package/dist/public/index.html +2 -2
- package/package.json +2 -2
|
@@ -78,6 +78,7 @@ const ErrorCodes = {
|
|
|
78
78
|
SESSION_FORK_ACTIVE_TURN: "session.fork_active_turn",
|
|
79
79
|
SESSION_EXPORT_NOT_FOUND: "session.export_not_found",
|
|
80
80
|
SESSION_EXPORT_MISSING_VERSION: "session.export_missing_version",
|
|
81
|
+
SESSION_DELETE_FAILED: "session.delete_failed",
|
|
81
82
|
SESSION_CLOSED: "session.closed",
|
|
82
83
|
SESSION_PERMISSION_MODE_INVALID: "session.permission_mode_invalid",
|
|
83
84
|
SESSION_THINKING_EMPTY: "session.thinking_empty",
|
|
@@ -201,6 +202,12 @@ const SCREAM_ERROR_INFO = {
|
|
|
201
202
|
public: true,
|
|
202
203
|
action: "Provide a version when exporting the session."
|
|
203
204
|
},
|
|
205
|
+
"session.delete_failed": {
|
|
206
|
+
title: "Failed to delete session",
|
|
207
|
+
retryable: true,
|
|
208
|
+
public: true,
|
|
209
|
+
action: "Close programs holding files in the session directory (editors, dev servers) and retry."
|
|
210
|
+
},
|
|
204
211
|
"session.closed": {
|
|
205
212
|
title: "Session is closed",
|
|
206
213
|
retryable: false,
|
|
@@ -46194,15 +46201,15 @@ function catalogProviderModels(entry) {
|
|
|
46194
46201
|
/**
|
|
46195
46202
|
* Idle-stream watchdog.
|
|
46196
46203
|
*
|
|
46197
|
-
* Ported from oh-my-pi `packages/ai/src/utils/idle-iterator.ts:154-382`.
|
|
46198
46204
|
* Reasoning models (deepseek-reasoner, mimo thinking) can sit silent for
|
|
46199
46205
|
* 30s+ between tokens; without a watchdog the stream hangs forever and the
|
|
46200
46206
|
* user thinks the agent died. This wraps any async iterable with a per-item
|
|
46201
46207
|
* idle deadline, turning a stalled stream into a retryable `APITimeoutError`.
|
|
46202
46208
|
*
|
|
46203
|
-
*
|
|
46204
|
-
*
|
|
46205
|
-
*
|
|
46209
|
+
* Deliberately narrow: no pre-response arming, no terminal grace iteration and
|
|
46210
|
+
* no per-provider env-var aliases. The core design — reuse one racer promise
|
|
46211
|
+
* across iterations (re-minted every 1024 races to bound retention) and
|
|
46212
|
+
* self-rearm a single timer per item — is all this needs.
|
|
46206
46213
|
*/
|
|
46207
46214
|
const DEFAULT_STREAM_IDLE_TIMEOUT_MS = 6e4;
|
|
46208
46215
|
const DEFAULT_STREAM_FIRST_ITEM_TIMEOUT_MS = 12e4;
|
|
@@ -46811,6 +46818,33 @@ function extractError(value) {
|
|
|
46811
46818
|
} : { message: value.message };
|
|
46812
46819
|
}
|
|
46813
46820
|
//#endregion
|
|
46821
|
+
//#region ../../node_modules/.pnpm/@antfu+utils@9.3.0/node_modules/@antfu/utils/dist/index.mjs
|
|
46822
|
+
function uniq(array) {
|
|
46823
|
+
return Array.from(new Set(array));
|
|
46824
|
+
}
|
|
46825
|
+
function notNullish(v) {
|
|
46826
|
+
return v != null;
|
|
46827
|
+
}
|
|
46828
|
+
function objectMap(obj, fn) {
|
|
46829
|
+
return Object.fromEntries(Object.entries(obj).map(([k, v]) => fn(k, v)).filter(notNullish));
|
|
46830
|
+
}
|
|
46831
|
+
function sleep$2(ms, callback) {
|
|
46832
|
+
return new Promise((resolve) => setTimeout(async () => {
|
|
46833
|
+
await callback?.();
|
|
46834
|
+
resolve();
|
|
46835
|
+
}, ms));
|
|
46836
|
+
}
|
|
46837
|
+
function createControlledPromise() {
|
|
46838
|
+
let resolve, reject;
|
|
46839
|
+
const promise = new Promise((_resolve, _reject) => {
|
|
46840
|
+
resolve = _resolve;
|
|
46841
|
+
reject = _reject;
|
|
46842
|
+
});
|
|
46843
|
+
promise.resolve = resolve;
|
|
46844
|
+
promise.reject = reject;
|
|
46845
|
+
return promise;
|
|
46846
|
+
}
|
|
46847
|
+
//#endregion
|
|
46814
46848
|
//#region ../../packages/agent-core/src/utils/fs.ts
|
|
46815
46849
|
/**
|
|
46816
46850
|
* Low-level POSIX durability primitives.
|
|
@@ -46911,6 +46945,50 @@ async function atomicWrite(filePath, content, _syncOverride) {
|
|
|
46911
46945
|
} catch {}
|
|
46912
46946
|
}
|
|
46913
46947
|
}
|
|
46948
|
+
/**
|
|
46949
|
+
* Error codes that indicate a *transient* removal failure: another handle
|
|
46950
|
+
* holds the file or a parent directory right now (Windows keeps files
|
|
46951
|
+
* exclusively locked by editors, indexers, dev servers and virus scanners;
|
|
46952
|
+
* POSIX sees the same from racing deletions). Retrying with a short backoff
|
|
46953
|
+
* turns the common "lock released within a second" case into a success while
|
|
46954
|
+
* a genuinely stuck path still surfaces as an error after the budget.
|
|
46955
|
+
*/
|
|
46956
|
+
const RM_RETRY_CODES = new Set([
|
|
46957
|
+
"EBUSY",
|
|
46958
|
+
"EPERM",
|
|
46959
|
+
"ENOTEMPTY",
|
|
46960
|
+
"EMFILE",
|
|
46961
|
+
"EACCES"
|
|
46962
|
+
]);
|
|
46963
|
+
const RM_RETRY_BACKOFF_MS = [
|
|
46964
|
+
50,
|
|
46965
|
+
150,
|
|
46966
|
+
400,
|
|
46967
|
+
1e3
|
|
46968
|
+
];
|
|
46969
|
+
/**
|
|
46970
|
+
* rm -rf with bounded retries on transient OS locks. Throws the last error
|
|
46971
|
+
* when every attempt fails, and never retries codes outside the transient
|
|
46972
|
+
* set. `rmOverride` is a fault-injection seam (same convention as
|
|
46973
|
+
* `atomicWrite`'s `_syncOverride`); production callers must never supply it.
|
|
46974
|
+
*/
|
|
46975
|
+
async function rmWithRetry(target, opts = {}) {
|
|
46976
|
+
const rmImpl = opts.rmOverride ?? rm;
|
|
46977
|
+
const backoff = opts.backoffMs ?? RM_RETRY_BACKOFF_MS;
|
|
46978
|
+
const attempts = opts.attempts ?? backoff.length + 1;
|
|
46979
|
+
for (let attempt = 1;; attempt += 1) try {
|
|
46980
|
+
await rmImpl(target, {
|
|
46981
|
+
recursive: true,
|
|
46982
|
+
force: true
|
|
46983
|
+
});
|
|
46984
|
+
return;
|
|
46985
|
+
} catch (error) {
|
|
46986
|
+
const code = error.code;
|
|
46987
|
+
const backoffMs = backoff[attempt - 1];
|
|
46988
|
+
if (attempt >= attempts || backoffMs === void 0 || code === void 0 || !RM_RETRY_CODES.has(code)) throw error;
|
|
46989
|
+
await sleep$2(backoffMs);
|
|
46990
|
+
}
|
|
46991
|
+
}
|
|
46914
46992
|
//#endregion
|
|
46915
46993
|
//#region ../../packages/agent-core/src/logging/sinks.ts
|
|
46916
46994
|
const PENDING_MAX = 1e3;
|
|
@@ -47431,33 +47509,6 @@ function ensureScreamHome(homeDir) {
|
|
|
47431
47509
|
});
|
|
47432
47510
|
}
|
|
47433
47511
|
//#endregion
|
|
47434
|
-
//#region ../../node_modules/.pnpm/@antfu+utils@9.3.0/node_modules/@antfu/utils/dist/index.mjs
|
|
47435
|
-
function uniq(array) {
|
|
47436
|
-
return Array.from(new Set(array));
|
|
47437
|
-
}
|
|
47438
|
-
function notNullish(v) {
|
|
47439
|
-
return v != null;
|
|
47440
|
-
}
|
|
47441
|
-
function objectMap(obj, fn) {
|
|
47442
|
-
return Object.fromEntries(Object.entries(obj).map(([k, v]) => fn(k, v)).filter(notNullish));
|
|
47443
|
-
}
|
|
47444
|
-
function sleep$2(ms, callback) {
|
|
47445
|
-
return new Promise((resolve) => setTimeout(async () => {
|
|
47446
|
-
await callback?.();
|
|
47447
|
-
resolve();
|
|
47448
|
-
}, ms));
|
|
47449
|
-
}
|
|
47450
|
-
function createControlledPromise() {
|
|
47451
|
-
let resolve, reject;
|
|
47452
|
-
const promise = new Promise((_resolve, _reject) => {
|
|
47453
|
-
resolve = _resolve;
|
|
47454
|
-
reject = _reject;
|
|
47455
|
-
});
|
|
47456
|
-
promise.resolve = resolve;
|
|
47457
|
-
promise.reject = reject;
|
|
47458
|
-
return promise;
|
|
47459
|
-
}
|
|
47460
|
-
//#endregion
|
|
47461
47512
|
//#region ../../packages/agent-core/src/utils/abort.ts
|
|
47462
47513
|
function abortError() {
|
|
47463
47514
|
const error = /* @__PURE__ */ new Error("Aborted");
|
|
@@ -47524,6 +47575,15 @@ function createMaxStepsExceededError(maxSteps, message) {
|
|
|
47524
47575
|
function isMaxStepsExceededError(error) {
|
|
47525
47576
|
return isScreamError(error) && error.code === ErrorCodes.LOOP_MAX_STEPS_EXCEEDED;
|
|
47526
47577
|
}
|
|
47578
|
+
/**
|
|
47579
|
+
* Context-window overflow, in both shapes it reaches the loop: the ltod error
|
|
47580
|
+
* class thrown by provider adapters, and the `ScreamError(CONTEXT_OVERFLOW)`
|
|
47581
|
+
* wrap produced by non-ltod adapters. Both need compaction, never a retry, so
|
|
47582
|
+
* retry.ts and the turn-level overflow handler must agree on this predicate.
|
|
47583
|
+
*/
|
|
47584
|
+
function isContextOverflowError(error) {
|
|
47585
|
+
return error instanceof APIContextOverflowError || isScreamError(error) && error.code === ErrorCodes.CONTEXT_OVERFLOW;
|
|
47586
|
+
}
|
|
47527
47587
|
function isAbortError$1(err) {
|
|
47528
47588
|
if (err instanceof Error) return err.name === "AbortError";
|
|
47529
47589
|
return false;
|
|
@@ -47551,7 +47611,7 @@ async function chatWithRetry(input) {
|
|
|
47551
47611
|
for (let attempt = 1;; attempt += 1) try {
|
|
47552
47612
|
return await input.llm.chat(paramsForAttempt(input, attempt, maxAttempts));
|
|
47553
47613
|
} catch (error) {
|
|
47554
|
-
if (error
|
|
47614
|
+
if (isContextOverflowError(error)) {
|
|
47555
47615
|
logRequestFailure(input, error, attempt, maxAttempts);
|
|
47556
47616
|
throw error;
|
|
47557
47617
|
}
|
|
@@ -52335,9 +52395,8 @@ var AgentTool = class {
|
|
|
52335
52395
|
* When `timeoutMs` is set and background dispatch is available, the wait is
|
|
52336
52396
|
* bounded by a race: if the child has not finished by the deadline it is
|
|
52337
52397
|
* handed to the background task manager (never aborted) and the caller
|
|
52338
|
-
* receives a `backgrounded` outcome carrying the task id.
|
|
52339
|
-
*
|
|
52340
|
-
* a timeout degrades the wait, it does not destroy the subagent's work.
|
|
52398
|
+
* receives a `backgrounded` outcome carrying the task id. A timeout degrades
|
|
52399
|
+
* the wait; it does not destroy the subagent's work.
|
|
52341
52400
|
*/
|
|
52342
52401
|
async awaitForegroundCompletion(handle, description, timeoutMs, childController, unlinkChild) {
|
|
52343
52402
|
if (timeoutMs === void 0 || !this.allowBackground || this.backgroundManager === void 0) return {
|
|
@@ -53080,11 +53139,10 @@ function formatTokens$2(tokens) {
|
|
|
53080
53139
|
* context on every submission. This wastes context budget and can trap the
|
|
53081
53140
|
* agent in a loop where it keeps retrying without new information.
|
|
53082
53141
|
*
|
|
53083
|
-
*
|
|
53084
|
-
*
|
|
53085
|
-
*
|
|
53086
|
-
*
|
|
53087
|
-
* deduplication keyed by goal objective.
|
|
53142
|
+
* Scope is set by this codebase's grader model: the grader is called once per
|
|
53143
|
+
* `complete` submission (not continuously), so per-round limiting is
|
|
53144
|
+
* unnecessary. The guard focuses on normalization, content-free filtering,
|
|
53145
|
+
* and exact-text deduplication keyed by goal objective.
|
|
53088
53146
|
*/
|
|
53089
53147
|
/** Short phrases that carry no actionable feedback. */
|
|
53090
53148
|
const CONTENT_FREE_PHRASES = new Set([
|
|
@@ -68401,7 +68459,7 @@ const scanCache = new FsScanCache();
|
|
|
68401
68459
|
* and, when found, appends a notice to the read result so the model does not
|
|
68402
68460
|
* silently edit a file with unresolved conflicts.
|
|
68403
68461
|
*
|
|
68404
|
-
* Marker shape is strict
|
|
68462
|
+
* Marker shape is strict:
|
|
68405
68463
|
* prefix alone, or prefix + single space + label. Lines that merely start
|
|
68406
68464
|
* with `<` or `=` never match. Only fully-closed blocks (opener + separator
|
|
68407
68465
|
* + closer all present in the scanned window) are reported — an open block
|
|
@@ -84389,6 +84447,10 @@ var AutoModeAskUserQuestionDenyPermissionPolicy = class {
|
|
|
84389
84447
|
* unattended in bot mode): reads, in-workspace edits, lookups, planning,
|
|
84390
84448
|
* coordination requests. Everything outside this allowlist is denied in bot
|
|
84391
84449
|
* mode (fail-closed) — no ask prompt can reach a human who is not there.
|
|
84450
|
+
*
|
|
84451
|
+
* This list is intentionally separate from `#/tools/tool-catalog`: bot mode
|
|
84452
|
+
* answers "what is reversible unattended", not "what is read-only /
|
|
84453
|
+
* executable", so the two classifications must not be merged.
|
|
84392
84454
|
*/
|
|
84393
84455
|
const REVERSIBLE_TOOLS = new Set([
|
|
84394
84456
|
"Read",
|
|
@@ -84491,36 +84553,105 @@ var BotModePermissionPolicy = class BotModePermissionPolicy {
|
|
|
84491
84553
|
}
|
|
84492
84554
|
};
|
|
84493
84555
|
//#endregion
|
|
84556
|
+
//#region ../../packages/agent-core/src/tools/tool-catalog.ts
|
|
84557
|
+
/**
|
|
84558
|
+
* Single catalog of builtin-tool name sets shared by permission and
|
|
84559
|
+
* capability policies. When adding a tool, classify it here once: the
|
|
84560
|
+
* subagent capability filter and the default-approve policy both read from
|
|
84561
|
+
* this file, so no list has to be synced by hand in two places.
|
|
84562
|
+
*
|
|
84563
|
+
* `DEFAULT_AUTO_APPROVE_TOOLS` is copied verbatim from the former per-file
|
|
84564
|
+
* record (including its legacy `SetTodoList` entry) so behavior is
|
|
84565
|
+
* unchanged; the sets are intentionally not re-derived from tool
|
|
84566
|
+
* definitions.
|
|
84567
|
+
*/
|
|
84568
|
+
/** Read-only inspection tools (no workspace mutation, no command execution). */
|
|
84569
|
+
const READ_TOOLS = new Set([
|
|
84570
|
+
"AskUserQuestion",
|
|
84571
|
+
"ContactParent",
|
|
84572
|
+
"FetchURL",
|
|
84573
|
+
"Glob",
|
|
84574
|
+
"Grep",
|
|
84575
|
+
"KnowledgeLookup",
|
|
84576
|
+
"LSP",
|
|
84577
|
+
"MemoryLookup",
|
|
84578
|
+
"Read",
|
|
84579
|
+
"ReadGroup",
|
|
84580
|
+
"ReadMediaFile",
|
|
84581
|
+
"ReportFinding",
|
|
84582
|
+
"Skill",
|
|
84583
|
+
"TodoList",
|
|
84584
|
+
"WebSearch"
|
|
84585
|
+
]);
|
|
84586
|
+
/** Tools that mutate the workspace (files, memory, plans, skills). */
|
|
84587
|
+
const WRITE_TOOLS = new Set([
|
|
84588
|
+
"Edit",
|
|
84589
|
+
"InspectOwnAssets",
|
|
84590
|
+
"MakeSkillApply",
|
|
84591
|
+
"MakeSkillPlan",
|
|
84592
|
+
"ManagePlugin",
|
|
84593
|
+
"MemoryEdit",
|
|
84594
|
+
"MemoryWrite",
|
|
84595
|
+
"Write"
|
|
84596
|
+
]);
|
|
84597
|
+
/** Tools that execute commands. */
|
|
84598
|
+
const EXECUTE_TOOLS = new Set(["Bash", "python"]);
|
|
84599
|
+
/** Nesting/coordination tools — only `all` mode keeps them. A restricted
|
|
84600
|
+
* child must not be able to spawn an unrestricted grandchild (that would
|
|
84601
|
+
* bypass the tool filtering entirely). WolfPack is batch-spawn sugar over
|
|
84602
|
+
* the same subagent host, so it is filtered too. */
|
|
84603
|
+
const NESTING_TOOLS = new Set([
|
|
84604
|
+
"Agent",
|
|
84605
|
+
"SendSubagentMessage",
|
|
84606
|
+
"WolfPack"
|
|
84607
|
+
]);
|
|
84608
|
+
/** Goal/session-management tools, always available regardless of mode. */
|
|
84609
|
+
const CORE_TOOLS = new Set([
|
|
84610
|
+
"CreateGoal",
|
|
84611
|
+
"GetGoal",
|
|
84612
|
+
"SetGoalBudget",
|
|
84613
|
+
"UpdateGoal",
|
|
84614
|
+
"WriteGoalNote",
|
|
84615
|
+
"EnterPlanMode",
|
|
84616
|
+
"ExitPlanMode"
|
|
84617
|
+
]);
|
|
84618
|
+
/**
|
|
84619
|
+
* Tools auto-approved without asking in manual mode, verbatim from the
|
|
84620
|
+
* former default-tool-approve record. `SetTodoList` is a legacy name kept
|
|
84621
|
+
* as-is: no current tool declares it, and removing it would be a behavior
|
|
84622
|
+
* change rather than a refactor.
|
|
84623
|
+
*/
|
|
84624
|
+
const DEFAULT_AUTO_APPROVE_TOOLS = new Set([
|
|
84625
|
+
"Read",
|
|
84626
|
+
"Grep",
|
|
84627
|
+
"Glob",
|
|
84628
|
+
"ReadMediaFile",
|
|
84629
|
+
"InspectOwnAssets",
|
|
84630
|
+
"SetTodoList",
|
|
84631
|
+
"TodoList",
|
|
84632
|
+
"TaskList",
|
|
84633
|
+
"TaskOutput",
|
|
84634
|
+
"CronList",
|
|
84635
|
+
"WebSearch",
|
|
84636
|
+
"FetchURL",
|
|
84637
|
+
"Agent",
|
|
84638
|
+
"AskUserQuestion",
|
|
84639
|
+
"Skill",
|
|
84640
|
+
"WolfPack",
|
|
84641
|
+
"CreateGoal",
|
|
84642
|
+
"UpdateGoal",
|
|
84643
|
+
"GetGoal",
|
|
84644
|
+
"SetGoalBudget",
|
|
84645
|
+
"WriteGoalNote",
|
|
84646
|
+
"MakeSkillPlan",
|
|
84647
|
+
"MakeSkillApply"
|
|
84648
|
+
]);
|
|
84649
|
+
//#endregion
|
|
84494
84650
|
//#region ../../packages/agent-core/src/agent/permission/policies/default-tool-approve.ts
|
|
84495
|
-
const DEFAULT_APPROVE_TOOLS = {
|
|
84496
|
-
Read: true,
|
|
84497
|
-
Grep: true,
|
|
84498
|
-
Glob: true,
|
|
84499
|
-
ReadMediaFile: true,
|
|
84500
|
-
InspectOwnAssets: true,
|
|
84501
|
-
SetTodoList: true,
|
|
84502
|
-
TodoList: true,
|
|
84503
|
-
TaskList: true,
|
|
84504
|
-
TaskOutput: true,
|
|
84505
|
-
CronList: true,
|
|
84506
|
-
WebSearch: true,
|
|
84507
|
-
FetchURL: true,
|
|
84508
|
-
Agent: true,
|
|
84509
|
-
AskUserQuestion: true,
|
|
84510
|
-
Skill: true,
|
|
84511
|
-
WolfPack: true,
|
|
84512
|
-
CreateGoal: true,
|
|
84513
|
-
UpdateGoal: true,
|
|
84514
|
-
GetGoal: true,
|
|
84515
|
-
SetGoalBudget: true,
|
|
84516
|
-
WriteGoalNote: true,
|
|
84517
|
-
MakeSkillPlan: true,
|
|
84518
|
-
MakeSkillApply: true
|
|
84519
|
-
};
|
|
84520
84651
|
var DefaultToolApprovePermissionPolicy = class {
|
|
84521
84652
|
name = "default-tool-approve";
|
|
84522
84653
|
evaluate(context) {
|
|
84523
|
-
if (!
|
|
84654
|
+
if (!DEFAULT_AUTO_APPROVE_TOOLS.has(context.toolCall.name)) return;
|
|
84524
84655
|
return { kind: "approve" };
|
|
84525
84656
|
}
|
|
84526
84657
|
};
|
|
@@ -85254,6 +85385,7 @@ var PermissionManager = class {
|
|
|
85254
85385
|
let response;
|
|
85255
85386
|
if (this.agent.rpc?.requestApproval) {
|
|
85256
85387
|
const approvalId = `approval-${String(++this.nextApprovalId)}`;
|
|
85388
|
+
let timeoutHandle;
|
|
85257
85389
|
try {
|
|
85258
85390
|
const customPromise = new Promise((resolve, reject) => {
|
|
85259
85391
|
this.pendingApprovals.set(approvalId, {
|
|
@@ -85276,7 +85408,7 @@ var PermissionManager = class {
|
|
|
85276
85408
|
}, { signal }).then(resolve, reject);
|
|
85277
85409
|
});
|
|
85278
85410
|
const timeoutPromise = new Promise((_, reject) => {
|
|
85279
|
-
setTimeout(() => {
|
|
85411
|
+
timeoutHandle = setTimeout(() => {
|
|
85280
85412
|
reject(/* @__PURE__ */ new Error(`Approval request timed out after ${String(APPROVAL_TIMEOUT_MS)}ms`));
|
|
85281
85413
|
}, APPROVAL_TIMEOUT_MS);
|
|
85282
85414
|
});
|
|
@@ -85286,6 +85418,7 @@ var PermissionManager = class {
|
|
|
85286
85418
|
const resolved = result.resolveError?.(error);
|
|
85287
85419
|
return await (resolved === void 0 ? Promise.reject(error) : this.permissionPolicyResolutionToPrepare(resolved, context, policyName));
|
|
85288
85420
|
} finally {
|
|
85421
|
+
if (timeoutHandle !== void 0) clearTimeout(timeoutHandle);
|
|
85289
85422
|
this.pendingApprovals.delete(approvalId);
|
|
85290
85423
|
}
|
|
85291
85424
|
} else response = {
|
|
@@ -95189,7 +95322,6 @@ function abortedToolOutput(toolName, signal) {
|
|
|
95189
95322
|
if (isUserCancellation(signal.reason)) return `The user manually interrupted "${toolName}" (and anything else running at the same time). This was a deliberate user action, not a system error, timeout, or capacity limit. Do not retry automatically or guess at the cause — wait for the user's next instruction.`;
|
|
95190
95323
|
return `Tool "${toolName}" was aborted`;
|
|
95191
95324
|
}
|
|
95192
|
-
const executedToolCallBlockIndex = /* @__PURE__ */ new Map();
|
|
95193
95325
|
/**
|
|
95194
95326
|
* Record tool calls that arrived in a truncated response (max_tokens,
|
|
95195
95327
|
* paused, unknown) but were never executed. Each call gets a `tool.call`
|
|
@@ -95781,8 +95913,7 @@ function makeErrorToolResult(call, args, output) {
|
|
|
95781
95913
|
*/
|
|
95782
95914
|
async function dispatchToolCall(step, call, args, displayFields) {
|
|
95783
95915
|
const { toolCall, toolName } = call;
|
|
95784
|
-
const index =
|
|
95785
|
-
executedToolCallBlockIndex.set(step.stepUuid, index + 1);
|
|
95916
|
+
const index = step.toolCallBlockIndex.value++;
|
|
95786
95917
|
await step.dispatchEvent({
|
|
95787
95918
|
type: "block.start",
|
|
95788
95919
|
uuid: randomUUID(),
|
|
@@ -95850,7 +95981,8 @@ async function executeLoopStep(deps) {
|
|
|
95850
95981
|
turnId,
|
|
95851
95982
|
currentStep,
|
|
95852
95983
|
stepUuid,
|
|
95853
|
-
hasPendingSteer: deps.hasPendingSteer
|
|
95984
|
+
hasPendingSteer: deps.hasPendingSteer,
|
|
95985
|
+
toolCallBlockIndex: { value: 0 }
|
|
95854
95986
|
};
|
|
95855
95987
|
await dispatchEvent({
|
|
95856
95988
|
type: "step.begin",
|
|
@@ -102654,7 +102786,7 @@ var TurnFlow = class {
|
|
|
102654
102786
|
}
|
|
102655
102787
|
})).stopReason;
|
|
102656
102788
|
} catch (error) {
|
|
102657
|
-
if (
|
|
102789
|
+
if (isContextOverflowError(error)) {
|
|
102658
102790
|
await this.agent.fullCompaction.handleOverflowError(signal, error);
|
|
102659
102791
|
continue;
|
|
102660
102792
|
}
|
|
@@ -102752,19 +102884,17 @@ function parseEnvBudget(raw) {
|
|
|
102752
102884
|
/**
|
|
102753
102885
|
* Compute the effective `max_completion_tokens` cap.
|
|
102754
102886
|
*
|
|
102755
|
-
*
|
|
102756
|
-
*
|
|
102757
|
-
*
|
|
102758
|
-
*
|
|
102759
|
-
*
|
|
102760
|
-
*
|
|
102761
|
-
*
|
|
102762
|
-
* sessions.
|
|
102887
|
+
* Use a reasonable output-token cap rather than the full context window:
|
|
102888
|
+
* `max_context_tokens` is the total (input + output) budget, not the
|
|
102889
|
+
* output-only budget. Using it as max_tokens tells the API "generate up to
|
|
102890
|
+
* 128K output tokens", which is incorrect - the actual max output is much
|
|
102891
|
+
* smaller. The API server clamps it to context_window - input_tokens, which
|
|
102892
|
+
* shrinks as context grows, causing "max_tokens limit - no tool call" errors
|
|
102893
|
+
* on long sessions.
|
|
102763
102894
|
*
|
|
102764
|
-
* The 64K cap
|
|
102765
|
-
*
|
|
102766
|
-
*
|
|
102767
|
-
* value from being used directly.
|
|
102895
|
+
* The 64K cap is well above any current model's real output limit (typically
|
|
102896
|
+
* 8K-32K), so it never artificially limits output while preventing the
|
|
102897
|
+
* context-window value from being used directly.
|
|
102768
102898
|
*/
|
|
102769
102899
|
const OUTPUT_TOKEN_CAP = 64e3;
|
|
102770
102900
|
function computeCompletionBudgetCap(args) {
|
|
@@ -108195,56 +108325,25 @@ function buildSubagentMessage(fromAgentId, toAgentId, operation, text, overrides
|
|
|
108195
108325
|
}
|
|
108196
108326
|
//#endregion
|
|
108197
108327
|
//#region ../../packages/agent-core/src/session/subagent-capability.ts
|
|
108198
|
-
/**
|
|
108199
|
-
|
|
108200
|
-
|
|
108201
|
-
|
|
108202
|
-
|
|
108203
|
-
|
|
108204
|
-
|
|
108205
|
-
|
|
108206
|
-
|
|
108207
|
-
|
|
108208
|
-
|
|
108209
|
-
|
|
108210
|
-
|
|
108211
|
-
|
|
108212
|
-
|
|
108213
|
-
|
|
108214
|
-
|
|
108215
|
-
|
|
108216
|
-
|
|
108217
|
-
const WRITE_TOOLS = new Set([
|
|
108218
|
-
"Edit",
|
|
108219
|
-
"InspectOwnAssets",
|
|
108220
|
-
"MakeSkillApply",
|
|
108221
|
-
"MakeSkillPlan",
|
|
108222
|
-
"ManagePlugin",
|
|
108223
|
-
"MemoryEdit",
|
|
108224
|
-
"MemoryWrite",
|
|
108225
|
-
"Write"
|
|
108226
|
-
]);
|
|
108227
|
-
/** Tools that execute commands. */
|
|
108228
|
-
const EXECUTE_TOOLS = new Set(["Bash", "python"]);
|
|
108229
|
-
/** Nesting/coordination tools — only `all` mode keeps them. A restricted
|
|
108230
|
-
* child must not be able to spawn an unrestricted grandchild (that would
|
|
108231
|
-
* bypass the tool filtering entirely). WolfPack is batch-spawn sugar over
|
|
108232
|
-
* the same subagent host, so it is filtered too. */
|
|
108233
|
-
const NESTING_TOOLS = new Set([
|
|
108234
|
-
"Agent",
|
|
108235
|
-
"SendSubagentMessage",
|
|
108236
|
-
"WolfPack"
|
|
108237
|
-
]);
|
|
108238
|
-
/** Goal/session-management tools, always available regardless of mode. */
|
|
108239
|
-
const CORE_TOOLS = new Set([
|
|
108240
|
-
"CreateGoal",
|
|
108241
|
-
"GetGoal",
|
|
108242
|
-
"SetGoalBudget",
|
|
108243
|
-
"UpdateGoal",
|
|
108244
|
-
"WriteGoalNote",
|
|
108245
|
-
"EnterPlanMode",
|
|
108246
|
-
"ExitPlanMode"
|
|
108247
|
-
]);
|
|
108328
|
+
/**
|
|
108329
|
+
* Subagent capability modes and their tool-set policy.
|
|
108330
|
+
*
|
|
108331
|
+
* Capability modes (read-only / read-write / execute / all): a mode is
|
|
108332
|
+
* enforced at the tool level, not just by prompting. `all` keeps the profile's
|
|
108333
|
+
* full tool set; stricter modes strip it down to the tools the mode permits.
|
|
108334
|
+
*
|
|
108335
|
+
* Tool classification is by name; the sets live in `#/tools/tool-catalog`
|
|
108336
|
+
* (shared with the permission policies) so a new tool is classified once.
|
|
108337
|
+
* Unknown tool names are kept (a future tool should fail open rather than
|
|
108338
|
+
* being silently stripped from a read-only child).
|
|
108339
|
+
*/
|
|
108340
|
+
const KNOWN_TOOL_SETS = [
|
|
108341
|
+
READ_TOOLS,
|
|
108342
|
+
WRITE_TOOLS,
|
|
108343
|
+
EXECUTE_TOOLS,
|
|
108344
|
+
NESTING_TOOLS,
|
|
108345
|
+
CORE_TOOLS
|
|
108346
|
+
];
|
|
108248
108347
|
/**
|
|
108249
108348
|
* Filter an active tool-name list down to what `mode` permits. `all` returns
|
|
108250
108349
|
* the input unchanged. Unknown names are preserved.
|
|
@@ -108257,13 +108356,6 @@ function filterToolsForCapability(activeTools, mode) {
|
|
|
108257
108356
|
return allowed.has(name) || !KNOWN_TOOL_SETS.some((set) => set.has(name));
|
|
108258
108357
|
});
|
|
108259
108358
|
}
|
|
108260
|
-
const KNOWN_TOOL_SETS = [
|
|
108261
|
-
READ_TOOLS,
|
|
108262
|
-
WRITE_TOOLS,
|
|
108263
|
-
EXECUTE_TOOLS,
|
|
108264
|
-
NESTING_TOOLS,
|
|
108265
|
-
CORE_TOOLS
|
|
108266
|
-
];
|
|
108267
108359
|
function union(...sets) {
|
|
108268
108360
|
const out = /* @__PURE__ */ new Set();
|
|
108269
108361
|
for (const s of sets) for (const v of s) out.add(v);
|
|
@@ -122330,7 +122422,7 @@ function installMuPdfWasmLogger() {
|
|
|
122330
122422
|
}
|
|
122331
122423
|
installMuPdfWasmLogger();
|
|
122332
122424
|
let markit = async () => {
|
|
122333
|
-
const promise = import("./markit-
|
|
122425
|
+
const promise = import("./markit-Dga2W6G6.mjs").then(({ Markit }) => {
|
|
122334
122426
|
const instance = new Markit();
|
|
122335
122427
|
markit = () => instance;
|
|
122336
122428
|
return instance;
|
|
@@ -122486,7 +122578,7 @@ function resolveDocumentExtension(url, contentType) {
|
|
|
122486
122578
|
}
|
|
122487
122579
|
} catch {}
|
|
122488
122580
|
}
|
|
122489
|
-
/** Hard ceiling for one markit conversion
|
|
122581
|
+
/** Hard ceiling for one markit conversion — generous enough for slow hosts. */
|
|
122490
122582
|
const CONVERSION_TIMEOUT_MS = 3e4;
|
|
122491
122583
|
const DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36";
|
|
122492
122584
|
const DEFAULT_MAX_BYTES = 10 * 1024 * 1024;
|
|
@@ -122692,7 +122784,7 @@ var LocalFetchURLProvider = class {
|
|
|
122692
122784
|
//#endregion
|
|
122693
122785
|
//#region ../../packages/agent-core/src/tools/providers/search-timeout.ts
|
|
122694
122786
|
/**
|
|
122695
|
-
* Hard timeout for outbound web-search requests
|
|
122787
|
+
* Hard timeout for outbound web-search requests.
|
|
122696
122788
|
*
|
|
122697
122789
|
* A stalled TCP/TLS connection can keep an undici fetch pending for minutes;
|
|
122698
122790
|
* composing the caller's signal with a fixed ceiling guarantees the request
|
|
@@ -124740,8 +124832,7 @@ async function removeSessionIndexEntry(homeDir, sessionId) {
|
|
|
124740
124832
|
if (entry === void 0 || entry.sessionId === sessionId) continue;
|
|
124741
124833
|
kept.push(line);
|
|
124742
124834
|
}
|
|
124743
|
-
|
|
124744
|
-
else await writeFile(indexPath, kept.join("\n") + "\n", "utf-8");
|
|
124835
|
+
await atomicWrite(indexPath, kept.length === 0 ? "" : `${kept.join("\n")}\n`);
|
|
124745
124836
|
invalidateSessionIndexCache();
|
|
124746
124837
|
}
|
|
124747
124838
|
function parseIndexLine(line) {
|
|
@@ -124792,18 +124883,6 @@ const SessionSummaryStateSchema = z.object({
|
|
|
124792
124883
|
title: z.string().optional(),
|
|
124793
124884
|
custom: z.record(z.string(), z.unknown()).optional()
|
|
124794
124885
|
});
|
|
124795
|
-
let stateWriteCounter = 0;
|
|
124796
|
-
/**
|
|
124797
|
-
* Atomic state.json write: plain writeFile truncates the target before the
|
|
124798
|
-
* new bytes land, so a process killed mid-write leaves a 0-byte state.json
|
|
124799
|
-
* and the next resume crashes on JSON.parse. Temp-file + rename makes the
|
|
124800
|
-
* swap all-or-nothing.
|
|
124801
|
-
*/
|
|
124802
|
-
async function writeStateAtomically(statePath, content) {
|
|
124803
|
-
const tmpPath = `${statePath}.${process.pid}.${Date.now().toString(36)}.${(stateWriteCounter++).toString(36)}.tmp`;
|
|
124804
|
-
await writeFile(tmpPath, content, "utf-8");
|
|
124805
|
-
await rename(tmpPath, statePath);
|
|
124806
|
-
}
|
|
124807
124886
|
var SessionStore = class {
|
|
124808
124887
|
homeDir;
|
|
124809
124888
|
sessionsDir;
|
|
@@ -124823,10 +124902,7 @@ var SessionStore = class {
|
|
|
124823
124902
|
workDir
|
|
124824
124903
|
});
|
|
124825
124904
|
if (await this.findSessionEntry(input.id) !== void 0) await this.delete(input.id);
|
|
124826
|
-
else if (await isDirectory(dir)) await
|
|
124827
|
-
recursive: true,
|
|
124828
|
-
force: true
|
|
124829
|
-
});
|
|
124905
|
+
else if (await isDirectory(dir)) await rmWithRetry(dir);
|
|
124830
124906
|
await mkdir(dir, {
|
|
124831
124907
|
recursive: true,
|
|
124832
124908
|
mode: 448
|
|
@@ -124866,10 +124942,7 @@ var SessionStore = class {
|
|
|
124866
124942
|
});
|
|
124867
124943
|
return summary;
|
|
124868
124944
|
} catch (error) {
|
|
124869
|
-
await
|
|
124870
|
-
recursive: true,
|
|
124871
|
-
force: true
|
|
124872
|
-
}).catch(() => {});
|
|
124945
|
+
await rmWithRetry(targetDir).catch(() => {});
|
|
124873
124946
|
throw error;
|
|
124874
124947
|
}
|
|
124875
124948
|
}
|
|
@@ -124893,16 +124966,19 @@ var SessionStore = class {
|
|
|
124893
124966
|
title: normalized,
|
|
124894
124967
|
isCustomTitle: true
|
|
124895
124968
|
};
|
|
124896
|
-
await
|
|
124969
|
+
await atomicWrite(statePath, `${JSON.stringify(next, null, 2)}\n`);
|
|
124897
124970
|
}
|
|
124898
124971
|
async delete(id) {
|
|
124899
124972
|
assertSafeSessionId(id);
|
|
124900
124973
|
const entry = await this.findSessionEntry(id);
|
|
124901
|
-
if (entry !== void 0)
|
|
124902
|
-
|
|
124903
|
-
|
|
124904
|
-
|
|
124905
|
-
|
|
124974
|
+
if (entry !== void 0) {
|
|
124975
|
+
try {
|
|
124976
|
+
await rmWithRetry(entry.sessionDir);
|
|
124977
|
+
} catch (error) {
|
|
124978
|
+
throw new ScreamError(ErrorCodes.SESSION_DELETE_FAILED, `Session "${id}" could not be deleted`, { cause: error });
|
|
124979
|
+
}
|
|
124980
|
+
await removeSessionIndexEntry(this.homeDir, id).catch(() => {});
|
|
124981
|
+
}
|
|
124906
124982
|
}
|
|
124907
124983
|
async list(options = {}) {
|
|
124908
124984
|
const workDir = options.workDir === void 0 ? void 0 : normalizeRequiredWorkDir(options.workDir);
|
|
@@ -124998,7 +125074,7 @@ var SessionStore = class {
|
|
|
124998
125074
|
agents: rewriteAgentHomedirs(parsed["agents"], sourceDir, targetDir),
|
|
124999
125075
|
custom: Object.assign({}, isRecord$1(parsed["custom"]) ? parsed["custom"] : {}, input.metadata)
|
|
125000
125076
|
};
|
|
125001
|
-
await
|
|
125077
|
+
await atomicWrite(statePath, `${JSON.stringify(next, null, 2)}\n`);
|
|
125002
125078
|
}
|
|
125003
125079
|
async summaryFromDir(id, sessionDir, workDir) {
|
|
125004
125080
|
const dirStat = await stat(sessionDir);
|
|
@@ -129882,7 +129958,7 @@ async function handleDiyConfig(host) {
|
|
|
129882
129958
|
* Open the full-screen conversation search overlay (same as Ctrl+Shift+F).
|
|
129883
129959
|
* The overlay is owned by pi-tui; `openSearch` is a TS-private method but a
|
|
129884
129960
|
* plain instance method at runtime, so we reach it through a cast instead of
|
|
129885
|
-
* adding
|
|
129961
|
+
* adding a public API to the dependency for a single caller.
|
|
129886
129962
|
*/
|
|
129887
129963
|
function handleSearchCommand(host) {
|
|
129888
129964
|
host.state.ui?.openSearch?.();
|
|
@@ -137396,7 +137472,6 @@ function renderDiffCode(code, colorFn, highlight, lang, colors) {
|
|
|
137396
137472
|
* words with `chalk.inverse()`. Only the first removed/added part has its
|
|
137397
137473
|
* leading whitespace stripped, so indentation isn't highlighted.
|
|
137398
137474
|
*
|
|
137399
|
-
* Ported from oh-my-pi `packages/coding-agent/src/modes/components/diff.ts:55-95`.
|
|
137400
137475
|
* Returns the two lines with inline inverse highlighting applied; caller wraps
|
|
137401
137476
|
* them in the usual add/del gutter + line color.
|
|
137402
137477
|
*/
|
package/dist/main.mjs
CHANGED
|
@@ -6,7 +6,7 @@ const __dirname = __cjsShimDirname(__filename);
|
|
|
6
6
|
import "./suppress-sqlite-warning-C2VB0doZ.mjs";
|
|
7
7
|
//#region src/main.ts
|
|
8
8
|
try {
|
|
9
|
-
(await import("./app-
|
|
9
|
+
(await import("./app-BL4emsvp.mjs")).main();
|
|
10
10
|
} catch (error) {
|
|
11
11
|
process.stderr.write(`${error instanceof Error ? error.stack ?? error.message : String(error)}\n`);
|
|
12
12
|
process.exit(1);
|