@robota-sdk/agent-framework 3.0.0-beta.78 → 3.0.0-beta.81
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/README.md +190 -41
- package/dist/node/createInteractiveRuntime-CKt44Pva.d.cts +9457 -0
- package/dist/node/createInteractiveRuntime-CKt44Pva.d.cts.map +1 -0
- package/dist/node/createInteractiveRuntime-GD7gJ7ig.d.ts +9457 -0
- package/dist/node/createInteractiveRuntime-GD7gJ7ig.d.ts.map +1 -0
- package/dist/node/index.cjs +29 -3
- package/dist/node/index.d.cts +1646 -0
- package/dist/node/index.d.cts.map +1 -0
- package/dist/node/index.d.ts +1350 -189
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +29 -3
- package/dist/node/index.js.map +1 -1
- package/dist/node/interactive-BpTvVVtf.cjs +122 -0
- package/dist/node/interactive-Bqe03GGe.js +123 -0
- package/dist/node/interactive-Bqe03GGe.js.map +1 -0
- package/dist/node/testing/index.cjs +2 -2
- package/dist/node/testing/index.d.cts +240 -0
- package/dist/node/testing/index.d.cts.map +1 -0
- package/dist/node/testing/index.d.ts +98 -15
- package/dist/node/testing/index.d.ts.map +1 -1
- package/dist/node/testing/index.js +2 -2
- package/dist/node/testing/index.js.map +1 -1
- package/package.json +70 -24
- package/dist/node/index-BeYNnJed.d.ts +0 -2656
- package/dist/node/index-BeYNnJed.d.ts.map +0 -1
- package/dist/node/index-DLFjpsfm.d.ts +0 -2658
- package/dist/node/index-DLFjpsfm.d.ts.map +0 -1
- package/dist/node/interactive-C93XBn4U.js +0 -111
- package/dist/node/interactive-C93XBn4U.js.map +0 -1
- package/dist/node/interactive-D1dVksoo.cjs +0 -110
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../interactive-
|
|
2
|
-
`).filter(e=>e.trim().length>0).map(e=>JSON.parse(e))}toolCalls(){return this.completions.flatMap(e=>e.toolSummaries)}emittedEvents(e){return this.events.get(e)??[]}readFile(e){return(0,r.readFileSync)((0,t.join)(this.cwd,e),`utf8`)}exists(e){return(0,r.existsSync)((0,t.join)(this.cwd,e))}files(){let e=[],n=i=>{for(let a of(0,r.readdirSync)(i,{withFileTypes:!0})){if(a.name===`.robota`)continue;let r=(0,t.join)(i,a.name);a.isDirectory()?n(r):e.push((0,t.relative)(this.cwd,r).split(t.sep).join(`/`))}};return n(this.cwd),e.sort()}async dispose(){this.disposed||(this.disposed=!0,await this.session.shutdown({reason:`other`,message:`functional test complete`}),this.ownsWorkspace&&(0,r.rmSync)(this.cwd,{recursive:!0,force:!0,maxRetries:5,retryDelay:20}))}};function s(e){return new o(e)}const c={usedTokens:0,maxTokens:2e5,usedPercentage:0,remainingPercentage:100},l={sessionId:`test-session-id`,updatedAt:new Date().toISOString(),entries:[]},u={id:`test-goal`,objective:`test goal`,status:`active`,iterations:0,maxIterations:25,startedAt:new Date().toISOString(),progress:[]},d={id:``,parentSessionId:`test-session-id`,waitPolicy:`wait_all`,taskIds:[],status:`completed`,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString(),results:[]};function f(e){return{submit:()=>Promise.resolve(),abort:()=>{},cancelQueue:()=>{},shutdown:()=>Promise.resolve(),isExecuting:()=>!1,getPendingPrompt:()=>null,getMessages:()=>[],getContextState:()=>({...c}),getSession:()=>({getSessionId:()=>`test-session-id`}),getCwd:()=>`/workspace`,executeCommand:()=>Promise.resolve(null),listCommands:()=>[],on:()=>{},off:()=>{},listBackgroundTasks:()=>[],getBackgroundTask:()=>void 0,cancelBackgroundTask:()=>Promise.resolve(),closeBackgroundTask:()=>Promise.resolve(),sendBackgroundTask:()=>Promise.resolve(),readBackgroundTaskLog:()=>Promise.resolve({taskId:``,lines:[]}),listBackgroundJobGroups:()=>[],getBackgroundJobGroup:()=>void 0,createBackgroundJobGroup:()=>({...d}),waitBackgroundJobGroup:()=>Promise.resolve({...d}),getExecutionWorkspaceSnapshot:()=>({...l}),listAgentDefinitions:()=>[],listAgentJobs:()=>[],spawnAgentJob:()=>Promise.resolve({id:`agent_1`,type:`general-purpose`,label:`general-purpose`,parentSessionId:`test-session-id`,status:`running`,mode:`background`,depth:1,cwd:`/workspace`,promptPreview:``,updatedAt:new Date().toISOString()}),sendAgentJob:()=>Promise.resolve(),cancelAgentJob:()=>Promise.resolve(),closeAgentJob:()=>Promise.resolve(),setGoal:()=>Promise.resolve({...u}),getGoalState:()=>null,cancelGoal:()=>null,...e}}exports.ScriptedSessionHarness=o,Object.defineProperty(exports,"createScriptedProvider",{enumerable:!0,get:function(){return i.createScriptedProvider}}),exports.createTestInteractiveSession=f,exports.scriptedSession=s;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../interactive-BpTvVVtf.cjs");let t=require("node:path"),n=require("@robota-sdk/agent-executor"),r=require("@robota-sdk/agent-session"),i=require("node:fs"),a=require("node:os"),o=require("@robota-sdk/agent-core/testing");function s(e){return{turnSource:`peer`,driverId:`peer:${e}`}}function c(e){return(0,t.join)(e,`.robota`,`logs`)}function l(e,n){return(0,t.join)(c(e),`${n}.jsonl`)}function u(e,t){let n=l(e,t);return(0,i.existsSync)(n)?(0,i.readFileSync)(n,`utf8`):``}function d(e,t){return u(e,t).split(`
|
|
2
|
+
`).filter(e=>e.trim().length>0).map(e=>JSON.parse(e))}function f(e,n){return(0,i.readFileSync)((0,t.join)(e,n),`utf8`)}function p(e,n){return(0,i.existsSync)((0,t.join)(e,n))}function m(e){let n=[],r=a=>{for(let o of(0,i.readdirSync)(a,{withFileTypes:!0})){if(o.name===`.robota`)continue;let i=(0,t.join)(a,o.name);o.isDirectory()?r(i):n.push((0,t.relative)(e,i).split(t.sep).join(`/`))}};return r(e),n.sort()}const h=[`text_delta`,`tool_start`,`tool_end`,`thinking`,`complete`,`interrupted`,`error`,`context_update`,`goal_event`,`turn_source`,`user_message`,`background_task_event`];var g=class{cwd;session;requests;events=new Map;completions=[];sessionStore;ownsWorkspace;disposed=!1;constructor(s){if(this.ownsWorkspace=s.cwd===void 0,this.cwd=s.cwd??(0,i.realpathSync)((0,i.mkdtempSync)((0,t.join)((0,a.tmpdir)(),`robota-fxn-`))),this.ownsWorkspace)for(let[e,n]of Object.entries(s.files??{})){let r=(0,t.join)(this.cwd,e);(0,i.mkdirSync)((0,t.dirname)(r),{recursive:!0}),(0,i.writeFileSync)(r,n,`utf8`)}if([s.turns,s.cassette,s.record].filter(e=>e!==void 0).length!==1)throw Error("scriptedSession requires exactly one of `turns`, `cassette`, or `record`.");let c;c=s.cassette?(0,o.createReplayProvider)({cassettePath:s.cassette,scrub:[this.cwd],rewriteCwd:this.cwd}):s.record?(0,o.createRecordingProvider)({provider:s.record.provider,cassettePath:s.record.toCassette,recordCwd:this.cwd}):(0,o.createScriptedProvider)(this.substituteWorkspacePath(s.turns??[])).provider,this.requests=[];let l={...c,chat:async(e,t)=>(this.requests.push([...e]),await s.beforeProviderCall?.(),c.chat(e,t))},u=(0,t.join)(this.cwd,`.robota`,`sessions`);this.sessionStore=s.persistence?new r.NodeSessionStore(u):void 0;let d;if(s.permissions!==void 0||s.hooks!==void 0){d=(0,t.join)(this.cwd,`.robota-test-user-settings.json`);let e={...s.permissions===void 0?{}:{permissions:s.permissions},...s.hooks===void 0?{}:{hooks:s.hooks}};(0,i.writeFileSync)(d,JSON.stringify(e),`utf8`)}this.session=new e.b({cwd:this.cwd,provider:l,...d===void 0?{}:{userSettingsSources:[e.yr(`user`,d)]},...s.projectAccess?{projectAccess:s.projectAccess}:{},...s.sandboxClient?{sandboxClient:s.sandboxClient}:{},...s.contributionSources===void 0?{}:{contributionSources:s.contributionSources},...s.skillRoots===void 0?{}:{skillRoots:s.skillRoots},...s.resolveDefaultLoopPrompt?{resolveDefaultLoopPrompt:s.resolveDefaultLoopPrompt}:{},...s.agentDefinitionRoots===void 0?{}:{agentDefinitionRoots:s.agentDefinitionRoots},bare:s.bare??!0,permissionMode:s.permissionMode??`bypassPermissions`,...s.allowedTools?{allowedTools:s.allowedTools}:{},...s.deniedTools?{deniedTools:s.deniedTools}:{},...this.sessionStore?{sessionStore:this.sessionStore}:{},sessionLogSink:new r.NodeSessionLogSink((0,t.join)(this.cwd,`.robota`,`logs`)),...s.resumeSessionId?{resumeSessionId:s.resumeSessionId}:{},...s.forkSession?{forkSession:s.forkSession}:{},...s.workspaceMovedFrom===void 0?{}:{workspaceMovedFrom:s.workspaceMovedFrom},...s.commandModules?{commandModules:s.commandModules}:{},...s.backgroundTasks?{backgroundTaskRunners:(0,n.createDefaultBackgroundTaskRunners)()}:{},...s.maxTurns===void 0?{}:{maxTurns:s.maxTurns},...s.model===void 0?{}:{model:s.model},...s.terminalHandoff?{terminalHandoff:s.terminalHandoff}:{},...s.additionalTools?{additionalTools:s.additionalTools}:{},...s.backgroundTaskRunners?{backgroundTaskRunners:s.backgroundTaskRunners}:{},...s.toolCallHandoff?{toolCallHandoff:s.toolCallHandoff}:{}});for(let e of h)this.session.on(e,((...t)=>{this.record(e,t),(e===`complete`||e===`interrupted`)&&this.completions.push(t[0])}));if(s.askHandler){let e=s.askHandler;this.session.on(`ask_request`,({id:t,request:n})=>{Promise.resolve(e(n)).then(e=>this.session.resolveAsk(t,e)).catch(()=>this.session.resolveAsk(t,{type:`cancelled`}))})}}substituteWorkspacePath(e){return e.map(e=>`toolCalls`in e?{toolCalls:e.toolCalls.map(e=>({name:e.name,args:JSON.parse(JSON.stringify(e.args).split(`{{cwd}}`).join(this.cwd))}))}:e)}record(e,t){let n=this.events.get(e)??[];n.push(t),this.events.set(e,n)}async submit(e){let t=this.nextSettledTurn();return await this.session.submit(e),t}async runGoal(e,t={}){let n=new Promise((e,t)=>{let n=t=>{t.type===`goal_stopped`&&(i(),e(t.goal))},r=e=>{i(),t(e)},i=()=>{this.session.off(`goal_event`,n),this.session.off(`error`,r)};this.session.on(`goal_event`,n),this.session.on(`error`,r)});return await this.session.setGoal(e,t.maxIterations?{maxIterations:t.maxIterations}:{}),n}command(e,t=``){return this.session.executeCommand(e,t)}async wake(e,t){return this.session.requestWakeup(e,t)?this.nextSettledTurn():null}async submitPeer(e,t){let n=this.nextSettledTurn();return await this.session.submit(e,void 0,void 0,s(t)),n}awaitEvent(e,t){return new Promise(n=>{let r=((...i)=>{let a=i;t&&!t(...a)||(this.session.off(e,r),n(a))});this.session.on(e,r)})}nextSettledTurn(){return new Promise((e,t)=>{let n=t=>{i(),e(t)},r=e=>{i(),t(e)},i=()=>{this.session.off(`complete`,n),this.session.off(`interrupted`,n),this.session.off(`error`,r)};this.session.on(`complete`,n),this.session.on(`interrupted`,n),this.session.on(`error`,r)})}history(){return this.session.getMessages()}sessionRecord(){if(!this.sessionStore)return;let e=this.sessionStore.load(this.session.getSession().getSessionId());return e.status===`valid`?e.record:void 0}sessionLog(){return{id:this.session.getSession().getSessionId(),history:this.session.getFullHistory()}}logsDir(){return c(this.cwd)}transcriptPath(){return l(this.cwd,this.session.getSession().getSessionId())}transcript(){return u(this.cwd,this.session.getSession().getSessionId())}logEntries(){return d(this.cwd,this.session.getSession().getSessionId())}toolCalls(){return this.completions.flatMap(e=>e.toolSummaries)}emittedEvents(e){return this.events.get(e)??[]}readFile(e){return f(this.cwd,e)}exists(e){return p(this.cwd,e)}files(){return m(this.cwd)}async dispose(){this.disposed||(this.disposed=!0,await this.session.shutdown({reason:`other`,message:`functional test complete`}),this.ownsWorkspace&&(0,i.rmSync)(this.cwd,{recursive:!0,force:!0,maxRetries:5,retryDelay:20}))}};function _(e){return new g(e)}const v=`1970-01-01T00:00:00.000Z`,y=`/robota-test-command-host`;function b(e,t){let n={...e};for(let[e,r]of Object.entries(t??{}))r!==void 0&&(n[e]=r);return n}const x={id:`test-agent-job`,type:`general-purpose`,label:`test`,parentSessionId:`test-command-host`,status:`running`,mode:`background`,depth:1,cwd:y,promptPreview:``,updatedAt:v},S={id:`test-group`,parentSessionId:`test-command-host`,waitPolicy:`wait_all`,taskIds:[],status:`running`,createdAt:v,updatedAt:v,results:[]},C={id:`test-background-task`,kind:`agent`,label:`test`,status:`running`,mode:`background`,parentSessionId:`test-command-host`,depth:1,cwd:y,updatedAt:v,unread:!1};function w(e){return b({listAgentDefinitions:()=>[],listAgentJobs:()=>[],spawnAgentJob:()=>Promise.resolve(x),sendAgentJob:()=>Promise.resolve(),cancelAgentJob:()=>Promise.resolve(),closeAgentJob:()=>Promise.resolve(),createBackgroundJobGroup:()=>S,waitBackgroundJobGroup:()=>Promise.resolve(S),spawnScheduledWake:()=>Promise.resolve(C),listSchedules:()=>[],pauseSchedule:()=>Promise.resolve(),resumeSchedule:()=>Promise.resolve(),editSchedule:()=>Promise.resolve(),spawnMonitorWake:()=>Promise.resolve(C),readBackgroundTaskLog:e=>Promise.resolve({taskId:e,lines:[]})},e)}const T={target:{id:`test-checkpoint`,sessionId:`test-command-host`,sequence:0,prompt:``,createdAt:v,fileCount:0},restoredCheckpointCount:0,restoredFileCount:0,removedCheckpointCount:0},E={maxTokens:0,usedTokens:0,usedPercentage:0,remainingPercentage:100},D={id:`test-goal`,objective:``,status:`stopped`,iterations:0,maxIterations:0,startedAt:v,progress:[]},O={id:`test-plan`,objective:``,steps:[],phase:`planning`,createdAt:v},k={},A={loadStartupMemory:()=>Promise.resolve({content:``,path:``,lineCount:0,truncated:!1}),list:()=>Promise.resolve({indexPath:``,topicsPath:``,topics:[]}),readTopic:()=>Promise.resolve(``),append:e=>Promise.resolve({indexPath:``,topicPath:``,topic:e.topic,deduplicated:!1}),recall:()=>Promise.resolve({content:``,references:[],truncated:!1}),getPending:()=>Promise.resolve(void 0),listPending:()=>Promise.resolve([]),markPending:(e,t,n)=>Promise.resolve({id:e,type:`project`,topic:``,text:``,sourceMessageIds:[],confidence:0,createdAt:v,reason:n,status:t,updatedAt:v}),upsertPending:()=>Promise.resolve()};let j=0;function M(e){let t=[];return b({getSessionId:()=>`test-command-host-${j}`,getHistory:()=>[],getFullHistory:()=>[],getMessageCount:()=>0,clearHistory:()=>{},compact:()=>Promise.resolve(),getContextState:()=>E,getPermissionMode:()=>`default`,setPermissionMode:()=>{},getSessionAllowedTools:()=>[],getPermissionRules:()=>({allow:[],deny:[],ask:[]}),getRecentPermissionDenials:()=>[],retryPermissionDenial:()=>void 0,applyPresetToolLists:e=>{t.push(e)},getAutoCompactThreshold:()=>!1,setAutoCompactThreshold:()=>{},getSessionTokenUsage:()=>void 0,getModelId:()=>void 0,getModelEffort:()=>`high`,getOfferedToolSchemas:()=>[],addTools:async()=>[],applyModelOptions:()=>{},applyAgentName:()=>{},getActivePresetId:()=>`default`,setActivePresetId:()=>{},setParallelSubagentsEnabled:()=>{}},e)}function N(e={}){j+=1;let t=e.cwd??`/robota-test-command-host-${j}`,n=M(e.session);return b({getSession:()=>n,validateCurrentSessionReplayLog:()=>({logFile:`${t}/session.jsonl`,entryCount:0,validation:{ok:!0,issues:[]}}),getCwd:()=>t,getCommandInvocationSource:()=>`user`,clearConversationHistory:()=>{},getSessionUsage:()=>[],forkSession:e=>Promise.resolve({sessionId:`test-command-host-${j}-fork`,name:e?.name??`test-command-host-${j} (fork)`}),getUserInteraction:()=>void 0,getActiveOutputStyleId:()=>`default`,applyPersona:()=>{},applySelfVerification:()=>{},applyResponseLanguage:()=>{},applyOutputStyle:()=>{},applyPresetSystemPrompt:()=>{},applyCommandModuleSelection:()=>[],getAutoCompactThresholdSource:()=>`session`,setAutoCompactThreshold:()=>{},listCheckpointBranches:()=>[],forkCheckpointBranch:()=>Promise.resolve(T),switchCheckpointBranch:()=>{},setGoal:()=>Promise.resolve(D),getGoalState:()=>null,cancelGoal:()=>null,setPlan:()=>Promise.resolve(O),getPlanState:()=>null,approvePlan:()=>O,revertPlan:()=>O,getMemoryStore:()=>A,runWithTerminal:e=>e(),getContextState:()=>E,getAutoCompactThreshold:()=>!1,compactContext:()=>Promise.resolve(),listCommands:()=>[],listSkills:()=>[],executeSkillCommandByName:()=>Promise.resolve(null),listContextReferences:()=>[],addContextReference:()=>Promise.resolve({evicted:[],diagnostics:[]}),removeContextReference:()=>({}),clearContextReferences:()=>({removed:[]}),listEditCheckpoints:()=>[],inspectEditCheckpoint:()=>({target:T.target,capturedFiles:[],restoreToCheckpoint:{checkpointIds:[],fileCount:0},rollbackThroughCheckpoint:{checkpointIds:[],fileCount:0}}),restoreEditCheckpoint:()=>Promise.resolve(T),rollbackEditCheckpoint:()=>Promise.resolve(T),getUsedMemoryReferences:()=>[],recordMemoryEvent:()=>{},listBackgroundTasks:()=>[],readBackgroundTaskLog:e=>Promise.resolve({taskId:e,lines:[]}),cancelBackgroundTask:()=>Promise.resolve(),closeBackgroundTask:()=>Promise.resolve(),getCommandHostAdapters:()=>k,canHandoffTerminal:()=>!1,getAgentJobCapability:()=>w()},e.overrides)}function P(t,n){return e.m(t,()=>n)}exports.ScriptedSessionHarness=g,exports.createInteractiveRuntimeForTesting=P,exports.createTestAgentJobHost=w,exports.createTestCommandHost=N,exports.createTestSessionRuntime=M,exports.scriptedSession=_;
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { Cn as IContributionSource, Fa as ICommandModule, Lt as IToolCallHandoffPolicy, Pc as IAgentJobHostContext, Sc as TWorkspaceProjectAccess, g as IInteractiveSession$1, gn as ISkillRootDescriptor, hl as ICommandSessionRuntime, i as IInteractiveRuntime, l as InteractiveSession, n as IInteractiveRuntimeTestOptions, qa as ICommandHostContext } from "../createInteractiveRuntime-CKt44Pva.cjs";
|
|
2
|
+
import { IExecutionResult, IGoalState, IInteractiveSessionEvents, IInteractiveSessionRecord, ITerminalHandoff, IToolSummary, TInteractiveEventName } from "@robota-sdk/agent-interface-session";
|
|
3
|
+
import { IAIProvider, IToolWithEventService, IUserInteraction, THooksConfig, TPermissionMode, TUniversalMessage } from "@robota-sdk/agent-core";
|
|
4
|
+
import { ICommandResult } from "@robota-sdk/agent-interface-command";
|
|
5
|
+
import { IBackgroundTaskRunner } from "@robota-sdk/agent-executor";
|
|
6
|
+
import { ISandboxClient } from "@robota-sdk/agent-tools";
|
|
7
|
+
import { TScriptedTurn } from "@robota-sdk/agent-core/testing";
|
|
8
|
+
//#region src/testing/scripted-session-harness.d.ts
|
|
9
|
+
/** Options for {@link scriptedSession}. Provide exactly one of `turns`, `cassette`, or `record`. */
|
|
10
|
+
interface IScriptedSessionOptions {
|
|
11
|
+
/** Scripted assistant turns replayed deterministically through the real loop. */
|
|
12
|
+
turns?: readonly TScriptedTurn[];
|
|
13
|
+
/**
|
|
14
|
+
* CMD-005: answer model-issued questions (AskUserQuestion) programmatically. When set, the harness
|
|
15
|
+
* subscribes to the session's `ask_request` event and answers via `resolveAsk` (REMOTE-007). Absent ⇒
|
|
16
|
+
* nothing subscribes, so a model-issued question fails closed (each question `cancelled`) — the
|
|
17
|
+
* headless no-human path.
|
|
18
|
+
*/
|
|
19
|
+
askHandler?: IUserInteraction['ask'];
|
|
20
|
+
/**
|
|
21
|
+
* Path to a recorded cassette (TEST-005). Replays a real model's captured prompts + tool-use
|
|
22
|
+
* deterministically through the real loop. The workspace path is rewritten/scrubbed automatically.
|
|
23
|
+
*/
|
|
24
|
+
cassette?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Record mode (TEST-005): drive the session with a REAL provider and capture every interaction to
|
|
27
|
+
* `toCassette` for later deterministic replay. Used in a one-off keyed record run, not in CI.
|
|
28
|
+
*/
|
|
29
|
+
record?: {
|
|
30
|
+
provider: IAIProvider;
|
|
31
|
+
toCassette: string;
|
|
32
|
+
};
|
|
33
|
+
/** Awaited before every provider call, so a test can hold a turn open while it observes. */
|
|
34
|
+
beforeProviderCall?: () => Promise<void>;
|
|
35
|
+
/** Seed files written into the workspace before the session starts (workspace-relative paths). */
|
|
36
|
+
files?: Record<string, string>;
|
|
37
|
+
/** Persist sessions to a real store in the workspace (enables resume/record assertions). */
|
|
38
|
+
persistence?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Reuse an existing workspace directory instead of a fresh temp one. Required for multi-session
|
|
41
|
+
* resume/fork (the resumed session must read the same store). The harness does not delete a
|
|
42
|
+
* workspace it did not create.
|
|
43
|
+
*/
|
|
44
|
+
cwd?: string;
|
|
45
|
+
/** Explicit host-issued project authority for contribution-discovery fixtures. */
|
|
46
|
+
projectAccess?: TWorkspaceProjectAccess;
|
|
47
|
+
/** Explicit host contribution sources used by skill discovery fixtures. */
|
|
48
|
+
contributionSources?: readonly IContributionSource[];
|
|
49
|
+
/** Ordered host-owned skill roots used by skill discovery fixtures. */
|
|
50
|
+
skillRoots?: readonly ISkillRootDescriptor[];
|
|
51
|
+
resolveDefaultLoopPrompt?: () => string;
|
|
52
|
+
/** Ordered host-owned agent-definition roots for discovery tests. */
|
|
53
|
+
agentDefinitionRoots?: readonly string[];
|
|
54
|
+
/** Resume a persisted session by id (multi-session). Requires `persistence` + the same `cwd`. */
|
|
55
|
+
resumeSessionId?: string;
|
|
56
|
+
/** Fork the resumed session into a new id while restoring its context (multi-session). */
|
|
57
|
+
forkSession?: boolean;
|
|
58
|
+
/** Issue #3081: the session is the target of a `/cd` from this directory. */
|
|
59
|
+
workspaceMovedFrom?: string;
|
|
60
|
+
/** Command modules composed into the session (e.g. the `/goal` module). */
|
|
61
|
+
commandModules?: readonly ICommandModule[];
|
|
62
|
+
/** Enable the real background-task runners for schedule/monitor functional tests. */
|
|
63
|
+
backgroundTasks?: boolean;
|
|
64
|
+
/** Permission posture. Defaults to `bypassPermissions` so tools run unattended. */
|
|
65
|
+
permissionMode?: TPermissionMode;
|
|
66
|
+
/** Pre-approved tool names. */
|
|
67
|
+
allowedTools?: string[];
|
|
68
|
+
/** Denied tool names (deny wins over allow). */
|
|
69
|
+
deniedTools?: string[];
|
|
70
|
+
/**
|
|
71
|
+
* Permission PATTERNS (`Bash(rm *)`), as a user's settings file would carry them — read through a
|
|
72
|
+
* host settings source, the route the product uses. Tool-name lists are `allowedTools`/`deniedTools`.
|
|
73
|
+
*/
|
|
74
|
+
permissions?: {
|
|
75
|
+
allow?: string[];
|
|
76
|
+
deny?: string[];
|
|
77
|
+
ask?: string[];
|
|
78
|
+
};
|
|
79
|
+
/** Hook configuration, written into the same user settings file as `permissions`. */
|
|
80
|
+
hooks?: THooksConfig;
|
|
81
|
+
/** A sandbox client, as a product that confines commands supplies one. */
|
|
82
|
+
sandboxClient?: ISandboxClient;
|
|
83
|
+
/** Skip AGENTS.md/CLAUDE.md and plugin discovery for determinism. Defaults to `true`. */
|
|
84
|
+
bare?: boolean;
|
|
85
|
+
/** Cap on agentic rounds per submit. */
|
|
86
|
+
maxTurns?: number;
|
|
87
|
+
/** Model override (e.g. when recording against a real provider whose model differs). */
|
|
88
|
+
model?: string;
|
|
89
|
+
/** TERM-001: inject a (fake) terminal-handoff capability to exercise the handoff orchestration. */
|
|
90
|
+
terminalHandoff?: ITerminalHandoff;
|
|
91
|
+
/** Additional tools registered alongside the default CLI tools (e.g. a fake slow MCP-like tool). */
|
|
92
|
+
additionalTools?: IToolWithEventService[];
|
|
93
|
+
/** Runtime-composed background task runners (e.g. the `tool-invocation` runner, MCP-004). */
|
|
94
|
+
backgroundTaskRunners?: IBackgroundTaskRunner[];
|
|
95
|
+
/** MCP-004 §S3: hand a main-turn tool call exceeding its threshold to a background task. */
|
|
96
|
+
toolCallHandoff?: IToolCallHandoffPolicy;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* A live, scripted, isolated functional-test session. Construct via {@link scriptedSession};
|
|
100
|
+
* always `await dispose()` in a test teardown.
|
|
101
|
+
*/
|
|
102
|
+
declare class ScriptedSessionHarness {
|
|
103
|
+
/** Absolute path of the isolated temp workspace. */
|
|
104
|
+
readonly cwd: string;
|
|
105
|
+
/** The real session under test. */
|
|
106
|
+
readonly session: InteractiveSession;
|
|
107
|
+
/** Message arrays of every provider chat() call, in order, for request assertions. */
|
|
108
|
+
readonly requests: TUniversalMessage[][];
|
|
109
|
+
private readonly events;
|
|
110
|
+
private readonly completions;
|
|
111
|
+
private readonly sessionStore?;
|
|
112
|
+
private readonly ownsWorkspace;
|
|
113
|
+
private disposed;
|
|
114
|
+
constructor(options: IScriptedSessionOptions);
|
|
115
|
+
/**
|
|
116
|
+
* Replace the `{{cwd}}` placeholder in scripted tool-call args with the isolated workspace path,
|
|
117
|
+
* so a test can reference absolute workspace paths it cannot know until the harness is built
|
|
118
|
+
* (e.g. `{ filePath: '{{cwd}}/out.txt' }` or a Bash `workingDirectory`). Keeps the harness free of
|
|
119
|
+
* global `process.cwd()` mutation.
|
|
120
|
+
*/
|
|
121
|
+
private substituteWorkspacePath;
|
|
122
|
+
private record;
|
|
123
|
+
/** Submit a user prompt and resolve with the completed turn result (rejects on `error`). */
|
|
124
|
+
submit(prompt: string): Promise<IExecutionResult>;
|
|
125
|
+
/**
|
|
126
|
+
* Assign an autonomous goal and resolve with the FINAL stopped goal state once the loop ends
|
|
127
|
+
* (satisfied or a bound). Rejects if the session emits `error` first.
|
|
128
|
+
*/
|
|
129
|
+
runGoal(objective: string, options?: {
|
|
130
|
+
maxIterations?: number;
|
|
131
|
+
}): Promise<IGoalState>;
|
|
132
|
+
/** Run a slash command through the real session command pipeline. */
|
|
133
|
+
command(name: string, args?: string): Promise<ICommandResult | null>;
|
|
134
|
+
/**
|
|
135
|
+
* FLOW-002: inject a background/scheduled wake (a non-user `agent-wakeup` turn) and resolve once
|
|
136
|
+
* that turn settles. Mirrors a background task completion or a scheduled fire re-entering the
|
|
137
|
+
* agent loop. Coalesces by `sourceTaskId` exactly as the real wake path does.
|
|
138
|
+
*
|
|
139
|
+
* Returns `null` when the wake was a no-op (coalesced because `sourceTaskId` is already in flight,
|
|
140
|
+
* or the session is shutting down) — no turn runs, so callers must not await one. This prevents the
|
|
141
|
+
* driver from hanging until the test timeout when the wake is dropped.
|
|
142
|
+
*/
|
|
143
|
+
wake(instruction: string, sourceTaskId: string): Promise<IExecutionResult | null>;
|
|
144
|
+
/** PEER-002 (#1809): deliver a message from ANOTHER SESSION; see `peerTurnOptions`. */
|
|
145
|
+
submitPeer(text: string, peerSessionId: string): Promise<IExecutionResult>;
|
|
146
|
+
/** Resolve with the args of the next `event` (optionally matching `predicate`). */
|
|
147
|
+
awaitEvent<E extends TInteractiveEventName>(event: E, predicate?: (...args: Parameters<IInteractiveSessionEvents[E]>) => boolean): Promise<Parameters<IInteractiveSessionEvents[E]>>;
|
|
148
|
+
private nextSettledTurn;
|
|
149
|
+
/** The current conversation messages. */
|
|
150
|
+
history(): TUniversalMessage[];
|
|
151
|
+
/** The persisted session record (requires `persistence: true`), or undefined. */
|
|
152
|
+
sessionRecord(): IInteractiveSessionRecord | undefined;
|
|
153
|
+
/**
|
|
154
|
+
* Neutral session-log accessor (INFRA-025): the id + full history in the shape analysis
|
|
155
|
+
* tooling consumes. Usage assertions compose it with `summarizeUsageBySource` from
|
|
156
|
+
* `@robota-sdk/agent-session-analytics` in the TEST — the harness itself carries no
|
|
157
|
+
* analytics dependency.
|
|
158
|
+
*/
|
|
159
|
+
sessionLog(): {
|
|
160
|
+
id: string;
|
|
161
|
+
history: ReturnType<InteractiveSession['getFullHistory']>;
|
|
162
|
+
};
|
|
163
|
+
/** The real session-log directory the framework writes to (`{cwd}/.robota/logs`). */
|
|
164
|
+
logsDir(): string;
|
|
165
|
+
/** Path of the real JSONL transcript the framework writes for this session. */
|
|
166
|
+
transcriptPath(): string;
|
|
167
|
+
/** Raw contents of the real session transcript (`''` if none was written). */
|
|
168
|
+
transcript(): string;
|
|
169
|
+
/**
|
|
170
|
+
* The real session transcript parsed into structured log entries — the durable record the
|
|
171
|
+
* framework itself writes. Leverages the system's own logging as a verification surface.
|
|
172
|
+
*/
|
|
173
|
+
logEntries(): Array<Record<string, unknown>>;
|
|
174
|
+
/** Every tool call the agent made across all completed turns, in order. */
|
|
175
|
+
toolCalls(): IToolSummary[];
|
|
176
|
+
/** Raw collected args of each emission of `event`. */
|
|
177
|
+
emittedEvents<E extends TInteractiveEventName>(event: E): Array<Parameters<IInteractiveSessionEvents[E]>>;
|
|
178
|
+
/** Read a workspace file (UTF-8). */
|
|
179
|
+
readFile(relPath: string): string;
|
|
180
|
+
/** Whether a workspace file exists. */
|
|
181
|
+
exists(relPath: string): boolean;
|
|
182
|
+
/** List workspace files (relative paths), excluding the `.robota` session/log dir. */
|
|
183
|
+
files(): string[];
|
|
184
|
+
/** Shut the session down and remove the temp workspace. Idempotent. */
|
|
185
|
+
dispose(): Promise<void>;
|
|
186
|
+
}
|
|
187
|
+
/** Build a live, isolated, scripted functional-test session (TEST-003). */
|
|
188
|
+
declare function scriptedSession(options: IScriptedSessionOptions): ScriptedSessionHarness;
|
|
189
|
+
//#endregion
|
|
190
|
+
//#region src/testing/double-overrides.d.ts
|
|
191
|
+
/**
|
|
192
|
+
* ARCH-029: the one guarantee every command-axis double makes about its overrides.
|
|
193
|
+
*
|
|
194
|
+
* It lives here rather than in either double because both make it, and review found the second copy
|
|
195
|
+
* had been re-implemented inline with a comment pointing at "the sibling double" — two copies of a
|
|
196
|
+
* guarantee drift, and this one had already been stated wrongly once.
|
|
197
|
+
*/
|
|
198
|
+
/**
|
|
199
|
+
* An override may replace a member, never remove one.
|
|
200
|
+
*
|
|
201
|
+
* `Partial<T>` admits `{ setPlan: undefined }`, and object spread then writes that `undefined` over
|
|
202
|
+
* the double's answer — reintroducing an ABSENT member at runtime, fully type-checked, which is the
|
|
203
|
+
* exact state ARCH-029 S4 removed.
|
|
204
|
+
*
|
|
205
|
+
* The type alone does NOT close it, and an earlier revision of this comment claimed it did.
|
|
206
|
+
* Measured: `NonNullable` strips `undefined` from the VALUE type, but the `?` modifier re-admits it
|
|
207
|
+
* unless `exactOptionalPropertyTypes` is on, and it is set nowhere in this repo — so
|
|
208
|
+
* `{ setPlan: undefined }` type-checks here with no cast. What the type DOES buy is `null`:
|
|
209
|
+
* `{ setPlan: null }` is rejected under `strictNullChecks`. The `undefined` half of the guarantee is
|
|
210
|
+
* enforced where it actually holds — {@link mergeOverrides} drops those values at merge time, which
|
|
211
|
+
* is flag-independent.
|
|
212
|
+
*/
|
|
213
|
+
type TOverrides<T> = { [K in keyof T]?: NonNullable<T[K]>; };
|
|
214
|
+
//#endregion
|
|
215
|
+
//#region src/testing/command-host-double.d.ts
|
|
216
|
+
/**
|
|
217
|
+
* The session-runtime half of the double, published for the same reason the host half is: three
|
|
218
|
+
* fixtures hand-rolled this 18-member contract, and making its members required turned each of
|
|
219
|
+
* those into a compile error with nothing honest to reach for.
|
|
220
|
+
*/
|
|
221
|
+
declare function createTestSessionRuntime(overrides?: TOverrides<ICommandSessionRuntime>): ICommandSessionRuntime;
|
|
222
|
+
interface ICreateTestCommandHostOptions {
|
|
223
|
+
/** Overrides applied last, so a test can state exactly the capability it exercises. */
|
|
224
|
+
readonly overrides?: TOverrides<ICommandHostContext>;
|
|
225
|
+
/** Convenience for the common case of shaping only the session runtime. */
|
|
226
|
+
readonly session?: TOverrides<ICommandSessionRuntime>;
|
|
227
|
+
/** The working directory every path-scoped command reads. */
|
|
228
|
+
readonly cwd?: string;
|
|
229
|
+
}
|
|
230
|
+
declare function createTestCommandHost(options?: ICreateTestCommandHostOptions): ICommandHostContext;
|
|
231
|
+
//#endregion
|
|
232
|
+
//#region src/testing/agent-job-host-double.d.ts
|
|
233
|
+
declare function createTestAgentJobHost(overrides?: TOverrides<IAgentJobHostContext>): IAgentJobHostContext;
|
|
234
|
+
//#endregion
|
|
235
|
+
//#region src/testing/interactive-runtime.d.ts
|
|
236
|
+
/** Create an interactive runtime around a test double without weakening production options. */
|
|
237
|
+
declare function createInteractiveRuntimeForTesting(options: IInteractiveRuntimeTestOptions, session: IInteractiveSession$1): IInteractiveRuntime;
|
|
238
|
+
//#endregion
|
|
239
|
+
export { type ICreateTestCommandHostOptions, type IScriptedSessionOptions, ScriptedSessionHarness, createInteractiveRuntimeForTesting, createTestAgentJobHost, createTestCommandHost, createTestSessionRuntime, scriptedSession };
|
|
240
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../../src/testing/scripted-session-harness.ts","../../../src/testing/double-overrides.ts","../../../src/testing/command-host-double.ts","../../../src/testing/agent-job-host-double.ts","../../../src/testing/interactive-runtime.ts"],"mappings":";;;;;;;;;UAqEiB;;EAEf,iBAAiB;;;;;;;EAOjB,aAAa;;;;;EAKb;;;;;EAKA;IAAW,UAAU;IAAa;;;EAElC,2BAA2B;;EAE3B,QAAQ;;EAER;;;;;;EAMA;;EAEA,gBAAgB;;EAEhB,+BAA+B;;EAE/B,sBAAsB;EACtB;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA,0BAA0B;;EAE1B;;EAEA,iBAAiB;;EAEjB;;EAEA;;;;;EAKA;IAAgB;IAAkB;IAAiB;;;EAEnD,QAAQ;;EAER,gBAAgB;;EAEhB;;EAEA;;EAEA;;EAEA,kBAAkB;;EAElB,kBAAkB;;EAElB,wBAAwB;;EAExB,kBAAkB;;;;;;cAuBP;;WAEF;;WAEA,SAAS;;WAET,UAAU;mBAEF;mBACA;mBACA;mBACA;UACT;EAEI,YAAA,SAAS;;;;;;;UA8Hb;UAeA;;EASF,OAAO,iBAAiB,QAAQ;;;;;EAUhC,QAAQ,mBAAmB;IAAW;MAAgC,QAAQ;;EA0BpF,QAAQ,cAAc,gBAAY,QAAQ;;;;;;;;;;EAapC,KAAK,qBAAqB,uBAAuB,QAAQ;;EAOzD,WAAW,cAAc,wBAAwB,QAAQ;;EAO/D,WAAW,UAAU,uBACnB,OAAO,GACP,gBAAgB,MAAM,WAAW,0BAA0B,kBAC1D,QAAQ,WAAW,0BAA0B;UAYxC;;EAwBR,WAAW;;EAKX,iBAAiB;;;;;;;EAYjB;IAAgB;IAAY,SAAS,WAAW;;;EAQhD;;EAKA;;EAKA;;;;;EAQA,cAAc,MAAM;;EAKpB,aAAa;;EAKb,cAAc,UAAU,uBACtB,OAAO,IACN,MAAM,WAAW,0BAA0B;;EAK9C,SAAS;;EAKT,OAAO;;EAKP;;EAOM,WAAW;;;iBAcH,gBAAgB,SAAS,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;KCzfvD,WAAW,QAAQ,WAAW,KAAK,YAAY,EAAE;;;;;;;;iBCoG7C,yBACd,YAAY,WAAW,0BACtB;UA8Cc;;WAEN,YAAY,WAAW;;WAEvB,UAAU,WAAW;;WAErB;;iBAGK,sBACd,UAAS,gCACR;;;iBC9Ga,uBACd,YAAY,WAAW,wBACtB;;;;iBCnEa,mCACd,SAAS,gCACT,SAAS,wBACR"}
|
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import { Cn as IContributionSource, Fa as ICommandModule, Lt as IToolCallHandoffPolicy, Pc as IAgentJobHostContext, Sc as TWorkspaceProjectAccess, g as IInteractiveSession$1, gn as ISkillRootDescriptor, hl as ICommandSessionRuntime, i as IInteractiveRuntime, l as InteractiveSession, n as IInteractiveRuntimeTestOptions, qa as ICommandHostContext } from "../createInteractiveRuntime-GD7gJ7ig.js";
|
|
2
|
+
import { IAIProvider, IToolWithEventService, IUserInteraction, THooksConfig, TPermissionMode, TUniversalMessage } from "@robota-sdk/agent-core";
|
|
3
|
+
import { IExecutionResult, IGoalState, IInteractiveSessionEvents, IInteractiveSessionRecord, ITerminalHandoff, IToolSummary, TInteractiveEventName } from "@robota-sdk/agent-interface-session";
|
|
4
|
+
import { IBackgroundTaskRunner } from "@robota-sdk/agent-executor";
|
|
5
|
+
import { ISandboxClient } from "@robota-sdk/agent-tools";
|
|
6
|
+
import { TScriptedTurn } from "@robota-sdk/agent-core/testing";
|
|
7
|
+
import { ICommandResult } from "@robota-sdk/agent-interface-command";
|
|
6
8
|
//#region src/testing/scripted-session-harness.d.ts
|
|
7
9
|
/** Options for {@link scriptedSession}. Provide exactly one of `turns`, `cassette`, or `record`. */
|
|
8
10
|
interface IScriptedSessionOptions {
|
|
9
11
|
/** Scripted assistant turns replayed deterministically through the real loop. */
|
|
10
|
-
turns?: readonly TScriptedTurn
|
|
12
|
+
turns?: readonly TScriptedTurn[];
|
|
11
13
|
/**
|
|
12
|
-
* CMD-005: answer model-issued questions (AskUserQuestion) programmatically. When set,
|
|
13
|
-
*
|
|
14
|
+
* CMD-005: answer model-issued questions (AskUserQuestion) programmatically. When set, the harness
|
|
15
|
+
* subscribes to the session's `ask_request` event and answers via `resolveAsk` (REMOTE-007). Absent ⇒
|
|
16
|
+
* nothing subscribes, so a model-issued question fails closed (each question `cancelled`) — the
|
|
17
|
+
* headless no-human path.
|
|
14
18
|
*/
|
|
15
19
|
askHandler?: IUserInteraction['ask'];
|
|
16
20
|
/**
|
|
@@ -26,6 +30,8 @@ interface IScriptedSessionOptions {
|
|
|
26
30
|
provider: IAIProvider;
|
|
27
31
|
toCassette: string;
|
|
28
32
|
};
|
|
33
|
+
/** Awaited before every provider call, so a test can hold a turn open while it observes. */
|
|
34
|
+
beforeProviderCall?: () => Promise<void>;
|
|
29
35
|
/** Seed files written into the workspace before the session starts (workspace-relative paths). */
|
|
30
36
|
files?: Record<string, string>;
|
|
31
37
|
/** Persist sessions to a real store in the workspace (enables resume/record assertions). */
|
|
@@ -36,18 +42,44 @@ interface IScriptedSessionOptions {
|
|
|
36
42
|
* workspace it did not create.
|
|
37
43
|
*/
|
|
38
44
|
cwd?: string;
|
|
45
|
+
/** Explicit host-issued project authority for contribution-discovery fixtures. */
|
|
46
|
+
projectAccess?: TWorkspaceProjectAccess;
|
|
47
|
+
/** Explicit host contribution sources used by skill discovery fixtures. */
|
|
48
|
+
contributionSources?: readonly IContributionSource[];
|
|
49
|
+
/** Ordered host-owned skill roots used by skill discovery fixtures. */
|
|
50
|
+
skillRoots?: readonly ISkillRootDescriptor[];
|
|
51
|
+
resolveDefaultLoopPrompt?: () => string;
|
|
52
|
+
/** Ordered host-owned agent-definition roots for discovery tests. */
|
|
53
|
+
agentDefinitionRoots?: readonly string[];
|
|
39
54
|
/** Resume a persisted session by id (multi-session). Requires `persistence` + the same `cwd`. */
|
|
40
55
|
resumeSessionId?: string;
|
|
41
56
|
/** Fork the resumed session into a new id while restoring its context (multi-session). */
|
|
42
57
|
forkSession?: boolean;
|
|
58
|
+
/** Issue #3081: the session is the target of a `/cd` from this directory. */
|
|
59
|
+
workspaceMovedFrom?: string;
|
|
43
60
|
/** Command modules composed into the session (e.g. the `/goal` module). */
|
|
44
61
|
commandModules?: readonly ICommandModule[];
|
|
62
|
+
/** Enable the real background-task runners for schedule/monitor functional tests. */
|
|
63
|
+
backgroundTasks?: boolean;
|
|
45
64
|
/** Permission posture. Defaults to `bypassPermissions` so tools run unattended. */
|
|
46
65
|
permissionMode?: TPermissionMode;
|
|
47
66
|
/** Pre-approved tool names. */
|
|
48
67
|
allowedTools?: string[];
|
|
49
68
|
/** Denied tool names (deny wins over allow). */
|
|
50
69
|
deniedTools?: string[];
|
|
70
|
+
/**
|
|
71
|
+
* Permission PATTERNS (`Bash(rm *)`), as a user's settings file would carry them — read through a
|
|
72
|
+
* host settings source, the route the product uses. Tool-name lists are `allowedTools`/`deniedTools`.
|
|
73
|
+
*/
|
|
74
|
+
permissions?: {
|
|
75
|
+
allow?: string[];
|
|
76
|
+
deny?: string[];
|
|
77
|
+
ask?: string[];
|
|
78
|
+
};
|
|
79
|
+
/** Hook configuration, written into the same user settings file as `permissions`. */
|
|
80
|
+
hooks?: THooksConfig;
|
|
81
|
+
/** A sandbox client, as a product that confines commands supplies one. */
|
|
82
|
+
sandboxClient?: ISandboxClient;
|
|
51
83
|
/** Skip AGENTS.md/CLAUDE.md and plugin discovery for determinism. Defaults to `true`. */
|
|
52
84
|
bare?: boolean;
|
|
53
85
|
/** Cap on agentic rounds per submit. */
|
|
@@ -56,6 +88,12 @@ interface IScriptedSessionOptions {
|
|
|
56
88
|
model?: string;
|
|
57
89
|
/** TERM-001: inject a (fake) terminal-handoff capability to exercise the handoff orchestration. */
|
|
58
90
|
terminalHandoff?: ITerminalHandoff;
|
|
91
|
+
/** Additional tools registered alongside the default CLI tools (e.g. a fake slow MCP-like tool). */
|
|
92
|
+
additionalTools?: IToolWithEventService[];
|
|
93
|
+
/** Runtime-composed background task runners (e.g. the `tool-invocation` runner, MCP-004). */
|
|
94
|
+
backgroundTaskRunners?: IBackgroundTaskRunner[];
|
|
95
|
+
/** MCP-004 §S3: hand a main-turn tool call exceeding its threshold to a background task. */
|
|
96
|
+
toolCallHandoff?: IToolCallHandoffPolicy;
|
|
59
97
|
}
|
|
60
98
|
/**
|
|
61
99
|
* A live, scripted, isolated functional-test session. Construct via {@link scriptedSession};
|
|
@@ -103,6 +141,8 @@ declare class ScriptedSessionHarness {
|
|
|
103
141
|
* driver from hanging until the test timeout when the wake is dropped.
|
|
104
142
|
*/
|
|
105
143
|
wake(instruction: string, sourceTaskId: string): Promise<IExecutionResult | null>;
|
|
144
|
+
/** PEER-002 (#1809): deliver a message from ANOTHER SESSION; see `peerTurnOptions`. */
|
|
145
|
+
submitPeer(text: string, peerSessionId: string): Promise<IExecutionResult>;
|
|
106
146
|
/** Resolve with the args of the next `event` (optionally matching `predicate`). */
|
|
107
147
|
awaitEvent<E extends TInteractiveEventName>(event: E, predicate?: (...args: Parameters<IInteractiveSessionEvents[E]>) => boolean): Promise<Parameters<IInteractiveSessionEvents[E]>>;
|
|
108
148
|
private nextSettledTurn;
|
|
@@ -128,8 +168,7 @@ declare class ScriptedSessionHarness {
|
|
|
128
168
|
transcript(): string;
|
|
129
169
|
/**
|
|
130
170
|
* The real session transcript parsed into structured log entries — the durable record the
|
|
131
|
-
* framework itself writes
|
|
132
|
-
* system's own logging as a verification surface, not just in-memory state.
|
|
171
|
+
* framework itself writes. Leverages the system's own logging as a verification surface.
|
|
133
172
|
*/
|
|
134
173
|
logEntries(): Array<Record<string, unknown>>;
|
|
135
174
|
/** Every tool call the agent made across all completed turns, in order. */
|
|
@@ -148,10 +187,54 @@ declare class ScriptedSessionHarness {
|
|
|
148
187
|
/** Build a live, isolated, scripted functional-test session (TEST-003). */
|
|
149
188
|
declare function scriptedSession(options: IScriptedSessionOptions): ScriptedSessionHarness;
|
|
150
189
|
//#endregion
|
|
151
|
-
//#region src/testing/
|
|
152
|
-
/**
|
|
153
|
-
*
|
|
154
|
-
|
|
190
|
+
//#region src/testing/double-overrides.d.ts
|
|
191
|
+
/**
|
|
192
|
+
* ARCH-029: the one guarantee every command-axis double makes about its overrides.
|
|
193
|
+
*
|
|
194
|
+
* It lives here rather than in either double because both make it, and review found the second copy
|
|
195
|
+
* had been re-implemented inline with a comment pointing at "the sibling double" — two copies of a
|
|
196
|
+
* guarantee drift, and this one had already been stated wrongly once.
|
|
197
|
+
*/
|
|
198
|
+
/**
|
|
199
|
+
* An override may replace a member, never remove one.
|
|
200
|
+
*
|
|
201
|
+
* `Partial<T>` admits `{ setPlan: undefined }`, and object spread then writes that `undefined` over
|
|
202
|
+
* the double's answer — reintroducing an ABSENT member at runtime, fully type-checked, which is the
|
|
203
|
+
* exact state ARCH-029 S4 removed.
|
|
204
|
+
*
|
|
205
|
+
* The type alone does NOT close it, and an earlier revision of this comment claimed it did.
|
|
206
|
+
* Measured: `NonNullable` strips `undefined` from the VALUE type, but the `?` modifier re-admits it
|
|
207
|
+
* unless `exactOptionalPropertyTypes` is on, and it is set nowhere in this repo — so
|
|
208
|
+
* `{ setPlan: undefined }` type-checks here with no cast. What the type DOES buy is `null`:
|
|
209
|
+
* `{ setPlan: null }` is rejected under `strictNullChecks`. The `undefined` half of the guarantee is
|
|
210
|
+
* enforced where it actually holds — {@link mergeOverrides} drops those values at merge time, which
|
|
211
|
+
* is flag-independent.
|
|
212
|
+
*/
|
|
213
|
+
type TOverrides<T> = { [K in keyof T]?: NonNullable<T[K]>; };
|
|
214
|
+
//#endregion
|
|
215
|
+
//#region src/testing/command-host-double.d.ts
|
|
216
|
+
/**
|
|
217
|
+
* The session-runtime half of the double, published for the same reason the host half is: three
|
|
218
|
+
* fixtures hand-rolled this 18-member contract, and making its members required turned each of
|
|
219
|
+
* those into a compile error with nothing honest to reach for.
|
|
220
|
+
*/
|
|
221
|
+
declare function createTestSessionRuntime(overrides?: TOverrides<ICommandSessionRuntime>): ICommandSessionRuntime;
|
|
222
|
+
interface ICreateTestCommandHostOptions {
|
|
223
|
+
/** Overrides applied last, so a test can state exactly the capability it exercises. */
|
|
224
|
+
readonly overrides?: TOverrides<ICommandHostContext>;
|
|
225
|
+
/** Convenience for the common case of shaping only the session runtime. */
|
|
226
|
+
readonly session?: TOverrides<ICommandSessionRuntime>;
|
|
227
|
+
/** The working directory every path-scoped command reads. */
|
|
228
|
+
readonly cwd?: string;
|
|
229
|
+
}
|
|
230
|
+
declare function createTestCommandHost(options?: ICreateTestCommandHostOptions): ICommandHostContext;
|
|
231
|
+
//#endregion
|
|
232
|
+
//#region src/testing/agent-job-host-double.d.ts
|
|
233
|
+
declare function createTestAgentJobHost(overrides?: TOverrides<IAgentJobHostContext>): IAgentJobHostContext;
|
|
234
|
+
//#endregion
|
|
235
|
+
//#region src/testing/interactive-runtime.d.ts
|
|
236
|
+
/** Create an interactive runtime around a test double without weakening production options. */
|
|
237
|
+
declare function createInteractiveRuntimeForTesting(options: IInteractiveRuntimeTestOptions, session: IInteractiveSession$1): IInteractiveRuntime;
|
|
155
238
|
//#endregion
|
|
156
|
-
export { type
|
|
239
|
+
export { type ICreateTestCommandHostOptions, type IScriptedSessionOptions, ScriptedSessionHarness, createInteractiveRuntimeForTesting, createTestAgentJobHost, createTestCommandHost, createTestSessionRuntime, scriptedSession };
|
|
157
240
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/testing/scripted-session-harness.ts","../../../src/testing/
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/testing/scripted-session-harness.ts","../../../src/testing/double-overrides.ts","../../../src/testing/command-host-double.ts","../../../src/testing/agent-job-host-double.ts","../../../src/testing/interactive-runtime.ts"],"mappings":";;;;;;;;;UAqEiB;;EAEf,iBAAiB;;;;;;;EAOjB,aAAa;;;;;EAKb;;;;;EAKA;IAAW,UAAU;IAAa;;;EAElC,2BAA2B;;EAE3B,QAAQ;;EAER;;;;;;EAMA;;EAEA,gBAAgB;;EAEhB,+BAA+B;;EAE/B,sBAAsB;EACtB;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA,0BAA0B;;EAE1B;;EAEA,iBAAiB;;EAEjB;;EAEA;;;;;EAKA;IAAgB;IAAkB;IAAiB;;;EAEnD,QAAQ;;EAER,gBAAgB;;EAEhB;;EAEA;;EAEA;;EAEA,kBAAkB;;EAElB,kBAAkB;;EAElB,wBAAwB;;EAExB,kBAAkB;;;;;;cAuBP;;WAEF;;WAEA,SAAS;;WAET,UAAU;mBAEF;mBACA;mBACA;mBACA;UACT;EAEI,YAAA,SAAS;;;;;;;UA8Hb;UAeA;;EASF,OAAO,iBAAiB,QAAQ;;;;;EAUhC,QAAQ,mBAAmB;IAAW;MAAgC,QAAQ;;EA0BpF,QAAQ,cAAc,gBAAY,QAAQ;;;;;;;;;;EAapC,KAAK,qBAAqB,uBAAuB,QAAQ;;EAOzD,WAAW,cAAc,wBAAwB,QAAQ;;EAO/D,WAAW,UAAU,uBACnB,OAAO,GACP,gBAAgB,MAAM,WAAW,0BAA0B,kBAC1D,QAAQ,WAAW,0BAA0B;UAYxC;;EAwBR,WAAW;;EAKX,iBAAiB;;;;;;;EAYjB;IAAgB;IAAY,SAAS,WAAW;;;EAQhD;;EAKA;;EAKA;;;;;EAQA,cAAc,MAAM;;EAKpB,aAAa;;EAKb,cAAc,UAAU,uBACtB,OAAO,IACN,MAAM,WAAW,0BAA0B;;EAK9C,SAAS;;EAKT,OAAO;;EAKP;;EAOM,WAAW;;;iBAcH,gBAAgB,SAAS,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;KCzfvD,WAAW,QAAQ,WAAW,KAAK,YAAY,EAAE;;;;;;;;iBCoG7C,yBACd,YAAY,WAAW,0BACtB;UA8Cc;;WAEN,YAAY,WAAW;;WAEvB,UAAU,WAAW;;WAErB;;iBAGK,sBACd,UAAS,gCACR;;;iBC9Ga,uBACd,YAAY,WAAW,wBACtB;;;;iBCnEa,mCACd,SAAS,gCACT,SAAS,wBACR"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`).filter(e=>e.trim().length>0).map(e=>JSON.parse(e))}toolCalls(){return this.completions.flatMap(e=>e.toolSummaries)}emittedEvents(e){return this.events.get(e)??[]}readFile(e){return u(r(this.cwd,e),`utf8`)}exists(e){return s(r(this.cwd,e))}files(){let e=[],t=n=>{for(let o of d(n,{withFileTypes:!0})){if(o.name===`.robota`)continue;let s=r(n,o.name);o.isDirectory()?t(s):e.push(i(this.cwd,s).split(a).join(`/`))}};return t(this.cwd),e.sort()}async dispose(){this.disposed||(this.disposed=!0,await this.session.shutdown({reason:`other`,message:`functional test complete`}),this.ownsWorkspace&&f(this.cwd,{recursive:!0,force:!0,maxRetries:5,retryDelay:20}))}};function b(e){return new y(e)}const x={usedTokens:0,maxTokens:2e5,usedPercentage:0,remainingPercentage:100},S={sessionId:`test-session-id`,updatedAt:new Date().toISOString(),entries:[]},C={id:`test-goal`,objective:`test goal`,status:`active`,iterations:0,maxIterations:25,startedAt:new Date().toISOString(),progress:[]},w={id:``,parentSessionId:`test-session-id`,waitPolicy:`wait_all`,taskIds:[],status:`completed`,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString(),results:[]};function T(e){return{submit:()=>Promise.resolve(),abort:()=>{},cancelQueue:()=>{},shutdown:()=>Promise.resolve(),isExecuting:()=>!1,getPendingPrompt:()=>null,getMessages:()=>[],getContextState:()=>({...x}),getSession:()=>({getSessionId:()=>`test-session-id`}),getCwd:()=>`/workspace`,executeCommand:()=>Promise.resolve(null),listCommands:()=>[],on:()=>{},off:()=>{},listBackgroundTasks:()=>[],getBackgroundTask:()=>void 0,cancelBackgroundTask:()=>Promise.resolve(),closeBackgroundTask:()=>Promise.resolve(),sendBackgroundTask:()=>Promise.resolve(),readBackgroundTaskLog:()=>Promise.resolve({taskId:``,lines:[]}),listBackgroundJobGroups:()=>[],getBackgroundJobGroup:()=>void 0,createBackgroundJobGroup:()=>({...w}),waitBackgroundJobGroup:()=>Promise.resolve({...w}),getExecutionWorkspaceSnapshot:()=>({...S}),listAgentDefinitions:()=>[],listAgentJobs:()=>[],spawnAgentJob:()=>Promise.resolve({id:`agent_1`,type:`general-purpose`,label:`general-purpose`,parentSessionId:`test-session-id`,status:`running`,mode:`background`,depth:1,cwd:`/workspace`,promptPreview:``,updatedAt:new Date().toISOString()}),sendAgentJob:()=>Promise.resolve(),cancelAgentJob:()=>Promise.resolve(),closeAgentJob:()=>Promise.resolve(),setGoal:()=>Promise.resolve({...C}),getGoalState:()=>null,cancelGoal:()=>null,...e}}export{y as ScriptedSessionHarness,g as createScriptedProvider,T as createTestInteractiveSession,b as scriptedSession};
|
|
1
|
+
import{b as e,m as t,yr as n}from"../interactive-Bqe03GGe.js";import{dirname as r,join as i,relative as a,sep as o}from"node:path";import{createDefaultBackgroundTaskRunners as s}from"@robota-sdk/agent-executor";import{NodeSessionLogSink as c,NodeSessionStore as l}from"@robota-sdk/agent-session";import{existsSync as u,mkdirSync as d,mkdtempSync as f,readFileSync as p,readdirSync as m,realpathSync as h,rmSync as g,writeFileSync as _}from"node:fs";import{tmpdir as v}from"node:os";import{createRecordingProvider as y,createReplayProvider as b,createScriptedProvider as x}from"@robota-sdk/agent-core/testing";function S(e){return{turnSource:`peer`,driverId:`peer:${e}`}}function C(e){return i(e,`.robota`,`logs`)}function w(e,t){return i(C(e),`${t}.jsonl`)}function T(e,t){let n=w(e,t);return u(n)?p(n,`utf8`):``}function E(e,t){return T(e,t).split(`
|
|
2
|
+
`).filter(e=>e.trim().length>0).map(e=>JSON.parse(e))}function D(e,t){return p(i(e,t),`utf8`)}function O(e,t){return u(i(e,t))}function k(e){let t=[],n=r=>{for(let s of m(r,{withFileTypes:!0})){if(s.name===`.robota`)continue;let c=i(r,s.name);s.isDirectory()?n(c):t.push(a(e,c).split(o).join(`/`))}};return n(e),t.sort()}const A=[`text_delta`,`tool_start`,`tool_end`,`thinking`,`complete`,`interrupted`,`error`,`context_update`,`goal_event`,`turn_source`,`user_message`,`background_task_event`];var j=class{cwd;session;requests;events=new Map;completions=[];sessionStore;ownsWorkspace;disposed=!1;constructor(t){if(this.ownsWorkspace=t.cwd===void 0,this.cwd=t.cwd??h(f(i(v(),`robota-fxn-`))),this.ownsWorkspace)for(let[e,n]of Object.entries(t.files??{})){let t=i(this.cwd,e);d(r(t),{recursive:!0}),_(t,n,`utf8`)}if([t.turns,t.cassette,t.record].filter(e=>e!==void 0).length!==1)throw Error("scriptedSession requires exactly one of `turns`, `cassette`, or `record`.");let a;a=t.cassette?b({cassettePath:t.cassette,scrub:[this.cwd],rewriteCwd:this.cwd}):t.record?y({provider:t.record.provider,cassettePath:t.record.toCassette,recordCwd:this.cwd}):x(this.substituteWorkspacePath(t.turns??[])).provider,this.requests=[];let o={...a,chat:async(e,n)=>(this.requests.push([...e]),await t.beforeProviderCall?.(),a.chat(e,n))},u=i(this.cwd,`.robota`,`sessions`);this.sessionStore=t.persistence?new l(u):void 0;let p;if(t.permissions!==void 0||t.hooks!==void 0){p=i(this.cwd,`.robota-test-user-settings.json`);let e={...t.permissions===void 0?{}:{permissions:t.permissions},...t.hooks===void 0?{}:{hooks:t.hooks}};_(p,JSON.stringify(e),`utf8`)}this.session=new e({cwd:this.cwd,provider:o,...p===void 0?{}:{userSettingsSources:[n(`user`,p)]},...t.projectAccess?{projectAccess:t.projectAccess}:{},...t.sandboxClient?{sandboxClient:t.sandboxClient}:{},...t.contributionSources===void 0?{}:{contributionSources:t.contributionSources},...t.skillRoots===void 0?{}:{skillRoots:t.skillRoots},...t.resolveDefaultLoopPrompt?{resolveDefaultLoopPrompt:t.resolveDefaultLoopPrompt}:{},...t.agentDefinitionRoots===void 0?{}:{agentDefinitionRoots:t.agentDefinitionRoots},bare:t.bare??!0,permissionMode:t.permissionMode??`bypassPermissions`,...t.allowedTools?{allowedTools:t.allowedTools}:{},...t.deniedTools?{deniedTools:t.deniedTools}:{},...this.sessionStore?{sessionStore:this.sessionStore}:{},sessionLogSink:new c(i(this.cwd,`.robota`,`logs`)),...t.resumeSessionId?{resumeSessionId:t.resumeSessionId}:{},...t.forkSession?{forkSession:t.forkSession}:{},...t.workspaceMovedFrom===void 0?{}:{workspaceMovedFrom:t.workspaceMovedFrom},...t.commandModules?{commandModules:t.commandModules}:{},...t.backgroundTasks?{backgroundTaskRunners:s()}:{},...t.maxTurns===void 0?{}:{maxTurns:t.maxTurns},...t.model===void 0?{}:{model:t.model},...t.terminalHandoff?{terminalHandoff:t.terminalHandoff}:{},...t.additionalTools?{additionalTools:t.additionalTools}:{},...t.backgroundTaskRunners?{backgroundTaskRunners:t.backgroundTaskRunners}:{},...t.toolCallHandoff?{toolCallHandoff:t.toolCallHandoff}:{}});for(let e of A)this.session.on(e,((...t)=>{this.record(e,t),(e===`complete`||e===`interrupted`)&&this.completions.push(t[0])}));if(t.askHandler){let e=t.askHandler;this.session.on(`ask_request`,({id:t,request:n})=>{Promise.resolve(e(n)).then(e=>this.session.resolveAsk(t,e)).catch(()=>this.session.resolveAsk(t,{type:`cancelled`}))})}}substituteWorkspacePath(e){return e.map(e=>`toolCalls`in e?{toolCalls:e.toolCalls.map(e=>({name:e.name,args:JSON.parse(JSON.stringify(e.args).split(`{{cwd}}`).join(this.cwd))}))}:e)}record(e,t){let n=this.events.get(e)??[];n.push(t),this.events.set(e,n)}async submit(e){let t=this.nextSettledTurn();return await this.session.submit(e),t}async runGoal(e,t={}){let n=new Promise((e,t)=>{let n=t=>{t.type===`goal_stopped`&&(i(),e(t.goal))},r=e=>{i(),t(e)},i=()=>{this.session.off(`goal_event`,n),this.session.off(`error`,r)};this.session.on(`goal_event`,n),this.session.on(`error`,r)});return await this.session.setGoal(e,t.maxIterations?{maxIterations:t.maxIterations}:{}),n}command(e,t=``){return this.session.executeCommand(e,t)}async wake(e,t){return this.session.requestWakeup(e,t)?this.nextSettledTurn():null}async submitPeer(e,t){let n=this.nextSettledTurn();return await this.session.submit(e,void 0,void 0,S(t)),n}awaitEvent(e,t){return new Promise(n=>{let r=((...i)=>{let a=i;t&&!t(...a)||(this.session.off(e,r),n(a))});this.session.on(e,r)})}nextSettledTurn(){return new Promise((e,t)=>{let n=t=>{i(),e(t)},r=e=>{i(),t(e)},i=()=>{this.session.off(`complete`,n),this.session.off(`interrupted`,n),this.session.off(`error`,r)};this.session.on(`complete`,n),this.session.on(`interrupted`,n),this.session.on(`error`,r)})}history(){return this.session.getMessages()}sessionRecord(){if(!this.sessionStore)return;let e=this.sessionStore.load(this.session.getSession().getSessionId());return e.status===`valid`?e.record:void 0}sessionLog(){return{id:this.session.getSession().getSessionId(),history:this.session.getFullHistory()}}logsDir(){return C(this.cwd)}transcriptPath(){return w(this.cwd,this.session.getSession().getSessionId())}transcript(){return T(this.cwd,this.session.getSession().getSessionId())}logEntries(){return E(this.cwd,this.session.getSession().getSessionId())}toolCalls(){return this.completions.flatMap(e=>e.toolSummaries)}emittedEvents(e){return this.events.get(e)??[]}readFile(e){return D(this.cwd,e)}exists(e){return O(this.cwd,e)}files(){return k(this.cwd)}async dispose(){this.disposed||(this.disposed=!0,await this.session.shutdown({reason:`other`,message:`functional test complete`}),this.ownsWorkspace&&g(this.cwd,{recursive:!0,force:!0,maxRetries:5,retryDelay:20}))}};function M(e){return new j(e)}const N=`1970-01-01T00:00:00.000Z`,P=`/robota-test-command-host`;function F(e,t){let n={...e};for(let[e,r]of Object.entries(t??{}))r!==void 0&&(n[e]=r);return n}const I={id:`test-agent-job`,type:`general-purpose`,label:`test`,parentSessionId:`test-command-host`,status:`running`,mode:`background`,depth:1,cwd:P,promptPreview:``,updatedAt:N},L={id:`test-group`,parentSessionId:`test-command-host`,waitPolicy:`wait_all`,taskIds:[],status:`running`,createdAt:N,updatedAt:N,results:[]},R={id:`test-background-task`,kind:`agent`,label:`test`,status:`running`,mode:`background`,parentSessionId:`test-command-host`,depth:1,cwd:P,updatedAt:N,unread:!1};function z(e){return F({listAgentDefinitions:()=>[],listAgentJobs:()=>[],spawnAgentJob:()=>Promise.resolve(I),sendAgentJob:()=>Promise.resolve(),cancelAgentJob:()=>Promise.resolve(),closeAgentJob:()=>Promise.resolve(),createBackgroundJobGroup:()=>L,waitBackgroundJobGroup:()=>Promise.resolve(L),spawnScheduledWake:()=>Promise.resolve(R),listSchedules:()=>[],pauseSchedule:()=>Promise.resolve(),resumeSchedule:()=>Promise.resolve(),editSchedule:()=>Promise.resolve(),spawnMonitorWake:()=>Promise.resolve(R),readBackgroundTaskLog:e=>Promise.resolve({taskId:e,lines:[]})},e)}const B={target:{id:`test-checkpoint`,sessionId:`test-command-host`,sequence:0,prompt:``,createdAt:N,fileCount:0},restoredCheckpointCount:0,restoredFileCount:0,removedCheckpointCount:0},V={maxTokens:0,usedTokens:0,usedPercentage:0,remainingPercentage:100},H={id:`test-goal`,objective:``,status:`stopped`,iterations:0,maxIterations:0,startedAt:N,progress:[]},U={id:`test-plan`,objective:``,steps:[],phase:`planning`,createdAt:N},W={},G={loadStartupMemory:()=>Promise.resolve({content:``,path:``,lineCount:0,truncated:!1}),list:()=>Promise.resolve({indexPath:``,topicsPath:``,topics:[]}),readTopic:()=>Promise.resolve(``),append:e=>Promise.resolve({indexPath:``,topicPath:``,topic:e.topic,deduplicated:!1}),recall:()=>Promise.resolve({content:``,references:[],truncated:!1}),getPending:()=>Promise.resolve(void 0),listPending:()=>Promise.resolve([]),markPending:(e,t,n)=>Promise.resolve({id:e,type:`project`,topic:``,text:``,sourceMessageIds:[],confidence:0,createdAt:N,reason:n,status:t,updatedAt:N}),upsertPending:()=>Promise.resolve()};let K=0;function q(e){let t=[];return F({getSessionId:()=>`test-command-host-${K}`,getHistory:()=>[],getFullHistory:()=>[],getMessageCount:()=>0,clearHistory:()=>{},compact:()=>Promise.resolve(),getContextState:()=>V,getPermissionMode:()=>`default`,setPermissionMode:()=>{},getSessionAllowedTools:()=>[],getPermissionRules:()=>({allow:[],deny:[],ask:[]}),getRecentPermissionDenials:()=>[],retryPermissionDenial:()=>void 0,applyPresetToolLists:e=>{t.push(e)},getAutoCompactThreshold:()=>!1,setAutoCompactThreshold:()=>{},getSessionTokenUsage:()=>void 0,getModelId:()=>void 0,getModelEffort:()=>`high`,getOfferedToolSchemas:()=>[],addTools:async()=>[],applyModelOptions:()=>{},applyAgentName:()=>{},getActivePresetId:()=>`default`,setActivePresetId:()=>{},setParallelSubagentsEnabled:()=>{}},e)}function J(e={}){K+=1;let t=e.cwd??`/robota-test-command-host-${K}`,n=q(e.session);return F({getSession:()=>n,validateCurrentSessionReplayLog:()=>({logFile:`${t}/session.jsonl`,entryCount:0,validation:{ok:!0,issues:[]}}),getCwd:()=>t,getCommandInvocationSource:()=>`user`,clearConversationHistory:()=>{},getSessionUsage:()=>[],forkSession:e=>Promise.resolve({sessionId:`test-command-host-${K}-fork`,name:e?.name??`test-command-host-${K} (fork)`}),getUserInteraction:()=>void 0,getActiveOutputStyleId:()=>`default`,applyPersona:()=>{},applySelfVerification:()=>{},applyResponseLanguage:()=>{},applyOutputStyle:()=>{},applyPresetSystemPrompt:()=>{},applyCommandModuleSelection:()=>[],getAutoCompactThresholdSource:()=>`session`,setAutoCompactThreshold:()=>{},listCheckpointBranches:()=>[],forkCheckpointBranch:()=>Promise.resolve(B),switchCheckpointBranch:()=>{},setGoal:()=>Promise.resolve(H),getGoalState:()=>null,cancelGoal:()=>null,setPlan:()=>Promise.resolve(U),getPlanState:()=>null,approvePlan:()=>U,revertPlan:()=>U,getMemoryStore:()=>G,runWithTerminal:e=>e(),getContextState:()=>V,getAutoCompactThreshold:()=>!1,compactContext:()=>Promise.resolve(),listCommands:()=>[],listSkills:()=>[],executeSkillCommandByName:()=>Promise.resolve(null),listContextReferences:()=>[],addContextReference:()=>Promise.resolve({evicted:[],diagnostics:[]}),removeContextReference:()=>({}),clearContextReferences:()=>({removed:[]}),listEditCheckpoints:()=>[],inspectEditCheckpoint:()=>({target:B.target,capturedFiles:[],restoreToCheckpoint:{checkpointIds:[],fileCount:0},rollbackThroughCheckpoint:{checkpointIds:[],fileCount:0}}),restoreEditCheckpoint:()=>Promise.resolve(B),rollbackEditCheckpoint:()=>Promise.resolve(B),getUsedMemoryReferences:()=>[],recordMemoryEvent:()=>{},listBackgroundTasks:()=>[],readBackgroundTaskLog:e=>Promise.resolve({taskId:e,lines:[]}),cancelBackgroundTask:()=>Promise.resolve(),closeBackgroundTask:()=>Promise.resolve(),getCommandHostAdapters:()=>W,canHandoffTerminal:()=>!1,getAgentJobCapability:()=>z()},e.overrides)}function Y(e,n){return t(e,()=>n)}export{j as ScriptedSessionHarness,Y as createInteractiveRuntimeForTesting,z as createTestAgentJobHost,J as createTestCommandHost,q as createTestSessionRuntime,M as scriptedSession};
|
|
3
3
|
//# sourceMappingURL=index.js.map
|