@roll-agent/runtime 0.15.0 → 0.16.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/approval/approval-gate.d.ts +1 -0
- package/dist/approval/approval-memory.d.ts +5 -0
- package/dist/approval/approval-memory.js +1 -0
- package/dist/bash/exec.js +1 -1
- package/dist/bash/format-result.d.ts +4 -0
- package/dist/bash/format-result.js +1 -1
- package/dist/bash/output-dump.d.ts +16 -0
- package/dist/bash/output-dump.js +1 -0
- package/dist/bash/profile.d.ts +5 -0
- package/dist/bash/profile.js +1 -1
- package/dist/bash/session/session-exec.js +1 -1
- package/dist/bash/session/types.d.ts +7 -0
- package/dist/bash/session/yield-loop.js +1 -1
- package/dist/bash/shell-pipe.d.ts +26 -0
- package/dist/bash/shell-pipe.js +1 -0
- package/dist/bash/truncate.js +1 -1
- package/dist/engine/agent-session.d.ts +28 -3
- package/dist/engine/agent-session.js +1 -1
- package/dist/engine/cancelled-turn-recovery.d.ts +1 -0
- package/dist/engine/cancelled-turn-recovery.js +1 -1
- package/dist/engine/capability-manifest.d.ts +3 -0
- package/dist/engine/capability-manifest.js +1 -1
- package/dist/engine/compactor.d.ts +3 -0
- package/dist/engine/compactor.js +1 -1
- package/dist/engine/context-window.js +1 -1
- package/dist/engine/conversation-engine.d.ts +3 -0
- package/dist/engine/conversation-engine.js +1 -1
- package/dist/engine/relocate-tool-images.js +1 -1
- package/dist/engine/system-prompt.d.ts +10 -0
- package/dist/engine/system-prompt.js +1 -1
- package/dist/server/runtime-protocol-adapter.js +1 -1
- package/dist/service/attachment-store.js +1 -1
- package/dist/service/runtime-service.d.ts +2 -1
- package/dist/service/runtime-service.js +1 -1
- package/dist/store/thread-store.d.ts +19 -2
- package/dist/store/thread-store.js +1 -1
- package/dist/tool-bridge/bash-tool.d.ts +3 -0
- package/dist/tool-bridge/bash-tool.js +1 -1
- package/dist/tool-bridge/bounded-param.d.ts +14 -0
- package/dist/tool-bridge/bounded-param.js +1 -0
- package/dist/tool-bridge/build-tools.d.ts +5 -0
- package/dist/tool-bridge/build-tools.js +1 -1
- package/dist/tool-bridge/file-tools/control-chars.d.ts +11 -0
- package/dist/tool-bridge/file-tools/control-chars.js +1 -0
- package/dist/tool-bridge/file-tools/edit-file-tool.d.ts +42 -0
- package/dist/tool-bridge/file-tools/edit-file-tool.js +1 -0
- package/dist/tool-bridge/file-tools/external-approval.d.ts +3 -0
- package/dist/tool-bridge/file-tools/external-approval.js +1 -0
- package/dist/tool-bridge/file-tools/file-io.d.ts +35 -0
- package/dist/tool-bridge/file-tools/file-io.js +1 -0
- package/dist/tool-bridge/file-tools/file-state-tracker.d.ts +11 -0
- package/dist/tool-bridge/file-tools/file-state-tracker.js +1 -0
- package/dist/tool-bridge/file-tools/glob-tool.d.ts +21 -0
- package/dist/tool-bridge/file-tools/glob-tool.js +1 -0
- package/dist/tool-bridge/file-tools/grep-tool.d.ts +33 -0
- package/dist/tool-bridge/file-tools/grep-tool.js +1 -0
- package/dist/tool-bridge/file-tools/index.d.ts +18 -0
- package/dist/tool-bridge/file-tools/index.js +1 -0
- package/dist/tool-bridge/file-tools/list-dir-tool.d.ts +18 -0
- package/dist/tool-bridge/file-tools/list-dir-tool.js +1 -0
- package/dist/tool-bridge/file-tools/match-pipeline.d.ts +22 -0
- package/dist/tool-bridge/file-tools/match-pipeline.js +1 -0
- package/dist/tool-bridge/file-tools/read-file-tool.d.ts +25 -0
- package/dist/tool-bridge/file-tools/read-file-tool.js +1 -0
- package/dist/tool-bridge/file-tools/rg-exec.d.ts +12 -0
- package/dist/tool-bridge/file-tools/rg-exec.js +1 -0
- package/dist/tool-bridge/file-tools/settings.d.ts +12 -0
- package/dist/tool-bridge/file-tools/settings.js +1 -0
- package/dist/tool-bridge/file-tools/text-normalize.d.ts +5 -0
- package/dist/tool-bridge/file-tools/text-normalize.js +1 -0
- package/dist/tool-bridge/file-tools/verifier-registry.d.ts +42 -0
- package/dist/tool-bridge/file-tools/verifier-registry.js +1 -0
- package/dist/tool-bridge/file-tools/verify-file-tool.d.ts +30 -0
- package/dist/tool-bridge/file-tools/verify-file-tool.js +1 -0
- package/dist/tool-bridge/file-tools/write-file-tool.d.ts +22 -0
- package/dist/tool-bridge/file-tools/write-file-tool.js +1 -0
- package/dist/tool-bridge/session-exec-tool.js +1 -1
- package/dist/tool-bridge/tool-execution-coordinator.d.ts +15 -2
- package/dist/tool-bridge/tool-execution-coordinator.js +1 -1
- package/dist/types/events.d.ts +1 -0
- package/package.json +4 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export class SessionApprovalMemory{granted=new Set;isGranted(e){return this.granted.has(e)}grant(e){this.granted.add(e)}}
|
package/dist/bash/exec.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawn as e}from"node:child_process";import{existsSync as t}from"node:fs";import{constants as
|
|
1
|
+
import{spawn as e}from"node:child_process";import{existsSync as t,readFileSync as o,unlinkSync as r}from"node:fs";import{constants as i}from"node:os";import{performance as n}from"node:perf_hooks";import{OutputSink as s}from"./output-buffer.js";import{parsePipeSegments as l}from"./shell-pipe.js";import{BASH_TERMINATION_CAUSES as a,EXEC_TIMEOUT_EXIT_CODE as m,normalizeExitCode as c}from"./format-result.js";import{isTimeoutAbortReason as u}from"../types/cancellation.js";const d=2e3,f=2500,p=1e3,v=130,T={spawn:e,killTreeDeadlineMs:f,rootKillSettleTimeoutMs:p};function w(e){return e instanceof Error?e.message:String(e)}function b(e,t){const o=new s(0).collect();return{exitCode:1,timedOut:!1,timeoutMs:t,wallTimeMs:0,stdout:o,stderr:o,spawnError:e}}function h(e,t){const o=new s(0).collect(),r=u(t);return{exitCode:r?m:v,timedOut:r,timeoutMs:e,wallTimeMs:0,stdout:o,stderr:o,terminationCause:r?a.timeout:a.abort}}export function runBashCommand(e,f=T){const{command:p,workdir:y,timeoutMs:M,maxCaptureBytes:C,profile:g,env:E,abortSignal:x,onDelta:S}=e;return new Promise(e=>{if(x?.aborted)return void e(h(M,x.reason));if(!t(y))return void e(b(`工作目录不存在: ${y}`,M));let T,$;try{const e=g.buildSpawn(p,y,E??process.env);$=e.rollSegmentFile,T=f.spawn(e.file,e.args,e.options)}catch(t){return void e(b(w(t),M))}const k=g.pipeCapability?.().capability??"none",D=()=>{if(void 0!==$)try{const e=o($,"utf8");return l(e)}catch{return}finally{try{r($)}catch{}}},L=n.now(),O=new s(C),j=new s(C);let K,P,A,B,F,I,_=!1,G=!1,N=!1,R=!1,q=!1,z=!1,H=null,J=null,Q=void 0!==T.pid,U=!1,V=!1;const W=e=>{I=I?`${I};${e}`:e},X=()=>{if(R||!q||!z)return;if(N&&!0===g.waitForTreeKillAfterRootExit&&!U&&!V)return;const e=null!==J?i.signals[J]:void 0,t=_?m:G?v:c({timedOut:!1,code:H,signalNumber:e}),o=D();oe({exitCode:t,timedOut:_,timeoutMs:M,wallTimeMs:n.now()-L,stdout:O.collect(),stderr:j.collect(),...K?{terminationCause:K}:{},...I?{terminationError:I}:{},...void 0!==o?{pipeSegments:o}:{},pipeCapability:k})},Y=()=>{if(R||q)return;for(const e of ie)e.stream.destroy();T.unref();const e=D();oe({exitCode:_?m:v,timedOut:_,timeoutMs:M,wallTimeMs:n.now()-L,stdout:O.collect(),stderr:j.collect(),...K?{terminationCause:K}:{},terminationError:`${I??"进程树清理未完成"};根进程在强制终止请求后仍未确认退出`,...void 0!==e?{pipeSegments:e}:{},pipeCapability:k})},Z=e=>{if(!R){if(B&&(clearTimeout(B),B=void 0),!U){U=!0;const t=void 0===e?"进程树清理未完成":w(e);W(`${t};已回退仅向根进程发送强制终止请求,无法确认后代进程是否已清理`)}if(q)X();else if(void 0===F){F=setTimeout(Y,f.rootKillSettleTimeoutMs);try{T.kill("SIGKILL")||W("根进程强制终止请求未被接受")}catch(e){W(`根进程强制终止请求失败: ${w(e)}`)}}}},ee=()=>{if(!N){N=!0,A=new AbortController,B=setTimeout(()=>Z(new Error("进程树清理超过独立期限")),f.killTreeDeadlineMs);try{g.killTree(T.pid,"terminate",{signal:A.signal}).then(()=>{V=!0,q&&B&&(clearTimeout(B),B=void 0),X()}).catch(Z)}catch(e){Z(e)}}},te=()=>{if(void 0!==K)return;const e=u(x?.reason);K=e?a.timeout:a.abort,_=e,G=!e,clearTimeout(ne),ee()},oe=t=>{R||(R=!0,clearTimeout(ne),P&&clearTimeout(P),B&&clearTimeout(B),F&&clearTimeout(F),A?.abort(),A=void 0,x?.removeEventListener("abort",te),e(t))},re=(e,t,o)=>{if(null===e)return;const r=new TextDecoder("utf-8");e.on("data",e=>{if(o.append(e),S){const o=r.decode(e,{stream:!0});o.length>0&&S(t,o)}});const i=new Promise(t=>{e.once("close",()=>t())});return{stream:e,closed:i}},ie=[re(T.stdout,"stdout",O),re(T.stderr,"stderr",j)].filter(e=>void 0!==e);T.once("spawn",()=>{Q=!0}),T.on("error",e=>{if(R)return;if(!N||!Q)return void oe(b(w(e),M));const t=`根进程终止请求失败: ${w(e)}`;U?W(t):Z(new Error(t,{cause:e}))}),T.on("exit",(e,t)=>{R||q||(q=!0,H=e,J=t,clearTimeout(ne),x?.removeEventListener("abort",te),V&&B&&(clearTimeout(B),B=void 0),F&&(clearTimeout(F),F=void 0),P=setTimeout(()=>{for(const e of ie)e.stream.destroy()},f.ioDrainTimeoutMs??d),Promise.all(ie.map(e=>e.closed)).then(()=>{z=!0,X()}).catch(()=>{}))});const ne=setTimeout(()=>{void 0===K&&(K=a.timeout,_=!0,ee())},M);x&&(x.aborted?te():x.addEventListener("abort",te))})}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type NormalizedToolResult } from "../tool-bridge/normalize-result.ts";
|
|
2
2
|
import type { CapturedStream } from "./output-buffer.ts";
|
|
3
|
+
import { type ShellPipeCapability } from "./shell-pipe.ts";
|
|
3
4
|
export declare const EXEC_TIMEOUT_EXIT_CODE = 124;
|
|
4
5
|
export declare const EXIT_CODE_SIGNAL_BASE = 128;
|
|
5
6
|
export declare const BASH_TERMINATION_CAUSES: {
|
|
@@ -17,6 +18,8 @@ export interface BashExecResult {
|
|
|
17
18
|
readonly terminationCause?: BashTerminationCause;
|
|
18
19
|
readonly spawnError?: string;
|
|
19
20
|
readonly terminationError?: string;
|
|
21
|
+
readonly pipeSegments?: readonly number[];
|
|
22
|
+
readonly pipeCapability?: ShellPipeCapability;
|
|
20
23
|
}
|
|
21
24
|
export interface NormalizeExitCodeParams {
|
|
22
25
|
readonly timedOut: boolean;
|
|
@@ -27,5 +30,6 @@ export declare function normalizeExitCode(params: NormalizeExitCodeParams): numb
|
|
|
27
30
|
export interface FormatBashResultInput {
|
|
28
31
|
readonly result: BashExecResult;
|
|
29
32
|
readonly maxModelOutputChars: number;
|
|
33
|
+
readonly fullOutputSink?: (text: string) => string | undefined;
|
|
30
34
|
}
|
|
31
35
|
export declare function formatBashResult(input: FormatBashResultInput): NormalizedToolResult;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{TOOL_OUTCOME_KINDS as t,failedToolResult as r,successfulToolResult as
|
|
1
|
+
import{TOOL_OUTCOME_KINDS as t,failedToolResult as r,successfulToolResult as e}from"../tool-bridge/normalize-result.js";import{partitionModelBudget as o}from"./output-buffer.js";import{allocateOutputDumpFile as n,describeOutputDumpRecovery as i,rollOutputDumpDir as s,writeOutputDump as u}from"./output-dump.js";import{evaluatePipelineExit as d}from"./shell-pipe.js";import{truncateMiddle as a}from"./truncate.js";export const EXEC_TIMEOUT_EXIT_CODE=124;export const EXIT_CODE_SIGNAL_BASE=128;export const BASH_TERMINATION_CAUSES={timeout:"timeout",abort:"abort"};const m=1;export function normalizeExitCode(t){return t.timedOut?124:null!==t.code?t.code:void 0!==t.signalNumber?128+t.signalNumber:1}function l(t,r){if(r.truncated)return`Warning: ${t} 输出已截断(原始 ${String(r.totalBytes)} 字节 / ${String(r.totalLines)} 行)`}function p(t){const r=n(s(),"bash");return u(r,t),r}function c(t,r){const e=r.length>0?r:void 0;return void 0!==e?`[${t}]\n${e}`:void 0}export function formatBashResult(n){const{result:s,maxModelOutputChars:u}=n;if(void 0!==s.spawnError)return r(t.toolFailed,`命令无法启动: ${s.spawnError}`,{raw:s});const m=o(u,Array.from(s.stderr.text).length),f=a(s.stdout.text,m.stdout),E=a(s.stderr.text,m.stderr),x=[];s.terminationCause===BASH_TERMINATION_CAUSES.abort&&x.push("命令已中断(收到取消请求),不能视为正常完成"),s.timedOut&&x.push(s.terminationError?`命令超时(超过 ${String(s.timeoutMs)}ms),终止状态未确认`:`命令超时(超过 ${String(s.timeoutMs)}ms),已终止`),s.terminationError&&x.push(`终止失败: ${s.terminationError}`);const S=d({exitCode:s.exitCode,...void 0!==s.pipeSegments?{segments:s.pipeSegments}:{},capability:s.pipeCapability??"none"});x.push(`Exit code: ${String(S.effectiveExitCode)}`),void 0!==S.note&&x.push(S.note),x.push(`Wall time: ${(s.wallTimeMs/1e3).toFixed(1)} s`);const v=[s.stdout.truncated||f.truncated?l("stdout",s.stdout):void 0,s.stderr.truncated||E.truncated?l("stderr",s.stderr):void 0].filter(t=>void 0!==t);if(f.truncated||E.truncated||s.stdout.truncated||s.stderr.truncated){const t=[s.stdout.text.length>0?`[stdout]\n${s.stdout.text}`:void 0,s.stderr.text.length>0?`[stderr]\n${s.stderr.text}`:void 0].filter(t=>void 0!==t),r=(n.fullOutputSink??p)(t.join("\n\n"));void 0!==r&&v.push(i(r))}x.push(...v);const g=[c("stdout",f.text),c("stderr",E.text)].filter(t=>void 0!==t),h=[x.join("\n"),...g].join("\n\n");return s.terminationCause===BASH_TERMINATION_CAUSES.abort?r(t.cancelled,h,{raw:s}):S.ok&&void 0===s.terminationError?e(h,{raw:s}):r(t.toolFailed,h,{raw:s})}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare const OUTPUT_DUMP_MAX_AGE_MS: number;
|
|
2
|
+
export declare const OUTPUT_DUMP_MAX_FILES = 32;
|
|
3
|
+
export declare const OUTPUT_DUMP_SESSION_CAP_BYTES: number;
|
|
4
|
+
export declare function rollOutputDumpDir(base?: string): string;
|
|
5
|
+
export declare function ensureOutputDumpDir(dir: string): void;
|
|
6
|
+
export declare function pruneOutputDumpDir(dir: string, now?: number): void;
|
|
7
|
+
export declare function allocateOutputDumpFile(dir: string, label: string): string;
|
|
8
|
+
export declare function writeOutputDump(path: string, text: string): void;
|
|
9
|
+
export interface OutputDumpWriter {
|
|
10
|
+
readonly path: string;
|
|
11
|
+
write(text: string): void;
|
|
12
|
+
close(): void;
|
|
13
|
+
}
|
|
14
|
+
export declare function createOutputDumpWriter(path: string, capBytes: number): OutputDumpWriter;
|
|
15
|
+
export declare function isWithinOutputDumpDir(path: string, dir?: string): boolean;
|
|
16
|
+
export declare function describeOutputDumpRecovery(path: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{closeSync as t,mkdirSync as r,openSync as e,readdirSync as o,statSync as u,unlinkSync as n,writeSync as i}from"node:fs";import{homedir as p}from"node:os";import{join as m,resolve as c,sep as f}from"node:path";import{randomUUID as s}from"node:crypto";export const OUTPUT_DUMP_MAX_AGE_MS=864e5;export const OUTPUT_DUMP_MAX_FILES=32;export const OUTPUT_DUMP_SESSION_CAP_BYTES=4194304;const l=m(".roll-agent","bash-output-dumps");export function rollOutputDumpDir(t=p()){return m(t,l)}export function ensureOutputDumpDir(t){r(t,{recursive:!0,mode:448})}export function pruneOutputDumpDir(t,r=Date.now()){let e;try{e=o(t)}catch{return}const i=e.map(r=>{try{return{name:r,mtime:u(m(t,r)).mtimeMs}}catch{return}}).filter(t=>void 0!==t).sort((t,r)=>t.mtime-r.mtime);for(const e of i)if(r-e.mtime>864e5)try{n(m(t,e.name))}catch{}const p=i.filter(t=>r-t.mtime<=864e5),c=p.length-32;for(let r=0;r<c;r+=1){const e=p[r];if(void 0!==e)try{n(m(t,e.name))}catch{}}}export function allocateOutputDumpFile(t,r){return ensureOutputDumpDir(t),pruneOutputDumpDir(t),m(t,`${String(Date.now())}-${r}-${s()}.log`)}export function writeOutputDump(r,o){const u=e(r,"w",384);i(u,o),t(u)}export function createOutputDumpWriter(r,o){const u=e(r,"w",384);let n=0,p=!1;return{path:r,write(t){if(p||n>=o)return;const r=Buffer.from(t,"utf8"),e=o-n,m=r.length>e?r.subarray(0,e):r;i(u,m),n+=m.length},close(){p||(p=!0,t(u))}}}export function isWithinOutputDumpDir(t,r=rollOutputDumpDir()){const e=c(t),o=c(r);return e===o||e.startsWith(o+f)}export function describeOutputDumpRecovery(t){return`完整输出已落盘: ${t};用 roll__read_file 以 offset/limit 分页查看被截断的中段,或重跑更窄的命令`}
|
package/dist/bash/profile.d.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { spawn, spawnSync, type SpawnOptions } from "node:child_process";
|
|
2
2
|
import type { CommandClassification } from "../types/command-classification.ts";
|
|
3
|
+
import { type ShellPipeProbe } from "./shell-pipe.ts";
|
|
3
4
|
export declare const SHELL_PROFILE_IDS: readonly ["posix", "powershell"];
|
|
4
5
|
export type ShellProfileId = (typeof SHELL_PROFILE_IDS)[number];
|
|
5
6
|
export declare const SHELL_TOOL_NAMES: readonly ["bash", "powershell"];
|
|
6
7
|
export type ShellToolName = (typeof SHELL_TOOL_NAMES)[number];
|
|
8
|
+
export declare const POSIX_PIPEFAIL_GUARD = "( set -o pipefail ) 2>/dev/null && set -o pipefail; ";
|
|
9
|
+
export declare function wrapPosixCommand(command: string): string;
|
|
7
10
|
export interface ShellSpawnSpec {
|
|
8
11
|
readonly file: string;
|
|
9
12
|
readonly args: readonly string[];
|
|
10
13
|
readonly options: SpawnOptions;
|
|
14
|
+
readonly rollSegmentFile?: string;
|
|
11
15
|
}
|
|
12
16
|
export interface ShellKillOptions {
|
|
13
17
|
readonly signal?: AbortSignal;
|
|
@@ -22,6 +26,7 @@ export interface ShellProfile {
|
|
|
22
26
|
classify(command: string, workdir: string): CommandClassification;
|
|
23
27
|
killTree(pid: number | undefined, intent: "interrupt" | "terminate", options?: ShellKillOptions): Promise<void>;
|
|
24
28
|
systemPromptHints(): readonly string[];
|
|
29
|
+
pipeCapability?: () => ShellPipeProbe;
|
|
25
30
|
}
|
|
26
31
|
export interface ShellProfileResolutionDeps {
|
|
27
32
|
readonly platform: NodeJS.Platform;
|
package/dist/bash/profile.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawn as e,spawnSync as
|
|
1
|
+
import{spawn as e,spawnSync as t}from"node:child_process";import{existsSync as o}from"node:fs";import{win32 as r}from"node:path";import{performance as n}from"node:perf_hooks";import{unknownCommandClassifier as i}from"../types/command-classification.js";import{ruleBasedClassifier as s}from"./classifier/index.js";import{DEFAULT_KILL_GRACE_MS as l,killProcessGroup as a}from"./kill.js";import{allocateOutputDumpFile as c,rollOutputDumpDir as p}from"./output-dump.js";import{buildSegmentCaptureWrapper as u,PIPE_STATUS_ENV as f,probeShellPipeCapability as m}from"./shell-pipe.js";import{resolveUserShell as d}from"./shell.js";export const SHELL_PROFILE_IDS=["posix","powershell"];export const SHELL_TOOL_NAMES=["bash","powershell"];export const POSIX_PIPEFAIL_GUARD="( set -o pipefail ) 2>/dev/null && set -o pipefail; ";export function wrapPosixCommand(e){return`${POSIX_PIPEFAIL_GUARD}${e}`}const w=["-NoLogo","-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-EncodedCommand"],h=32767,S=1024,g=5e3,E=2e3,v=128,x=["PowerShell","7","pwsh.exe"],P=["System32","taskkill.exe"];function b(e,t){return t?.aborted?Promise.resolve(!1):new Promise(o=>{let r=!1;const n=e=>{r||(r=!0,clearTimeout(s),t?.removeEventListener("abort",i),o(e))},i=()=>n(!1),s=setTimeout(()=>n(!0),e);t?.addEventListener("abort",i,{once:!0})})}function y(e){const r=e.fileExists??o,n=e.spawnSync??t,i=new Map,w=e=>{const t=i.get(e);if(void 0!==t)return t;const o=m(e,n);return i.set(e,o),o};return{id:"posix",toolName:"bash",supportsSessionExec:!0,supportsSafeCommandClassification:!0,waitForTreeKillAfterRootExit:!1,pipeCapability:()=>w(d({platform:e.platform,env:e.env,fileExists:r})),buildSpawn(t,o,n){const i=d({platform:e.platform,env:n,fileExists:r}),s=w(i);let l,a=t,m=n;return"segments"===s.capability&&void 0!==s.segmentArray?(l=c(p(),"pipestatus"),a=u(t,s.segmentArray),m={...n,[f]:l}):"pipefail"===s.capability&&(a=wrapPosixCommand(t)),{file:i,args:["-c",a],options:{cwd:o,detached:!0,stdio:["ignore","pipe","pipe"],env:m},...void 0!==l?{rollSegmentFile:l}:{}}},classify:(e,t)=>s.classify(e,t),async killTree(e,t,o={}){o.signal?.aborted||("interrupt"!==t?(a(e,"SIGTERM"),await b(l,o.signal)&&a(e,"SIGKILL")):a(e,"SIGINT"))},systemPromptHints(){const t=w(d({platform:e.platform,env:e.env,fileExists:r})).capability;return["当前 shell 后端是 POSIX shell;优先使用 macOS/Linux 常见命令语法。","segments"===t?"管道按逐段退出码判定:末段为 0 且其余段为 0 或被下游提前关闭(SIGPIPE/141)才算成功;…| head 型提前关闭会判成功并附说明,其余中段失败如实报告。":"pipefail"===t?"管道已启用 pipefail:任一阶段失败整条管道即失败;退出码 141 表示上游被下游提前关闭,已标注且不视为失败。":"当前 shell 不支持 pipefail/逐段判定:管道退出码为最后一段的退出码;退出码 141 表示上游被下游提前关闭,已标注且不视为失败。","仅为控制输出量时请用 roll__bash 的 max_output_chars 参数或 roll__read_file / roll__grep 等工具,不要自接 head/tail 管道;需要过滤时仍可用 grep 等工具。"]}}}function C(e,t,o,r,n={}){return void 0===e||n.signal?.aborted?Promise.resolve():void 0===t?Promise.reject(new Error("无法从绝对 SystemRoot 路径解析 taskkill.exe,不能安全清理进程树")):new Promise((i,s)=>{let l,a=!1;const c=e=>{a||(a=!0,clearTimeout(u),n.signal?.removeEventListener("abort",p),e?s(e):i())},p=()=>{try{l.kill()}catch{}try{l.unref()}catch{}c()},u=setTimeout(()=>{try{l.kill()}catch{}try{l.unref()}catch{}c(new Error(`taskkill.exe 在 ${String(r)}ms 内未结束`))},r);try{l=o(t,["/PID",String(e),"/T","/F"],{stdio:"ignore",windowsHide:!0})}catch(e){return void c(new Error(`无法启动 taskkill.exe: ${k(e)}`,{cause:e}))}l.once("error",e=>{c(new Error(`无法启动 taskkill.exe: ${e.message}`,{cause:e}))}),l.once("close",(e,t)=>{if(0===e||e===v)return void c();const o=null===e?`signal=${t??"unknown"}`:`exitCode=${String(e)}`;c(new Error(`taskkill.exe 执行失败: ${o}`))}),n.signal?.addEventListener("abort",p,{once:!0}),n.signal?.aborted&&p()})}function k(e){return e instanceof Error?e.message:String(e)}export function buildPowerShellEncodedCommand(e){const t=["[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new($false)","$OutputEncoding = [Console]::OutputEncoding","$ErrorActionPreference = 'Stop'","try {",e," if (Test-Path variable:LASTEXITCODE) { exit $LASTEXITCODE }","} catch {"," [Console]::Error.WriteLine([string]$_)"," exit 1","}"].join("\n");return Buffer.from(t,"utf16le").toString("base64")}function I(e,t){return[e,...t].reduce((e,t)=>e+t.length+1,0)}function L(e,t){const o=buildPowerShellEncodedCommand(e),r=[...w,o],n=I(t,r)+S;if(n>h)throw new Error(`PowerShell 命令过长:编码后命令行约 ${String(n)} 字符,超过 Windows CreateProcess 上限 ${String(h)};请拆分命令或改为执行脚本文件。`);return r}function T(e,t){const o=t.toLowerCase();for(const[t,r]of Object.entries(e))if(t.toLowerCase()===o&&void 0!==r&&r.length>0)return r}function _(e){const t=e.trim();return t.startsWith('"')&&t.endsWith('"')?t.slice(1,-1).trim():t}function $(e){return r.isAbsolute(e)&&r.parse(e).root.length>1}function j(e){const t=[],o=new Set,n=e=>{if(!$(e))return;const n=r.normalize(e).toLowerCase();o.has(n)||(o.add(n),t.push(r.normalize(e)))},i=T(e.env,"Path");for(const e of i?.split(r.delimiter)??[]){const t=_(e);$(t)&&n(r.join(t,"pwsh.exe"))}const s=[T(e.env,"ProgramFiles"),T(e.env,"ProgramW6432"),T(e.env,"ProgramFiles(x86)")];for(const e of s){if(void 0===e)continue;const t=_(e);$(t)&&n(r.join(t,...x))}return t}function O(e){const t=T(e,"SystemRoot");if(void 0===t)return;const o=_(t);return $(o)?r.join(o,...P):void 0}function A(e,t,o){const r=t(e,["-NoLogo","-NoProfile","-NonInteractive","-Command","$PSVersionTable.PSVersion.Major"],{encoding:"utf8",timeout:o,windowsHide:!0});if(r.error||0!==r.status)return;const n=`${r.stdout??""}`.trim(),i=Number.parseInt(n,10);return Number.isFinite(i)?i:void 0}function F(e,t){const r=e.fileExists??o,i=e.now??(()=>n.now()),s=i()+g;let l=!1;for(const o of j(e)){if(s-i()<=0)break;if(!r(o))continue;const e=Math.ceil(s-i());if(e<=0)break;const n=A(o,t,e);if(void 0!==n){if(n>=7)return{supported:!0,executable:o};l=!0}}return{supported:!1,reason:l?"pwsh-version-unsupported":"pwsh-not-found"}}function N(o){const r=F(o,o.spawnSync??t);if(!r.supported)return r;const n=o.spawn??e,s=O(o.env),l=o.taskkillTimeoutMs??E;return{supported:!0,profile:{id:"powershell",toolName:"powershell",supportsSessionExec:!0,supportsSafeCommandClassification:!1,waitForTreeKillAfterRootExit:!0,buildSpawn:(e,t,o)=>({file:r.executable,args:L(e,r.executable),options:{cwd:t,detached:!1,stdio:["ignore","pipe","pipe"],env:o,windowsHide:!0}}),classify:(e,t)=>i.classify(e,t),async killTree(e,t,o={}){await C(e,s,n,l,o)},systemPromptHints:()=>["当前 shell 后端是 PowerShell 7;请使用 PowerShell 语法,例如 Get-ChildItem、Get-Content、Select-String。","过滤和预览输出时优先使用 Select-String、Select-Object -First、Get-Content -TotalCount。"]}}}export function resolveShellProfile(e){return"win32"===e.platform?N(e):{supported:!0,profile:y(e)}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawn as e}from"node:child_process";import{
|
|
1
|
+
import{spawn as e}from"node:child_process";import{readFileSync as t,unlinkSync as o}from"node:fs";import{constants as i}from"node:os";import{performance as r}from"node:perf_hooks";import{normalizeExitCode as n}from"../format-result.js";import{allocateOutputDumpFile as s,createOutputDumpWriter as a,OUTPUT_DUMP_SESSION_CAP_BYTES as d,rollOutputDumpDir as p}from"../output-dump.js";import{parsePipeSegments as l}from"../shell-pipe.js";import{HeadTailBuffer as m}from"./head-tail-buffer.js";import{SESSION_STATES as c}from"./types.js";class Gate{opened=!1;waiters=[];open(){if(this.opened)return;this.opened=!0;const e=this.waiters;this.waiters=[];for(const t of e)t()}wait(){return this.opened?Promise.resolve():new Promise(e=>{this.waiters.push(e)})}}export function spawnSession(u){const f=u.profile.buildSpawn(u.command,u.workdir,u.env),w=e(f.file,f.args,f.options),g=f.rollSegmentFile,v=a(s(p(),"session"),d),h=new m(u.bufferCapacity),b=r.now(),C=new Gate,x=new Gate,k=new Gate;let y=u.onDelta,S=!1;const O={id:u.id,command:u.command,workdir:u.workdir,profile:u.profile,child:w,buffer:h,startedAt:b,state:c.running,exitCode:void 0,exitObserved:!1,closeObserved:!1,completedAt:void 0,terminationCause:void 0,cleanupError:void 0,lastUsedAt:b,pipeSegments:void 0,pipeCapability:u.profile.pipeCapability?.().capability,dumpPath:v.path,beginPoll:e=>!S&&(S=!0,void 0!==e&&(y=e),!0),endPoll:()=>{y=void 0,S=!1},markStopping:e=>{O.state!==c.completed&&O.state!==c.cleanupFailed&&(O.terminationCause??=e,O.state=c.stopping)},markCompleted:()=>{O.state!==c.cleanupFailed&&(O.exitCode??=1,O.state=c.completed,O.completedAt??=r.now(),k.open())},markCleanupFailed:e=>{O.cleanupError=O.cleanupError?`${O.cleanupError};${e}`:e,O.exitCode??=1,O.state=c.cleanupFailed,O.completedAt??=r.now(),k.open()},waitExit:()=>C.wait(),waitClose:()=>x.wait(),waitSettled:()=>k.wait()},A=(e,t)=>{0!==t.length&&(h.append(t),v.write(t),y?.(e,t))},j=(e,t)=>{if(null===e)return;const o=new TextDecoder("utf-8");e.on("data",e=>{A(t,o.decode(e,{stream:!0}))}),e.on("end",()=>{A(t,o.decode())})};j(w.stdout,"stdout"),j(w.stderr,"stderr");const E=(e,t)=>{if(O.exitObserved)return;const o=null!==t?i.signals[t]:void 0;O.exitCode=n({timedOut:!1,code:e,signalNumber:o}),O.exitObserved=!0,O.state===c.running&&(O.state=c.draining),C.open()};return w.on("exit",(e,t)=>{E(e,t)}),w.on("close",(e,i)=>{E(e,i),v.close(),(()=>{if(void 0!==g)try{O.pipeSegments=l(t(g,"utf8"))}catch{O.pipeSegments=void 0}finally{try{o(g)}catch{}}})(),O.closeObserved=!0,O.completedAt??=r.now(),x.open(),O.state!==c.stopping&&O.markCompleted()}),w.on("error",e=>{h.append(`无法启动进程: ${e.message}\n`),O.exitCode=O.exitCode??1,O.exitObserved=!0,O.state===c.running&&(O.state=c.draining),C.open()}),O}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ChildProcess } from "node:child_process";
|
|
2
2
|
import type { BashStreamName } from "../exec.ts";
|
|
3
3
|
import type { ShellProfile } from "../profile.ts";
|
|
4
|
+
import type { ShellPipeCapability } from "../shell-pipe.ts";
|
|
4
5
|
import type { HeadTailBuffer } from "./head-tail-buffer.ts";
|
|
5
6
|
export type SessionDeltaHandler = (stream: BashStreamName, delta: string) => void;
|
|
6
7
|
export declare const SESSION_STATES: {
|
|
@@ -33,6 +34,9 @@ export interface ManagedSession {
|
|
|
33
34
|
terminationCause: SessionTerminationCause | undefined;
|
|
34
35
|
cleanupError: string | undefined;
|
|
35
36
|
lastUsedAt: number;
|
|
37
|
+
pipeSegments?: readonly number[] | undefined;
|
|
38
|
+
pipeCapability?: ShellPipeCapability | undefined;
|
|
39
|
+
dumpPath?: string | undefined;
|
|
36
40
|
beginPoll(onDelta?: SessionDeltaHandler): boolean;
|
|
37
41
|
endPoll(): void;
|
|
38
42
|
markStopping(cause: SessionTerminationCause): void;
|
|
@@ -51,6 +55,9 @@ export type SessionPollResult = {
|
|
|
51
55
|
readonly state: TerminalSessionState;
|
|
52
56
|
readonly terminationCause?: SessionTerminationCause;
|
|
53
57
|
readonly cleanupError?: string;
|
|
58
|
+
readonly pipeSegments?: readonly number[];
|
|
59
|
+
readonly pipeCapability?: ShellPipeCapability;
|
|
60
|
+
readonly dumpPath?: string;
|
|
54
61
|
} | {
|
|
55
62
|
readonly kind: "running";
|
|
56
63
|
readonly output: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{performance as
|
|
1
|
+
import{performance as e}from"node:perf_hooks";import{isTerminalSessionState as t}from"./types.js";export class SessionPollInProgressError extends Error{constructor(e){super(`会话 ${String(e)} 已有一个轮询窗口在运行`),this.name="SessionPollInProgressError"}}function o(e){const t=e?.reason;return t instanceof Error?t:new DOMException("string"==typeof t&&t.length>0?t:"The operation was aborted","AbortError")}export function throwIfSessionExecAborted(e){if(!0===e?.aborted)throw o(e)}function r(e,r,n){return r<=0||t(e.state)?Promise.resolve():new Promise((t,i)=>{let s=!1;const a=e=>{s||(s=!0,clearTimeout(d),n?.removeEventListener("abort",l),void 0!==e?i(e):t())},l=()=>a(o(n)),d=setTimeout(()=>a(),r);e.waitSettled().then(()=>a()),n?.addEventListener("abort",l,{once:!0}),!0===n?.aborted&&l()})}export async function pollUntilDeadline(o,n,i,s={}){if(!o.beginPoll(s.onDelta))throw new SessionPollInProgressError(o.id);try{throwIfSessionExecAborted(s.abortSignal),await r(o,n-e.now(),s.abortSignal),throwIfSessionExecAborted(s.abortSignal);const a=e.now();o.lastUsedAt=a;const l=o.state,d=t(l),p=d?o.buffer.snapshot(i):o.buffer.drain(i),u=(d?o.completedAt??a:a)-o.startedAt;return d?{kind:"exited",output:p.text,omitted:p.omitted,wallTimeMs:u,exitCode:o.exitCode??1,state:l,...o.terminationCause?{terminationCause:o.terminationCause}:{},...o.cleanupError?{cleanupError:o.cleanupError}:{},...void 0!==o.pipeSegments?{pipeSegments:o.pipeSegments}:{},...void 0!==o.pipeCapability?{pipeCapability:o.pipeCapability}:{},...void 0!==o.dumpPath?{dumpPath:o.dumpPath}:{}}:{kind:"running",output:p.text,omitted:p.omitted,wallTimeMs:u,sessionId:o.id}}finally{o.lastUsedAt=e.now(),o.endPoll()}}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { spawnSync as SpawnSync } from "node:child_process";
|
|
2
|
+
export declare const SIGPIPE_EXIT_CODE = 141;
|
|
3
|
+
export declare const PIPE_STATUS_ENV = "ROLL_PIPE_STATUS_FILE";
|
|
4
|
+
export declare const SHELL_PIPE_CAPABILITIES: readonly ["segments", "pipefail", "none"];
|
|
5
|
+
export type ShellPipeCapability = (typeof SHELL_PIPE_CAPABILITIES)[number];
|
|
6
|
+
export declare const PIPE_SEGMENT_ARRAYS: readonly ["PIPESTATUS", "pipestatus"];
|
|
7
|
+
export type PipeSegmentArray = (typeof PIPE_SEGMENT_ARRAYS)[number];
|
|
8
|
+
export interface ShellPipeProbe {
|
|
9
|
+
readonly capability: ShellPipeCapability;
|
|
10
|
+
readonly segmentArray?: PipeSegmentArray;
|
|
11
|
+
}
|
|
12
|
+
export declare function probeShellPipeCapability(shellPath: string, spawnSyncImpl: typeof SpawnSync): ShellPipeProbe;
|
|
13
|
+
export declare function parsePipeSegments(text: string): readonly number[] | undefined;
|
|
14
|
+
export declare function buildSegmentCaptureWrapper(command: string, segmentArray: PipeSegmentArray): string;
|
|
15
|
+
export interface PipelineVerdict {
|
|
16
|
+
readonly ok: boolean;
|
|
17
|
+
readonly effectiveExitCode: number;
|
|
18
|
+
readonly note?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare const SIGPIPE_BENIGN_NOTE = "\u7BA1\u9053\u4E2D\u6709\u4E0A\u6E38\u9636\u6BB5\u88AB\u4E0B\u6E38\u63D0\u524D\u5173\u95ED\uFF08SIGPIPE\uFF0C\u9000\u51FA\u7801 141\uFF09\uFF0C\u6309\u826F\u6027\u5904\u7406\uFF1B\u4E0B\u6E38\u8F93\u51FA\u53EF\u80FD\u4E0D\u5B8C\u6574";
|
|
21
|
+
export declare const SIGPIPE_FALLBACK_NOTE = "\u9000\u51FA\u7801 141\uFF1A\u4E0A\u6E38\u88AB\u4E0B\u6E38\u63D0\u524D\u5173\u95ED\uFF08SIGPIPE\uFF09\uFF0C\u8F93\u51FA\u53EF\u80FD\u5B8C\u6574\uFF1B\u5F53\u524D shell \u65E0\u9010\u6BB5\u72B6\u6001\uFF0C\u672A\u89C6\u4E3A\u5931\u8D25";
|
|
22
|
+
export declare function evaluatePipelineExit(params: {
|
|
23
|
+
readonly exitCode: number;
|
|
24
|
+
readonly segments?: readonly number[];
|
|
25
|
+
readonly capability: ShellPipeCapability;
|
|
26
|
+
}): PipelineVerdict;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const SIGPIPE_EXIT_CODE=141;export const PIPE_STATUS_ENV="ROLL_PIPE_STATUS_FILE";export const SHELL_PIPE_CAPABILITIES=["segments","pipefail","none"];export const PIPE_SEGMENT_ARRAYS=["PIPESTATUS","pipestatus"];const e=2e3;export function probeShellPipeCapability(t,i){const n=i(t,["-c",'false | true; printf "%s|%s" "${PIPESTATUS[*]:-}" "${pipestatus[*]:-}"'],{encoding:"utf8",timeout:e});if(!n.error&&0===n.status){const e=n.stdout??"";if(e.startsWith("1 0"))return{capability:"segments",segmentArray:"PIPESTATUS"};if(e.endsWith("1 0")&&e.includes("|"))return{capability:"segments",segmentArray:"pipestatus"}}const o=i(t,["-c","( set -o pipefail ) 2>/dev/null && set -o pipefail; false | true"],{timeout:e});return o.error||0===o.status?{capability:"none"}:{capability:"pipefail"}}export function parsePipeSegments(e){const t=e.split(/\s+/u).filter(e=>e.length>0).map(e=>Number.parseInt(e,10));if(0!==t.length&&!t.some(e=>!Number.isFinite(e)))return t}export function buildSegmentCaptureWrapper(e,t){return`trap '${`__roll_pipe_status="\${${t}[*]:-}"`}; ${`[ -n "\${${PIPE_STATUS_ENV}:-}" ] && printf "%s\\n" "$__roll_pipe_status" >"\${${PIPE_STATUS_ENV}}" 2>/dev/null`}' EXIT; ${e}`}export const SIGPIPE_BENIGN_NOTE="管道中有上游阶段被下游提前关闭(SIGPIPE,退出码 141),按良性处理;下游输出可能不完整";export const SIGPIPE_FALLBACK_NOTE="退出码 141:上游被下游提前关闭(SIGPIPE),输出可能完整;当前 shell 无逐段状态,未视为失败";export function evaluatePipelineExit(e){const i=e.segments;if("segments"===e.capability&&void 0!==i&&i.length>0){const n=i[i.length-1]??e.exitCode;if(n!==e.exitCode)return t(e.exitCode);const o=i.slice(0,-1),s=o.every(e=>0===e||141===e),r=o.some(e=>141===e);if(0===n&&s)return{ok:!0,effectiveExitCode:0,...r?{note:SIGPIPE_BENIGN_NOTE}:{}};const p=o.find(e=>0!==e&&141!==e);return{ok:!1,effectiveExitCode:void 0!==p?p:n}}return t(e.exitCode)}function t(e){return 0===e?{ok:!0,effectiveExitCode:0}:141===e?{ok:!0,effectiveExitCode:141,note:SIGPIPE_FALLBACK_NOTE}:{ok:!1,effectiveExitCode:e}}
|
package/dist/bash/truncate.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export function truncateMiddle(t,e){const n=Array.from(t);if(n.length<=e)return{text:t,truncated:!1,removed:0};if(e<=0)return{text:"",truncated:!0,removed:n.length};const r=Math.ceil(e/2),
|
|
1
|
+
export function truncateMiddle(t,e){const n=Array.from(t);if(n.length<=e)return{text:t,truncated:!1,removed:0};if(e<=0)return{text:"",truncated:!0,removed:n.length};const r=Math.ceil(e/2),i=Math.floor(e/2),c=n.length-r-i,o=n.slice(0,r).join(""),l=n.slice(n.length-i).join("");return{text:`${o}\n…${String(c)} chars truncated(保留前 ${String(r)} 与后 ${String(i)} 字符,全文 ${String(n.length)} 字符)…\n${l}`,truncated:!0,removed:c}}
|
|
@@ -7,11 +7,12 @@ import type { ContextCompactionReason, ContextCompactionStrategy, SessionEvent,
|
|
|
7
7
|
import type { ToolPolicy } from "../types/policy.ts";
|
|
8
8
|
import { type AgentToolSource } from "../tool-bridge/build-tools.ts";
|
|
9
9
|
import { type AgentInstallToolCatalogEntry, type AgentInstallToolOutcome } from "../tool-bridge/agent-install-tool.ts";
|
|
10
|
+
import { type SessionFileToolsSettings } from "../tool-bridge/file-tools/index.ts";
|
|
10
11
|
import { type SessionBashSettings } from "../tool-bridge/bash-tool.ts";
|
|
11
12
|
import type { ShellProfile } from "../bash/profile.ts";
|
|
12
13
|
import type { CommandClassifier } from "../types/command-classification.ts";
|
|
13
14
|
import { type RedactedToolExecutionRecordSummary, type ToolExecutionRecord } from "../tool-bridge/tool-execution-record.ts";
|
|
14
|
-
import type { CommitCompactionInput, ListToolExecutionsOptions, ListTranscriptMessagesOptions, SequencedToolExecutionRecord } from "../store/thread-store.ts";
|
|
15
|
+
import type { AppendMessagesOptions, CommitCompactionInput, ListToolExecutionsOptions, ListTranscriptMessagesOptions, SequencedToolExecutionRecord } from "../store/thread-store.ts";
|
|
15
16
|
import { type CapabilityAgentOnboardingCatalogEntry, type CapabilityExternalDynamicContext, type CapabilityHostMode, type EffectiveCapabilityTurnContext, type EffectiveCapabilityManifest } from "./capability-manifest.ts";
|
|
16
17
|
import { type ArchivedTranscriptMessage, type CompactionCheckpoint } from "./compaction-checkpoint.ts";
|
|
17
18
|
import { type TranscriptReader } from "../tool-bridge/transcript-tool.ts";
|
|
@@ -34,11 +35,12 @@ export interface AgentSessionOptions {
|
|
|
34
35
|
readonly maxSteps: number;
|
|
35
36
|
readonly policy?: ToolPolicy;
|
|
36
37
|
readonly initialMessages?: readonly ModelMessage[];
|
|
37
|
-
readonly onPersist?: (messages: readonly ModelMessage[]) => void;
|
|
38
|
+
readonly onPersist?: (messages: readonly ModelMessage[], options?: AppendMessagesOptions) => void;
|
|
38
39
|
readonly onReplace?: (messages: readonly ModelMessage[]) => void;
|
|
39
40
|
readonly onToolExecution?: (record: ToolExecutionRecord) => void;
|
|
40
41
|
readonly listToolExecutions?: (options?: ListToolExecutionsOptions) => readonly SequencedToolExecutionRecord[];
|
|
41
42
|
readonly getToolExecution?: (executionId: string) => SequencedToolExecutionRecord | undefined;
|
|
43
|
+
readonly recoverUncoveredToolExecutions?: () => readonly ModelMessage[];
|
|
42
44
|
readonly initialCheckpoint?: CompactionCheckpoint;
|
|
43
45
|
readonly listTranscriptMessages?: (options?: ListTranscriptMessagesOptions) => readonly ArchivedTranscriptMessage[];
|
|
44
46
|
readonly commitCompaction?: (input: CommitCompactionInput) => CompactionCheckpoint;
|
|
@@ -60,6 +62,7 @@ export interface AgentSessionOptions {
|
|
|
60
62
|
readonly capabilityContext?: AgentSessionCapabilityContext;
|
|
61
63
|
readonly resolveDynamicCapabilityContext?: (abortSignal: AbortSignal) => CapabilityExternalDynamicContext | Promise<CapabilityExternalDynamicContext>;
|
|
62
64
|
readonly skillLibrary?: SkillLibrary;
|
|
65
|
+
readonly fileTools?: SessionFileToolsSettings;
|
|
63
66
|
readonly bash?: SessionBashSettings;
|
|
64
67
|
readonly bashClassifier?: CommandClassifier;
|
|
65
68
|
readonly bashSession?: AgentSessionBashSession;
|
|
@@ -113,9 +116,11 @@ export declare class AgentSession {
|
|
|
113
116
|
private readonly onToolExecution;
|
|
114
117
|
private readonly listPersistedToolExecutions;
|
|
115
118
|
private readonly getPersistedToolExecution;
|
|
119
|
+
private readonly recoverPersistedToolExecutionContext;
|
|
116
120
|
private readonly listPersistedTranscriptMessages;
|
|
117
121
|
private readonly commitPersistedCompaction;
|
|
118
122
|
private readonly inMemoryToolExecutions;
|
|
123
|
+
private readonly uncoveredToolExecutions;
|
|
119
124
|
private readonly inMemoryTranscript;
|
|
120
125
|
private readonly legacyV1ActiveSnapshot;
|
|
121
126
|
private readonly compactionResources;
|
|
@@ -157,6 +162,10 @@ export declare class AgentSession {
|
|
|
157
162
|
private closed;
|
|
158
163
|
private sessionUsage;
|
|
159
164
|
private lastInputTokens;
|
|
165
|
+
private lastStepOutputTokens;
|
|
166
|
+
private lastStepToolResultTokens;
|
|
167
|
+
private measuredMessageCount;
|
|
168
|
+
private promptOverhead;
|
|
160
169
|
private needsCompaction;
|
|
161
170
|
constructor(options: AgentSessionOptions);
|
|
162
171
|
private compileCapabilityManifest;
|
|
@@ -173,13 +182,19 @@ export declare class AgentSession {
|
|
|
173
182
|
compact(reason?: ContextCompactionReason): AsyncIterable<SessionEvent>;
|
|
174
183
|
private runTurn;
|
|
175
184
|
private persistMessages;
|
|
185
|
+
private recordPersistedMessagesInMemory;
|
|
186
|
+
private reconcileUncoveredToolExecutionContext;
|
|
176
187
|
private persistContextFailure;
|
|
188
|
+
private persistFailedTurn;
|
|
189
|
+
private failedTurnContextMessage;
|
|
190
|
+
private failedTurnDisplayMessage;
|
|
191
|
+
private appendInterruptedTurnMessages;
|
|
177
192
|
private persistToolExecution;
|
|
178
193
|
private rememberCompactionResources;
|
|
179
194
|
private retainCompactionResource;
|
|
180
195
|
private interactionDeadlineMs;
|
|
181
196
|
private requestApproval;
|
|
182
|
-
approve(approvalId: string): boolean;
|
|
197
|
+
approve(approvalId: string, scope?: "once" | "session"): boolean;
|
|
183
198
|
reject(approvalId: string, reason?: string): boolean;
|
|
184
199
|
getMessages(): readonly ModelMessage[];
|
|
185
200
|
getToolExecutions(options?: ListToolExecutionsOptions, includeRaw?: boolean): readonly SessionToolExecutionRecordView[];
|
|
@@ -190,6 +205,13 @@ export declare class AgentSession {
|
|
|
190
205
|
getSessionUsage(): SessionTokenUsage;
|
|
191
206
|
getSkillSummaries(): readonly SessionSkillSummary[];
|
|
192
207
|
setProviderOptions(providerOptions: SharedV4ProviderOptions | undefined): void;
|
|
208
|
+
private runAutoCompactionPasses;
|
|
209
|
+
private stopOnContextPressure;
|
|
210
|
+
private contextPressureTokens;
|
|
211
|
+
private promptOverheadTokens;
|
|
212
|
+
private currentCheckpointReminder;
|
|
213
|
+
private persistPausedTurnCancellation;
|
|
214
|
+
private compactionTargetTokens;
|
|
193
215
|
private shouldAutoCompact;
|
|
194
216
|
private listCompactionTranscriptEvidence;
|
|
195
217
|
private listCompactionToolEvidence;
|
|
@@ -213,7 +235,10 @@ export declare class AgentSession {
|
|
|
213
235
|
private cancellationDisplayMessage;
|
|
214
236
|
private cancellationContextMessage;
|
|
215
237
|
private emitCancellation;
|
|
238
|
+
private persistCancelledRecoveryTurn;
|
|
216
239
|
private persistCancelledTurn;
|
|
240
|
+
private cancellationRecordMessages;
|
|
241
|
+
private persistPendingToolCancellationsOrReport;
|
|
217
242
|
private persistPendingToolCancellations;
|
|
218
243
|
cancel(): boolean;
|
|
219
244
|
close(): Promise<void>;
|