@myagentroam/agent 0.9.141 → 0.9.143
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-core/host/contracts.d.ts +64 -0
- package/dist/{host → agent-core/host}/local-agent-host.d.ts +6 -5
- package/dist/{host → agent-core/host}/local-agent-host.js +4 -4
- package/dist/{model → agent-core/model}/anthropic-messages.js +24 -13
- package/dist/{model → agent-core/model}/contracts.d.ts +6 -16
- package/dist/{model → agent-core/model}/openai-responses.js +16 -9
- package/dist/agent-core/model/recovery.d.ts +4 -0
- package/dist/agent-core/model/recovery.js +71 -0
- package/dist/{prompts → agent-core/prompts}/core.d.ts +3 -13
- package/dist/{prompts → agent-core/prompts}/index.d.ts +1 -1
- package/dist/{prompts → agent-core/prompts}/modes.d.ts +1 -1
- package/dist/{prompts → agent-core/prompts}/resources.d.ts +1 -1
- package/dist/{runtime/compact.d.ts → agent-core/runtime/compaction/history.d.ts} +2 -23
- package/dist/{runtime/compact.js → agent-core/runtime/compaction/history.js} +2 -92
- package/dist/agent-core/runtime/compaction/operation.d.ts +22 -0
- package/dist/agent-core/runtime/compaction/operation.js +91 -0
- package/dist/agent-core/runtime/context/contracts.d.ts +12 -0
- package/dist/{runtime/environment-context.d.ts → agent-core/runtime/context/environment.d.ts} +2 -2
- package/dist/{runtime/environment-context.js → agent-core/runtime/context/environment.js} +1 -1
- package/dist/{runtime/context-gc-runtime.d.ts → agent-core/runtime/context/gc-runtime.d.ts} +4 -4
- package/dist/{runtime/context-gc-runtime.js → agent-core/runtime/context/gc-runtime.js} +3 -3
- package/dist/{runtime/context-gc-tokens.d.ts → agent-core/runtime/context/gc-tokens.d.ts} +2 -2
- package/dist/{runtime/context-gc-tokens.js → agent-core/runtime/context/gc-tokens.js} +7 -5
- package/dist/{runtime/context-gc.d.ts → agent-core/runtime/context/gc.d.ts} +3 -3
- package/dist/{runtime/context-gc.js → agent-core/runtime/context/gc.js} +152 -19
- package/dist/{runtime → agent-core/runtime/context}/instructions.d.ts +1 -1
- package/dist/{runtime → agent-core/runtime/context}/instructions.js +1 -1
- package/dist/{runtime → agent-core/runtime/context}/normalize.d.ts +1 -1
- package/dist/{runtime/context-projection.d.ts → agent-core/runtime/context/projection.d.ts} +3 -3
- package/dist/{runtime/context-projection.js → agent-core/runtime/context/projection.js} +35 -4
- package/dist/agent-core/runtime/context/request-budget.d.ts +6 -0
- package/dist/agent-core/runtime/context/request-budget.js +22 -0
- package/dist/agent-core/runtime/context/restore.d.ts +15 -0
- package/dist/agent-core/runtime/context/restore.js +85 -0
- package/dist/agent-core/runtime/context/usage.d.ts +18 -0
- package/dist/agent-core/runtime/context/usage.js +138 -0
- package/dist/agent-core/runtime/context/world-state.d.ts +35 -0
- package/dist/agent-core/runtime/context/world-state.js +133 -0
- package/dist/agent-core/runtime/contracts.d.ts +37 -0
- package/dist/agent-core/runtime/event-projection.d.ts +5 -0
- package/dist/agent-core/runtime/event-projection.js +17 -0
- package/dist/agent-core/runtime/events.d.ts +143 -0
- package/dist/agent-core/runtime/execution.d.ts +50 -0
- package/dist/agent-core/runtime/execution.js +397 -0
- package/dist/{runtime → agent-core/runtime}/rollout-budget.d.ts +1 -1
- package/dist/agent-core/sdk/agent.js +209 -0
- package/dist/agent-core/sdk/model-runtime.d.ts +13 -0
- package/dist/agent-core/sdk/model-runtime.js +63 -0
- package/dist/agent-core/sdk/session-title.d.ts +3 -0
- package/dist/agent-core/sdk/session-title.js +42 -0
- package/dist/agent-core/sdk/session.d.ts +62 -0
- package/dist/agent-core/sdk/session.js +1147 -0
- package/dist/agent-core/sdk/subagent-backend.d.ts +3 -0
- package/dist/agent-core/sdk/subagent-backend.js +46 -0
- package/dist/agent-core/sdk/types.d.ts +56 -0
- package/dist/{session → agent-core/session}/catalog.d.ts +2 -1
- package/dist/{session → agent-core/session}/context-gc-checkpoint.d.ts +3 -0
- package/dist/{session → agent-core/session}/context-gc-checkpoint.js +122 -23
- package/dist/agent-core/session/context-gc-observations.d.ts +38 -0
- package/dist/agent-core/session/context-gc-observations.js +150 -0
- package/dist/{session → agent-core/session}/context-gc-replacements.d.ts +1 -1
- package/dist/{session → agent-core/session}/context-gc-replacements.js +6 -2
- package/dist/{session → agent-core/session}/jsonl-store.d.ts +2 -2
- package/dist/{session → agent-core/session}/jsonl-store.js +1 -1
- package/dist/agent-core/subagent/contracts.d.ts +91 -0
- package/dist/agent-core/subagent/contracts.js +1 -0
- package/dist/agent-core/subagent/scheduler.d.ts +117 -0
- package/dist/{subagent → agent-core/subagent}/session-controller.d.ts +3 -2
- package/dist/agent-core/tools/agent/agent-cancel.d.ts +7 -0
- package/dist/{tools → agent-core/tools/agent}/agent-cancel.js +1 -1
- package/dist/agent-core/tools/agent/agent-message.d.ts +7 -0
- package/dist/{tools → agent-core/tools/agent}/agent-message.js +2 -2
- package/dist/{tools → agent-core/tools/agent}/agent-start.d.ts +3 -3
- package/dist/{tools → agent-core/tools/agent}/agent-start.js +3 -3
- package/dist/agent-core/tools/agent/agent-wait.d.ts +7 -0
- package/dist/{tools → agent-core/tools/agent}/agent-wait.js +2 -2
- package/dist/{tools → agent-core/tools/agent}/question.d.ts +2 -2
- package/dist/{tools → agent-core/tools/agent}/question.js +2 -2
- package/dist/{tools → agent-core/tools/agent}/skill.d.ts +2 -2
- package/dist/{tools → agent-core/tools/agent}/skill.js +2 -2
- package/dist/{tools → agent-core/tools/agent}/todo-read.d.ts +2 -2
- package/dist/{tools → agent-core/tools/agent}/todo-write.d.ts +2 -2
- package/dist/{tools → agent-core/tools/agent}/todo-write.js +2 -2
- package/dist/{tools → agent-core/tools/agent}/todo.d.ts +2 -9
- package/dist/{tools → agent-core/tools/agent}/todo.js +1 -1
- package/dist/{tools → agent-core/tools}/code-mode/cells.d.ts +4 -1
- package/dist/{tools → agent-core/tools}/code-mode/cells.js +60 -6
- package/dist/{tools → agent-core/tools}/code-mode/dispatch.d.ts +2 -4
- package/dist/{tools → agent-core/tools}/code-mode/dispatch.js +10 -6
- package/dist/{tools → agent-core/tools}/code-mode/engine.d.ts +13 -1
- package/dist/agent-core/tools/code-mode/engine.js +1 -0
- package/dist/{tools/code-mode.d.ts → agent-core/tools/code-mode/index.d.ts} +7 -7
- package/dist/{tools/code-mode.js → agent-core/tools/code-mode/index.js} +190 -28
- package/dist/agent-core/tools/code-mode/observations.d.ts +103 -0
- package/dist/agent-core/tools/code-mode/observations.js +195 -0
- package/dist/{tools → agent-core/tools}/code-mode/quickjs-engine.js +91 -17
- package/dist/{tools → agent-core/tools}/code-mode/state.d.ts +2 -13
- package/dist/agent-core/tools/code-mode/worker.d.ts +1 -0
- package/dist/{tools → agent-core/tools}/code-mode/worker.js +8 -1
- package/dist/agent-core/tools/contracts.d.ts +172 -0
- package/dist/agent-core/tools/contracts.js +1 -0
- package/dist/agent-core/tools/execution.d.ts +36 -0
- package/dist/agent-core/tools/execution.js +111 -0
- package/dist/agent-core/tools/local/apply-patch.d.ts +19 -0
- package/dist/{tools → agent-core/tools/local}/apply-patch.js +8 -2
- package/dist/{tools → agent-core/tools/local}/exec.d.ts +5 -17
- package/dist/{tools → agent-core/tools/local}/exec.js +4 -4
- package/dist/{tools → agent-core/tools/local}/read.d.ts +7 -15
- package/dist/{tools → agent-core/tools/local}/read.js +185 -2
- package/dist/{tools/local-registry.d.ts → agent-core/tools/local/registry.d.ts} +5 -5
- package/dist/agent-core/tools/local/registry.js +101 -0
- package/dist/{tools → agent-core/tools/local}/view-image.d.ts +4 -9
- package/dist/{tools → agent-core/tools/local}/view-image.js +2 -2
- package/dist/agent-core/tools/local/web-fetch.d.ts +4 -0
- package/dist/agent-core/tools/local/web-fetch.js +85 -0
- package/dist/agent-core/tools/local/web-search.d.ts +7 -0
- package/dist/agent-core/tools/local/web-search.js +34 -0
- package/dist/{tools/local-workspace-tools.js → agent-core/tools/local/workspace-tools.js} +1 -1
- package/dist/{sdk/mcp-catalog.d.ts → agent-core/tools/mcp/catalog.d.ts} +1 -2
- package/dist/{sdk/mcp-catalog.js → agent-core/tools/mcp/catalog.js} +1 -1
- package/dist/agent-core/tools/mcp/history.d.ts +4 -0
- package/dist/agent-core/tools/mcp/history.js +33 -0
- package/dist/{tools → agent-core/tools/mcp}/tool-search.d.ts +3 -3
- package/dist/{tools → agent-core/tools/mcp}/tool-search.js +4 -4
- package/dist/agent-core/tools/output-projection.d.ts +14 -0
- package/dist/agent-core/tools/output-projection.js +223 -0
- package/dist/{tools → agent-core/tools}/registry.d.ts +1 -1
- package/dist/agent-core/tools/registry.js +47 -0
- package/dist/{tools → agent-core/tools}/runtime-context.d.ts +8 -7
- package/dist/agent-core/tools/runtime-context.js +1 -0
- package/dist/{tools → agent-core/tools}/runtime.d.ts +1 -1
- package/dist/cli/codex-auth-file.d.ts +1 -1
- package/dist/cli/codex-auth-file.js +2 -2
- package/dist/cli/main.js +9 -9
- package/dist/index.d.ts +17 -15
- package/dist/index.js +8 -8
- package/dist/sandbox/linux/bubblewrap-sandbox-executor.d.ts +1 -1
- package/dist/sandbox/linux/bubblewrap-sandbox-executor.js +1 -1
- package/package.json +3 -3
- package/dist/host/contracts.d.ts +0 -21
- package/dist/sdk/agent.js +0 -2548
- package/dist/sdk/types.d.ts +0 -349
- package/dist/subagent/scheduler.d.ts +0 -206
- package/dist/tools/agent-cancel.d.ts +0 -7
- package/dist/tools/agent-message.d.ts +0 -7
- package/dist/tools/agent-wait.d.ts +0 -7
- package/dist/tools/apply-patch.d.ts +0 -32
- package/dist/tools/local-registry.js +0 -373
- package/dist/tools/registry.js +0 -47
- package/dist/tools/web-fetch.d.ts +0 -2
- package/dist/tools/web-fetch.js +0 -12
- package/dist/tools/web-search.d.ts +0 -2
- package/dist/tools/web-search.js +0 -15
- /package/dist/{error.d.ts → agent-core/error.d.ts} +0 -0
- /package/dist/{error.js → agent-core/error.js} +0 -0
- /package/dist/{host → agent-core/host}/contracts.js +0 -0
- /package/dist/{host → agent-core/host}/local-process-executor.d.ts +0 -0
- /package/dist/{host → agent-core/host}/local-process-executor.js +0 -0
- /package/dist/{host → agent-core/host}/network.d.ts +0 -0
- /package/dist/{host → agent-core/host}/network.js +0 -0
- /package/dist/{model → agent-core/model}/anthropic-messages.d.ts +0 -0
- /package/dist/{model → agent-core/model}/anthropic-thinking.d.ts +0 -0
- /package/dist/{model → agent-core/model}/anthropic-thinking.js +0 -0
- /package/dist/{model → agent-core/model}/catalog-file.d.ts +0 -0
- /package/dist/{model → agent-core/model}/catalog-file.js +0 -0
- /package/dist/{model → agent-core/model}/configuration.d.ts +0 -0
- /package/dist/{model → agent-core/model}/configuration.js +0 -0
- /package/dist/{model → agent-core/model}/contracts.js +0 -0
- /package/dist/{model → agent-core/model}/http.d.ts +0 -0
- /package/dist/{model → agent-core/model}/http.js +0 -0
- /package/dist/{model → agent-core/model}/openai-responses.d.ts +0 -0
- /package/dist/{model → agent-core/model}/runtime-credential.d.ts +0 -0
- /package/dist/{model → agent-core/model}/runtime-credential.js +0 -0
- /package/dist/{model → agent-core/model}/sse.d.ts +0 -0
- /package/dist/{model → agent-core/model}/sse.js +0 -0
- /package/dist/{model → agent-core/model}/transport-test.d.ts +0 -0
- /package/dist/{model → agent-core/model}/transport-test.js +0 -0
- /package/dist/{prompts → agent-core/prompts}/compact.d.ts +0 -0
- /package/dist/{prompts → agent-core/prompts}/compact.js +0 -0
- /package/dist/{prompts → agent-core/prompts}/core.js +0 -0
- /package/dist/{prompts → agent-core/prompts}/execution-budget.d.ts +0 -0
- /package/dist/{prompts → agent-core/prompts}/execution-budget.js +0 -0
- /package/dist/{prompts → agent-core/prompts}/index.js +0 -0
- /package/dist/{prompts → agent-core/prompts}/modes.js +0 -0
- /package/dist/{prompts → agent-core/prompts}/output.d.ts +0 -0
- /package/dist/{prompts → agent-core/prompts}/output.js +0 -0
- /package/dist/{prompts → agent-core/prompts}/resources.js +0 -0
- /package/dist/{prompts → agent-core/prompts}/subagent.d.ts +0 -0
- /package/dist/{prompts → agent-core/prompts}/subagent.js +0 -0
- /package/dist/{prompts → agent-core/prompts}/title.d.ts +0 -0
- /package/dist/{prompts → agent-core/prompts}/title.js +0 -0
- /package/dist/{prompts → agent-core/prompts}/workflow.d.ts +0 -0
- /package/dist/{prompts → agent-core/prompts}/workflow.js +0 -0
- /package/dist/{runtime → agent-core/runtime}/async-queue.d.ts +0 -0
- /package/dist/{runtime → agent-core/runtime}/async-queue.js +0 -0
- /package/dist/{sdk/types.js → agent-core/runtime/context/contracts.js} +0 -0
- /package/dist/{runtime → agent-core/runtime/context}/normalize.js +0 -0
- /package/dist/{session/types.js → agent-core/runtime/contracts.js} +0 -0
- /package/dist/{tools/code-mode/engine.js → agent-core/runtime/events.js} +0 -0
- /package/dist/{runtime → agent-core/runtime}/execution-policy.d.ts +0 -0
- /package/dist/{runtime → agent-core/runtime}/execution-policy.js +0 -0
- /package/dist/{runtime → agent-core/runtime}/plan-output.d.ts +0 -0
- /package/dist/{runtime → agent-core/runtime}/plan-output.js +0 -0
- /package/dist/{runtime → agent-core/runtime}/rollout-budget.js +0 -0
- /package/dist/{runtime → agent-core/runtime}/token-budget.d.ts +0 -0
- /package/dist/{runtime → agent-core/runtime}/token-budget.js +0 -0
- /package/dist/{sdk → agent-core/sdk}/agent.d.ts +0 -0
- /package/dist/{tools/code-mode/worker.d.ts → agent-core/sdk/types.js} +0 -0
- /package/dist/{session → agent-core/session}/catalog.js +0 -0
- /package/dist/{session → agent-core/session}/context-gc-subagent.d.ts +0 -0
- /package/dist/{session → agent-core/session}/context-gc-subagent.js +0 -0
- /package/dist/{session → agent-core/session}/transaction-recovery.d.ts +0 -0
- /package/dist/{session → agent-core/session}/transaction-recovery.js +0 -0
- /package/dist/{session → agent-core/session}/types.d.ts +0 -0
- /package/dist/{tools/runtime-context.js → agent-core/session/types.js} +0 -0
- /package/dist/{subagent → agent-core/subagent}/scheduler.js +0 -0
- /package/dist/{subagent → agent-core/subagent}/session-controller.js +0 -0
- /package/dist/{tools → agent-core/tools/agent}/todo-read.js +0 -0
- /package/dist/{tools → agent-core/tools}/callers.d.ts +0 -0
- /package/dist/{tools → agent-core/tools}/callers.js +0 -0
- /package/dist/{tools → agent-core/tools}/code-mode/quickjs-engine.d.ts +0 -0
- /package/dist/{tools → agent-core/tools}/code-mode/state.js +0 -0
- /package/dist/{tools → agent-core/tools}/code-mode/text-output.d.ts +0 -0
- /package/dist/{tools → agent-core/tools}/code-mode/text-output.js +0 -0
- /package/dist/{tools → agent-core/tools}/execution-limits.d.ts +0 -0
- /package/dist/{tools → agent-core/tools}/execution-limits.js +0 -0
- /package/dist/{tools → agent-core/tools/local}/read-context.d.ts +0 -0
- /package/dist/{tools → agent-core/tools/local}/read-context.js +0 -0
- /package/dist/{tools/local-workspace-tools.d.ts → agent-core/tools/local/workspace-tools.d.ts} +0 -0
- /package/dist/{tools → agent-core/tools}/runtime.js +0 -0
- /package/dist/{tools → agent-core/tools}/scheduler.d.ts +0 -0
- /package/dist/{tools → agent-core/tools}/scheduler.js +0 -0
- /package/dist/{tools → agent-core/tools}/shared/path-resolver.d.ts +0 -0
- /package/dist/{tools → agent-core/tools}/shared/path-resolver.js +0 -0
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { JsonlSessionStore } from '../session/jsonl-store.js';
|
|
2
|
+
import type { SubagentSessionControllerBackend } from '../subagent/session-controller.js';
|
|
3
|
+
export declare function createSubagentBackend(store: JsonlSessionStore, workspace: string): SubagentSessionControllerBackend;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { MarAgentError } from '../error.js';
|
|
2
|
+
export function createSubagentBackend(store, workspace) {
|
|
3
|
+
return {
|
|
4
|
+
createSession: async (input) => {
|
|
5
|
+
const session = await store.createSession({
|
|
6
|
+
workspace,
|
|
7
|
+
title: input.title,
|
|
8
|
+
source: input.source
|
|
9
|
+
});
|
|
10
|
+
return { id: session.id };
|
|
11
|
+
},
|
|
12
|
+
deleteSession: async (sessionId) => {
|
|
13
|
+
await store.delete(sessionId);
|
|
14
|
+
},
|
|
15
|
+
listChildren: async (parentSessionId) => {
|
|
16
|
+
const sessions = await store.listSubagentChildren(parentSessionId);
|
|
17
|
+
return Promise.all(sessions.map(async (session) => ({
|
|
18
|
+
id: session.id,
|
|
19
|
+
createdAt: session.createdAt,
|
|
20
|
+
lastActivityAt: session.lastActivityAt,
|
|
21
|
+
source: session.source,
|
|
22
|
+
records: await store.read(session.id)
|
|
23
|
+
})));
|
|
24
|
+
},
|
|
25
|
+
loadChild: async (parentSessionId, childSessionId) => {
|
|
26
|
+
let session;
|
|
27
|
+
try {
|
|
28
|
+
session = await store.getSession(childSessionId);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
if (error instanceof MarAgentError && error.code === 'MAR_AGENT_SESSION_NOT_FOUND')
|
|
32
|
+
return undefined;
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
if (session.source.type !== 'subagent' || session.source.parentSessionId !== parentSessionId)
|
|
36
|
+
return undefined;
|
|
37
|
+
return {
|
|
38
|
+
id: session.id,
|
|
39
|
+
createdAt: session.createdAt,
|
|
40
|
+
lastActivityAt: session.lastActivityAt,
|
|
41
|
+
source: session.source,
|
|
42
|
+
records: await store.read(session.id)
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { MarAgentHost } from '../host/contracts.js';
|
|
2
|
+
import type { MarAgentModelConfiguration } from '../model/configuration.js';
|
|
3
|
+
import type { ExecutionResult, RolloutBudgetOptions, RunInput } from '../runtime/contracts.js';
|
|
4
|
+
import type { MarAgentEvent } from '../runtime/events.js';
|
|
5
|
+
import type { MarAgentSessionPage, MarAgentSessionSummary } from '../session/catalog.js';
|
|
6
|
+
import type { SessionListInput, SessionSource } from '../session/types.js';
|
|
7
|
+
export interface CreateSessionInput {
|
|
8
|
+
workspace: string;
|
|
9
|
+
title?: string;
|
|
10
|
+
}
|
|
11
|
+
export type { HostExecutionExtensions, HostSessionResourceSnapshot, HostSkill, MarAgentHost } from '../host/contracts.js';
|
|
12
|
+
export type { AccessMode, ExecutionMode, ExecutionResult, MarAgentImageMetadata, RolloutBudgetOptions, RunInput, RunInputImage } from '../runtime/contracts.js';
|
|
13
|
+
export type { MarAgentEvent, MarAgentEventBase } from '../runtime/events.js';
|
|
14
|
+
export type { CodeCellEventData, MarAgentToolArtifact, MarAgentToolImageArtifact, McpCatalogTool, McpToolCallContext, McpToolCatalog, McpToolCatalogContext, ToolCall, ToolExecutionContext, ToolExecutionResult } from '../tools/contracts.js';
|
|
15
|
+
/** A live execution exposes streamed events separately from its terminal result. */
|
|
16
|
+
export interface ExecutionHandle extends AsyncIterable<MarAgentEvent> {
|
|
17
|
+
readonly executionId: string;
|
|
18
|
+
result(): Promise<ExecutionResult>;
|
|
19
|
+
/** Signals abort; await result() to observe the terminal status and cleanup. */
|
|
20
|
+
cancel(): void;
|
|
21
|
+
}
|
|
22
|
+
/** A persisted Session permits one active main execution at a time. */
|
|
23
|
+
export interface MarAgentSession {
|
|
24
|
+
readonly id: string;
|
|
25
|
+
run(input: RunInput): ExecutionHandle;
|
|
26
|
+
plan(input: RunInput): ExecutionHandle;
|
|
27
|
+
compact(input?: Partial<RunInput>): ExecutionHandle;
|
|
28
|
+
cancel(executionId: string): Promise<void>;
|
|
29
|
+
}
|
|
30
|
+
export interface MarAgent {
|
|
31
|
+
createSession(input: CreateSessionInput): Promise<MarAgentSession>;
|
|
32
|
+
openSession(sessionId: string): Promise<MarAgentSession>;
|
|
33
|
+
listSessions(input?: SessionListInput): Promise<MarAgentSessionPage>;
|
|
34
|
+
clearSession(sessionId: string): Promise<void>;
|
|
35
|
+
/** Rebinds future main executions only; running subagents keep their captured model providers. */
|
|
36
|
+
reconfigureModels(input: {
|
|
37
|
+
readonly models: readonly MarAgentModelConfiguration[];
|
|
38
|
+
readonly defaultModelId?: string;
|
|
39
|
+
}): Promise<void>;
|
|
40
|
+
deleteSession(sessionId: string): Promise<void>;
|
|
41
|
+
/** Cancels active executions, then closes SDK-owned providers, the Host and the Session store. */
|
|
42
|
+
dispose(): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
export interface CreateMarAgentOptions {
|
|
45
|
+
mode: 'normal' | 'node';
|
|
46
|
+
host: MarAgentHost;
|
|
47
|
+
models: readonly MarAgentModelConfiguration[];
|
|
48
|
+
defaultModelId?: string;
|
|
49
|
+
systemInstruction?: string;
|
|
50
|
+
workspaceMapping?: {
|
|
51
|
+
readonly logicalPath: string;
|
|
52
|
+
readonly physicalPath: string;
|
|
53
|
+
};
|
|
54
|
+
rolloutBudget?: false | RolloutBudgetOptions;
|
|
55
|
+
}
|
|
56
|
+
export type { MarAgentSessionSummary, SessionListInput, SessionSource };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { MarAgentImageMetadata } from '../runtime/contracts.js';
|
|
2
|
+
import type { MarAgentEvent } from '../runtime/events.js';
|
|
1
3
|
import type { SessionListInput, SessionSource } from './types.js';
|
|
2
|
-
import type { MarAgentEvent, MarAgentImageMetadata } from '../sdk/types.js';
|
|
3
4
|
export interface MarAgentSessionSummary {
|
|
4
5
|
id: string;
|
|
5
6
|
title: string;
|
|
@@ -29,6 +29,7 @@ export type ContextGcBase = {
|
|
|
29
29
|
readonly recordId: string;
|
|
30
30
|
};
|
|
31
31
|
export interface ContextGcTarget {
|
|
32
|
+
readonly observationId?: string;
|
|
32
33
|
readonly sequence: number;
|
|
33
34
|
readonly recordId: string;
|
|
34
35
|
readonly role: 'tool_call' | 'tool' | 'provider';
|
|
@@ -37,6 +38,7 @@ export interface ContextGcTarget {
|
|
|
37
38
|
readonly sourceHash: string;
|
|
38
39
|
}
|
|
39
40
|
export interface ContextGcReadItemReplacement {
|
|
41
|
+
readonly supersededByCallId?: string;
|
|
40
42
|
readonly index: number;
|
|
41
43
|
readonly path: string;
|
|
42
44
|
readonly replacement: string;
|
|
@@ -58,6 +60,7 @@ export type ContextGcReplacement = {
|
|
|
58
60
|
readonly evidenceSequence: number;
|
|
59
61
|
} | {
|
|
60
62
|
readonly kind: 'EXEC_OUTPUT';
|
|
63
|
+
readonly terminalCallId?: string;
|
|
61
64
|
readonly callId: string;
|
|
62
65
|
readonly target: ContextGcTarget;
|
|
63
66
|
readonly replacementContent: string;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { posix, win32 } from 'node:path';
|
|
3
3
|
import { isDeepStrictEqual } from 'node:util';
|
|
4
|
-
import {
|
|
4
|
+
import { codeCallEvidence, callsFromRecord, codeObservationEvidence, observationsFromRecord, retainedCodeInputs } from './context-gc-observations.js';
|
|
5
|
+
import { parseReadContextOutput } from '../tools/local/read-context.js';
|
|
5
6
|
import { codeCellCompletionSequence, contextGcApplyPatchInputReplacement, contextGcCodeModeInputReplacement, contextGcCodeModeOutputReplacement, contextGcExecInputReplacement, contextGcExecOutputReplacement, contextGcPatchResultFromCompletedPayload, contextGcStaleReadReplacement, contextGcWebOutputReplacement, normalizeContextGcCodeModeInput, normalizeContextGcExecResult } from './context-gc-replacements.js';
|
|
6
7
|
import { contextGcSubagentNeedsRetainedPriorFinal, contextGcSubagentOutputReplacement, contextGcSubagentSnapshotIsPreciselyCovered, contextGcSubagentSnapshotIsSuperseded, normalizeContextGcSubagentSnapshot } from './context-gc-subagent.js';
|
|
7
8
|
export const CONTEXT_GC_CHECKPOINT_VERSION = 1;
|
|
@@ -57,7 +58,7 @@ export function contextGcLogicalPathKey(path, workspace, platform) {
|
|
|
57
58
|
return resolved;
|
|
58
59
|
}
|
|
59
60
|
export function contextGcTargetKey(target) {
|
|
60
|
-
return `${target.sequence}:${target.recordId}:${target.role}:${target.callId ?? ''}:${target.toolName ?? ''}`;
|
|
61
|
+
return `${target.sequence}:${target.recordId}:${target.role}:${target.callId ?? ''}:${target.toolName ?? ''}${target.observationId ? `:${target.observationId}` : ''}`;
|
|
61
62
|
}
|
|
62
63
|
export function contextGcReplacementKey(replacement) {
|
|
63
64
|
return contextGcTargetKey(replacement.target);
|
|
@@ -154,6 +155,8 @@ export function validateContextGcCheckpoint(records, record, workspace = session
|
|
|
154
155
|
if (contextGcSourceProjectionHash(records, payload.boundarySequence, payload.base) !==
|
|
155
156
|
payload.sourceProjectionHash)
|
|
156
157
|
return undefined;
|
|
158
|
+
// Later cell completion cannot retroactively authorize an earlier checkpoint.
|
|
159
|
+
records = records.filter((item) => item.sequence <= payload.boundarySequence);
|
|
157
160
|
const recordsBySequence = new Map(records.map((item) => [item.sequence, item]));
|
|
158
161
|
if (!triggerMatchesRecords(records, recordsBySequence, payload))
|
|
159
162
|
return undefined;
|
|
@@ -225,13 +228,39 @@ function targetMatchesRecord(target, record) {
|
|
|
225
228
|
const messageCallId = modelContextCallId(record.payload);
|
|
226
229
|
const messageToolName = modelContextToolName(record.payload);
|
|
227
230
|
return ((target.callId === undefined || target.callId === messageCallId) &&
|
|
231
|
+
(target.observationId === undefined ||
|
|
232
|
+
observationsFromRecord(record)?.some((value) => value.id === target.observationId) ===
|
|
233
|
+
true) &&
|
|
228
234
|
(target.toolName === undefined || target.toolName === messageToolName));
|
|
229
235
|
}
|
|
230
236
|
/** A checkpoint draft is valid only when its replacements match the source records and evidence. */
|
|
231
237
|
function replacementMatchesRecords(replacement, records, recordsBySequence, workspace, platform) {
|
|
232
|
-
|
|
238
|
+
let source = recordsBySequence.get(replacement.target.sequence);
|
|
233
239
|
if (!source || !isRecord(source.payload))
|
|
234
240
|
return false;
|
|
241
|
+
if (replacement.target.observationId) {
|
|
242
|
+
const selected = observationsFromRecord(source)?.find((value) => value.id === replacement.target.observationId);
|
|
243
|
+
if (!selected)
|
|
244
|
+
return false;
|
|
245
|
+
if (selected.type === 'tool_result') {
|
|
246
|
+
const evidence = codeObservationEvidence(records, source, selected);
|
|
247
|
+
if (!evidence)
|
|
248
|
+
return false;
|
|
249
|
+
source = {
|
|
250
|
+
...source,
|
|
251
|
+
payload: {
|
|
252
|
+
...source.payload,
|
|
253
|
+
callId: selected.source.callId,
|
|
254
|
+
content: selected.result.content
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
else
|
|
259
|
+
source = { ...source, payload: { ...source.payload, content: selected.value } };
|
|
260
|
+
recordsBySequence = new Map(recordsBySequence).set(source.sequence, source);
|
|
261
|
+
}
|
|
262
|
+
if (!isRecord(source.payload))
|
|
263
|
+
return false;
|
|
235
264
|
if (replacement.kind === 'READ_OUTPUT_ITEMS') {
|
|
236
265
|
if (!workspace || toolNameForCallId(records, replacement.callId, source.sequence) !== 'read')
|
|
237
266
|
return false;
|
|
@@ -243,7 +272,7 @@ function replacementMatchesRecords(replacement, records, recordsBySequence, work
|
|
|
243
272
|
const originalItems = new Map(parsed.items.map((item) => [item.index, item]));
|
|
244
273
|
return replacement.items.every((item) => {
|
|
245
274
|
const original = originalItems.get(item.index);
|
|
246
|
-
const evidence = successfulPatchEvidenceForPath(records, recordsBySequence, item.evidenceSequence, item.path, workspace, platform);
|
|
275
|
+
const evidence = successfulPatchEvidenceForPath(records, recordsBySequence, item.evidenceSequence, item.path, workspace, platform, item.supersededByCallId);
|
|
247
276
|
return (original?.pathTruncated === false &&
|
|
248
277
|
original?.path === item.path &&
|
|
249
278
|
evidence !== undefined &&
|
|
@@ -274,7 +303,9 @@ function replacementMatchesRecords(replacement, records, recordsBySequence, work
|
|
|
274
303
|
codeCellCompletionSequence(records, evidence.completed) !== undefined &&
|
|
275
304
|
evidence.call.sequence === replacement.target.sequence &&
|
|
276
305
|
input !== undefined &&
|
|
277
|
-
isDeepStrictEqual(replacement.replacementArguments, contextGcCodeModeInputReplacement(input)
|
|
306
|
+
isDeepStrictEqual(replacement.replacementArguments, contextGcCodeModeInputReplacement(input, observationsFromRecord(evidence.result)
|
|
307
|
+
? retainedCodeInputs(records, replacement.callId)
|
|
308
|
+
: [])));
|
|
278
309
|
}
|
|
279
310
|
if (replacement.kind === 'CODE_MODE_OUTPUT') {
|
|
280
311
|
const evidence = ['code_mode', 'code_exec', 'code_exec_wait']
|
|
@@ -288,12 +319,16 @@ function replacementMatchesRecords(replacement, records, recordsBySequence, work
|
|
|
288
319
|
isRecord(evidence.completed.payload) &&
|
|
289
320
|
typeof evidence.completed.payload.truncated === 'boolean' &&
|
|
290
321
|
replacement.replacementContent ===
|
|
291
|
-
contextGcCodeModeOutputReplacement(
|
|
322
|
+
contextGcCodeModeOutputReplacement(source.payload.content, replacement.target.observationId
|
|
323
|
+
? observationsFromRecord(source)?.some((value) => value.id === replacement.target.observationId &&
|
|
324
|
+
value.type === 'value' &&
|
|
325
|
+
value.truncated === true) === true
|
|
326
|
+
: evidence.completed.payload.truncated));
|
|
292
327
|
}
|
|
293
328
|
if (replacement.kind === 'SUBAGENT_OUTPUT') {
|
|
294
329
|
const retainedPriorFinal = replacement.retainedPriorFinal;
|
|
295
330
|
const sourceEvidence = successfulToolEvidence(records, recordsBySequence, source.sequence, replacement.toolName);
|
|
296
|
-
const terminalEvidence = successfulToolEvidence(records, recordsBySequence, replacement.evidenceSequence, replacement.terminalToolName);
|
|
331
|
+
const terminalEvidence = successfulToolEvidence(records, recordsBySequence, replacement.evidenceSequence, replacement.terminalToolName, replacement.terminalCallId);
|
|
297
332
|
if (!sourceEvidence ||
|
|
298
333
|
sourceEvidence.callId !== replacement.callId ||
|
|
299
334
|
!terminalEvidence ||
|
|
@@ -304,7 +339,7 @@ function replacementMatchesRecords(replacement, records, recordsBySequence, work
|
|
|
304
339
|
let retainedPriorFinalEvidence;
|
|
305
340
|
let retainedPriorFinalSnapshot;
|
|
306
341
|
if (retainedPriorFinal !== undefined) {
|
|
307
|
-
retainedPriorFinalEvidence = successfulToolEvidence(records, recordsBySequence, retainedPriorFinal.evidenceSequence, retainedPriorFinal.toolName);
|
|
342
|
+
retainedPriorFinalEvidence = successfulToolEvidence(records, recordsBySequence, retainedPriorFinal.evidenceSequence, retainedPriorFinal.toolName, retainedPriorFinal.callId);
|
|
308
343
|
if (!retainedPriorFinalEvidence ||
|
|
309
344
|
retainedPriorFinalEvidence.callId !== retainedPriorFinal.callId ||
|
|
310
345
|
!isRecord(retainedPriorFinalEvidence.result.payload))
|
|
@@ -319,7 +354,7 @@ function replacementMatchesRecords(replacement, records, recordsBySequence, work
|
|
|
319
354
|
(retainedPriorFinal !== undefined) &&
|
|
320
355
|
(retainedPriorFinalEvidence === undefined ||
|
|
321
356
|
retainedPriorFinalEvidence.result.sequence < sourceEvidence.result.sequence) &&
|
|
322
|
-
sourceEvidence.
|
|
357
|
+
sourceEvidence.completed.sequence < terminalEvidence.completed.sequence &&
|
|
323
358
|
(contextGcSubagentSnapshotIsSuperseded(sourceSnapshot, terminalSnapshot, retainedPriorFinalSnapshot) ||
|
|
324
359
|
contextGcSubagentSnapshotIsPreciselyCovered(sourceSnapshot, terminalSnapshot)) &&
|
|
325
360
|
replacement.replacementContent ===
|
|
@@ -351,8 +386,8 @@ function replacementMatchesRecords(replacement, records, recordsBySequence, work
|
|
|
351
386
|
return false;
|
|
352
387
|
if (replacement.kind === 'TOOL_CALL_INPUT')
|
|
353
388
|
return isDeepStrictEqual(replacement.replacementArguments, contextGcExecInputReplacement(source.payload.arguments, execInputReplacementFormatVersion(replacement.replacementArguments), replacement.toolName));
|
|
354
|
-
const targetEvidence = successfulToolEvidence(records, recordsBySequence, source.sequence, 'exec') ??
|
|
355
|
-
successfulToolEvidence(records, recordsBySequence, source.sequence, 'exec_wait');
|
|
389
|
+
const targetEvidence = successfulToolEvidence(records, recordsBySequence, source.sequence, 'exec', replacement.callId) ??
|
|
390
|
+
successfulToolEvidence(records, recordsBySequence, source.sequence, 'exec_wait', replacement.callId);
|
|
356
391
|
const result = normalizeContextGcExecResult(source.payload.content, targetEvidence?.completed.payload);
|
|
357
392
|
return (result !== undefined &&
|
|
358
393
|
replacement.replacementContent ===
|
|
@@ -401,7 +436,7 @@ function toolNameForCallId(records, callId, beforeSequence) {
|
|
|
401
436
|
? call.payload.name
|
|
402
437
|
: undefined;
|
|
403
438
|
}
|
|
404
|
-
function successfulToolEvidence(records, recordsBySequence, evidenceSequence, toolName) {
|
|
439
|
+
function successfulToolEvidence(records, recordsBySequence, evidenceSequence, toolName, expectedCallId) {
|
|
405
440
|
const result = recordsBySequence.get(evidenceSequence);
|
|
406
441
|
if (result?.type !== 'model.context' ||
|
|
407
442
|
!isRecord(result.payload) ||
|
|
@@ -410,8 +445,28 @@ function successfulToolEvidence(records, recordsBySequence, evidenceSequence, to
|
|
|
410
445
|
return undefined;
|
|
411
446
|
const callId = result.payload.callId;
|
|
412
447
|
const call = modelToolCallForCallId(records, callId, result.sequence);
|
|
413
|
-
if (!call ||
|
|
448
|
+
if (!call ||
|
|
449
|
+
!isRecord(call.payload) ||
|
|
450
|
+
call.payload.name !== toolName ||
|
|
451
|
+
(expectedCallId && expectedCallId !== callId)) {
|
|
452
|
+
for (const observation of observationsFromRecord(result) ?? []) {
|
|
453
|
+
if (observation.type !== 'tool_result' ||
|
|
454
|
+
observation.source.toolName !== toolName ||
|
|
455
|
+
(expectedCallId && observation.source.callId !== expectedCallId))
|
|
456
|
+
continue;
|
|
457
|
+
const evidence = codeObservationEvidence(records, result, observation);
|
|
458
|
+
if (evidence)
|
|
459
|
+
return evidence;
|
|
460
|
+
}
|
|
461
|
+
for (const entry of callsFromRecord(result) ?? []) {
|
|
462
|
+
if (entry.toolName !== toolName || (expectedCallId && entry.callId !== expectedCallId))
|
|
463
|
+
continue;
|
|
464
|
+
const evidence = codeCallEvidence(records, result, entry);
|
|
465
|
+
if (evidence)
|
|
466
|
+
return evidence;
|
|
467
|
+
}
|
|
414
468
|
return undefined;
|
|
469
|
+
}
|
|
415
470
|
const completed = records.findLast((record) => record.sequence > call.sequence &&
|
|
416
471
|
record.sequence < result.sequence &&
|
|
417
472
|
record.type === 'tool.completed' &&
|
|
@@ -441,11 +496,29 @@ function hasFailedToolEvidence(records, call, result, toolName) {
|
|
|
441
496
|
record.payload.toolName === toolName);
|
|
442
497
|
}
|
|
443
498
|
function modelToolCallForCallId(records, callId, beforeSequence) {
|
|
444
|
-
|
|
499
|
+
const direct = records.findLast((record) => record.sequence < beforeSequence &&
|
|
445
500
|
record.type === 'model.context' &&
|
|
446
501
|
isRecord(record.payload) &&
|
|
447
502
|
record.payload.role === 'tool_call' &&
|
|
448
503
|
record.payload.callId === callId);
|
|
504
|
+
if (direct)
|
|
505
|
+
return direct;
|
|
506
|
+
const started = records.findLast((record) => record.sequence < beforeSequence &&
|
|
507
|
+
record.type === 'tool.started' &&
|
|
508
|
+
isRecord(record.payload) &&
|
|
509
|
+
record.payload.callId === callId &&
|
|
510
|
+
typeof record.payload.parentCallId === 'string');
|
|
511
|
+
return started && isRecord(started.payload)
|
|
512
|
+
? {
|
|
513
|
+
...started,
|
|
514
|
+
payload: {
|
|
515
|
+
role: 'tool_call',
|
|
516
|
+
name: started.payload.toolName,
|
|
517
|
+
callId,
|
|
518
|
+
arguments: started.payload.input
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
: undefined;
|
|
449
522
|
}
|
|
450
523
|
function modelToolResultForCall(records, call, beforeSequence) {
|
|
451
524
|
if (!isRecord(call.payload) || typeof call.payload.callId !== 'string')
|
|
@@ -458,8 +531,8 @@ function modelToolResultForCall(records, call, beforeSequence) {
|
|
|
458
531
|
record.payload.role === 'tool' &&
|
|
459
532
|
record.payload.callId === callId);
|
|
460
533
|
}
|
|
461
|
-
function successfulPatchEvidenceForPath(records, recordsBySequence, evidenceSequence, path, workspace, platform) {
|
|
462
|
-
const evidence = successfulToolEvidence(records, recordsBySequence, evidenceSequence, 'apply_patch');
|
|
534
|
+
function successfulPatchEvidenceForPath(records, recordsBySequence, evidenceSequence, path, workspace, platform, expectedCallId) {
|
|
535
|
+
const evidence = successfulToolEvidence(records, recordsBySequence, evidenceSequence, 'apply_patch', expectedCallId);
|
|
463
536
|
if (!evidence || !isRecord(evidence.completed.payload))
|
|
464
537
|
return undefined;
|
|
465
538
|
const result = contextGcPatchResultFromCompletedPayload(evidence.completed.payload);
|
|
@@ -475,8 +548,9 @@ function successfulPatchEvidenceForPath(records, recordsBySequence, evidenceSequ
|
|
|
475
548
|
: undefined;
|
|
476
549
|
}
|
|
477
550
|
function isSuccessfulExecLifecycleEvidence(replacement, source, records, recordsBySequence) {
|
|
478
|
-
const
|
|
479
|
-
|
|
551
|
+
const expectedTerminal = replacement.kind === 'EXEC_OUTPUT' ? replacement.terminalCallId : undefined;
|
|
552
|
+
const evidence = successfulToolEvidence(records, recordsBySequence, replacement.evidenceSequence, 'exec', expectedTerminal) ??
|
|
553
|
+
successfulToolEvidence(records, recordsBySequence, replacement.evidenceSequence, 'exec_wait', expectedTerminal);
|
|
480
554
|
if (!evidence || !isRecord(evidence.call.payload) || !isRecord(evidence.result.payload))
|
|
481
555
|
return false;
|
|
482
556
|
const finalResult = normalizeContextGcExecResult(evidence.result.payload.content, evidence.completed.payload);
|
|
@@ -497,7 +571,7 @@ function isSuccessfulExecLifecycleEvidence(replacement, source, records, records
|
|
|
497
571
|
: modelToolResultForCall(records, targetCall, evidence.result.sequence);
|
|
498
572
|
if (!targetResult)
|
|
499
573
|
return false;
|
|
500
|
-
const targetEvidence = successfulToolEvidence(records, recordsBySequence, targetResult.sequence, targetCall.payload.name);
|
|
574
|
+
const targetEvidence = successfulToolEvidence(records, recordsBySequence, targetResult.sequence, targetCall.payload.name, replacement.callId);
|
|
501
575
|
if (!targetEvidence || targetEvidence.call.sequence !== targetCall.sequence)
|
|
502
576
|
return false;
|
|
503
577
|
if (targetEvidence.callId === evidence.callId)
|
|
@@ -597,7 +671,7 @@ function isContextGcReplacement(value) {
|
|
|
597
671
|
if (!isRecord(value) ||
|
|
598
672
|
!isContextGcTarget(value.target) ||
|
|
599
673
|
!isNonemptyString(value.callId) ||
|
|
600
|
-
value.target.callId !== value.callId)
|
|
674
|
+
(value.target.callId !== value.callId && value.target.observationId === undefined))
|
|
601
675
|
return false;
|
|
602
676
|
if (value.kind === 'READ_OUTPUT_ITEMS') {
|
|
603
677
|
const items = value.items;
|
|
@@ -607,7 +681,14 @@ function isContextGcReplacement(value) {
|
|
|
607
681
|
Array.isArray(items) &&
|
|
608
682
|
items.length > 0 &&
|
|
609
683
|
items.every((item) => isRecord(item) &&
|
|
610
|
-
hasOnlyKeys(item, [
|
|
684
|
+
hasOnlyKeys(item, [
|
|
685
|
+
'index',
|
|
686
|
+
'path',
|
|
687
|
+
'replacement',
|
|
688
|
+
'evidenceSequence',
|
|
689
|
+
'supersededByCallId'
|
|
690
|
+
]) &&
|
|
691
|
+
(item.supersededByCallId === undefined || isNonemptyString(item.supersededByCallId)) &&
|
|
611
692
|
isNonnegativeInteger(item.index) &&
|
|
612
693
|
isNonemptyString(item.path) &&
|
|
613
694
|
isNonemptyString(item.replacement) &&
|
|
@@ -697,14 +778,32 @@ function isContextGcReplacement(value) {
|
|
|
697
778
|
isNonemptyString(value.replacementContent) &&
|
|
698
779
|
isPositiveInteger(value.evidenceSequence));
|
|
699
780
|
return (value.kind === 'EXEC_OUTPUT' &&
|
|
700
|
-
hasOnlyKeys(value, [
|
|
781
|
+
hasOnlyKeys(value, [
|
|
782
|
+
'kind',
|
|
783
|
+
'callId',
|
|
784
|
+
'target',
|
|
785
|
+
'replacementContent',
|
|
786
|
+
'evidenceSequence',
|
|
787
|
+
'terminalCallId'
|
|
788
|
+
]) &&
|
|
789
|
+
(value.terminalCallId === undefined || isNonemptyString(value.terminalCallId)) &&
|
|
701
790
|
value.target.role === 'tool' &&
|
|
702
791
|
isNonemptyString(value.replacementContent) &&
|
|
703
792
|
isPositiveInteger(value.evidenceSequence));
|
|
704
793
|
}
|
|
705
794
|
function isContextGcTarget(value) {
|
|
706
795
|
return (isRecord(value) &&
|
|
707
|
-
hasOnlyKeys(value, [
|
|
796
|
+
hasOnlyKeys(value, [
|
|
797
|
+
'sequence',
|
|
798
|
+
'recordId',
|
|
799
|
+
'role',
|
|
800
|
+
'callId',
|
|
801
|
+
'toolName',
|
|
802
|
+
'sourceHash',
|
|
803
|
+
'observationId'
|
|
804
|
+
]) &&
|
|
805
|
+
(value.observationId === undefined ||
|
|
806
|
+
(value.role === 'tool' && isNonemptyString(value.observationId))) &&
|
|
708
807
|
isPositiveInteger(value.sequence) &&
|
|
709
808
|
isNonemptyString(value.recordId) &&
|
|
710
809
|
(value.role === 'tool_call' || value.role === 'tool' || value.role === 'provider') &&
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { SessionRecord } from './jsonl-store.js';
|
|
2
|
+
import { type CodeObservation, type CodeToolCallRecord } from '../tools/code-mode/observations.js';
|
|
3
|
+
/** Resolve private observation identity to real dispatch facts, not Provider tool calls. */
|
|
4
|
+
export declare function codeObservationEvidence(records: readonly SessionRecord[], result: SessionRecord, observation: Extract<CodeObservation, {
|
|
5
|
+
type: 'tool_result';
|
|
6
|
+
}>): {
|
|
7
|
+
callId: string;
|
|
8
|
+
call: SessionRecord;
|
|
9
|
+
completed: SessionRecord;
|
|
10
|
+
result: SessionRecord;
|
|
11
|
+
} | undefined;
|
|
12
|
+
export declare function observationsFromRecord(record: SessionRecord): CodeObservation[] | undefined;
|
|
13
|
+
export declare function codeCallEvidence(records: readonly SessionRecord[], result: SessionRecord, entry: CodeToolCallRecord): {
|
|
14
|
+
result: {
|
|
15
|
+
payload: {
|
|
16
|
+
role: string;
|
|
17
|
+
callId: string;
|
|
18
|
+
content: string;
|
|
19
|
+
};
|
|
20
|
+
schemaVersion: 1;
|
|
21
|
+
recordId: string;
|
|
22
|
+
sequence: number;
|
|
23
|
+
timestamp: string;
|
|
24
|
+
sessionId: string;
|
|
25
|
+
executionId?: string;
|
|
26
|
+
turnId?: string;
|
|
27
|
+
type: string;
|
|
28
|
+
};
|
|
29
|
+
callId: string;
|
|
30
|
+
call: SessionRecord;
|
|
31
|
+
completed: SessionRecord;
|
|
32
|
+
} | undefined;
|
|
33
|
+
export declare function callsFromRecord(record: SessionRecord): CodeToolCallRecord[] | undefined;
|
|
34
|
+
export declare function retainedCodeInputs(records: readonly SessionRecord[], parentCallId: string): {
|
|
35
|
+
callId: unknown;
|
|
36
|
+
toolName: unknown;
|
|
37
|
+
input: unknown;
|
|
38
|
+
}[];
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
2
|
+
import { codeCellCompletionSequence, contextGcPatchResultFromCompletedPayload } from './context-gc-replacements.js';
|
|
3
|
+
import { parseCodeCalls, parseObservations } from '../tools/code-mode/observations.js';
|
|
4
|
+
/** Resolve private observation identity to real dispatch facts, not Provider tool calls. */
|
|
5
|
+
export function codeObservationEvidence(records, result, observation) {
|
|
6
|
+
if (observation.outcome !== 'completed')
|
|
7
|
+
return undefined;
|
|
8
|
+
const started = records.findLast((record) => record.sequence < result.sequence &&
|
|
9
|
+
record.type === 'tool.started' &&
|
|
10
|
+
isRecord(record.payload) &&
|
|
11
|
+
record.payload.callId === observation.source.callId &&
|
|
12
|
+
record.payload.toolName === observation.source.toolName &&
|
|
13
|
+
typeof record.payload.parentCallId === 'string' &&
|
|
14
|
+
isDeepStrictEqual(record.payload.input, observation.source.input));
|
|
15
|
+
if (!started || !isRecord(started.payload))
|
|
16
|
+
return undefined;
|
|
17
|
+
const parentId = started.payload.parentCallId;
|
|
18
|
+
const parent = records.find((record) => record.type === 'model.context' &&
|
|
19
|
+
record.sequence < started.sequence &&
|
|
20
|
+
isRecord(record.payload) &&
|
|
21
|
+
record.payload.role === 'tool_call' &&
|
|
22
|
+
record.payload.callId === parentId &&
|
|
23
|
+
(record.payload.name === 'code_exec' || record.payload.name === 'code_mode'));
|
|
24
|
+
if (!parent)
|
|
25
|
+
return undefined;
|
|
26
|
+
const original = records.find((record) => record.recordId === result.recordId) ?? result;
|
|
27
|
+
if (!isRecord(original.payload))
|
|
28
|
+
return undefined;
|
|
29
|
+
const outerId = original.payload.callId;
|
|
30
|
+
const outer = records.findLast((record) => record.sequence < result.sequence &&
|
|
31
|
+
record.type === 'tool.completed' &&
|
|
32
|
+
isRecord(record.payload) &&
|
|
33
|
+
record.payload.callId === outerId &&
|
|
34
|
+
(record.payload.toolName === 'code_exec' ||
|
|
35
|
+
record.payload.toolName === 'code_mode' ||
|
|
36
|
+
record.payload.toolName === 'code_exec_wait'));
|
|
37
|
+
if (!outer ||
|
|
38
|
+
codeCellCompletionSequence(records, outer) === undefined ||
|
|
39
|
+
records.some((record) => record.sequence < result.sequence &&
|
|
40
|
+
record.type === 'tool.failed' &&
|
|
41
|
+
isRecord(record.payload) &&
|
|
42
|
+
record.payload.callId === outerId))
|
|
43
|
+
return undefined;
|
|
44
|
+
if (original.payload.callId !== parentId) {
|
|
45
|
+
const initial = records.find((record) => record.sequence < outer.sequence &&
|
|
46
|
+
record.type === 'tool.completed' &&
|
|
47
|
+
isRecord(record.payload) &&
|
|
48
|
+
record.payload.callId === parentId);
|
|
49
|
+
if (!initial ||
|
|
50
|
+
!isRecord(outer.payload) ||
|
|
51
|
+
outer.payload.toolName !== 'code_exec_wait' ||
|
|
52
|
+
!isRecord(initial.payload) ||
|
|
53
|
+
!isRecord(outer.payload.data) ||
|
|
54
|
+
!isRecord(initial.payload.data) ||
|
|
55
|
+
typeof outer.payload.data.cellId !== 'string' ||
|
|
56
|
+
outer.payload.data.cellId !== initial.payload.data.cellId)
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
const completed = records.findLast((record) => record.sequence > started.sequence &&
|
|
60
|
+
record.sequence < result.sequence &&
|
|
61
|
+
record.type === 'tool.completed' &&
|
|
62
|
+
isRecord(record.payload) &&
|
|
63
|
+
record.payload.callId === observation.source.callId &&
|
|
64
|
+
record.payload.toolName === observation.source.toolName &&
|
|
65
|
+
record.payload.parentCallId === parentId);
|
|
66
|
+
if (!completed ||
|
|
67
|
+
records.some((record) => record.sequence > started.sequence &&
|
|
68
|
+
record.sequence < result.sequence &&
|
|
69
|
+
record.type === 'tool.failed' &&
|
|
70
|
+
isRecord(record.payload) &&
|
|
71
|
+
record.payload.callId === observation.source.callId))
|
|
72
|
+
return undefined;
|
|
73
|
+
const call = {
|
|
74
|
+
...started,
|
|
75
|
+
payload: {
|
|
76
|
+
role: 'tool_call',
|
|
77
|
+
name: observation.source.toolName,
|
|
78
|
+
callId: observation.source.callId,
|
|
79
|
+
arguments: observation.source.input
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const selected = {
|
|
83
|
+
...result,
|
|
84
|
+
payload: {
|
|
85
|
+
role: 'tool',
|
|
86
|
+
callId: observation.source.callId,
|
|
87
|
+
content: observation.result.content,
|
|
88
|
+
observationId: observation.id
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
return { callId: observation.source.callId, call, completed, result: selected };
|
|
92
|
+
}
|
|
93
|
+
export function observationsFromRecord(record) {
|
|
94
|
+
return isRecord(record.payload) ? parseObservations(record.payload.observations) : undefined;
|
|
95
|
+
}
|
|
96
|
+
export function codeCallEvidence(records, result, entry) {
|
|
97
|
+
if (entry.status !== 'completed')
|
|
98
|
+
return undefined;
|
|
99
|
+
const evidence = codeObservationEvidence(records, result, {
|
|
100
|
+
type: 'tool_result',
|
|
101
|
+
id: `call:${entry.callId}`,
|
|
102
|
+
source: { callId: entry.callId, toolName: entry.toolName, input: entry.input },
|
|
103
|
+
outcome: 'completed',
|
|
104
|
+
result: { content: '' }
|
|
105
|
+
});
|
|
106
|
+
if (!evidence || !isRecord(evidence.completed.payload))
|
|
107
|
+
return undefined;
|
|
108
|
+
return {
|
|
109
|
+
...evidence,
|
|
110
|
+
result: {
|
|
111
|
+
...evidence.result,
|
|
112
|
+
payload: {
|
|
113
|
+
role: 'tool',
|
|
114
|
+
callId: entry.callId,
|
|
115
|
+
content: JSON.stringify(evidence.completed.payload.data ?? {})
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
export function callsFromRecord(record) {
|
|
121
|
+
return isRecord(record.payload) ? parseCodeCalls(record.payload.calls) : undefined;
|
|
122
|
+
}
|
|
123
|
+
export function retainedCodeInputs(records, parentCallId) {
|
|
124
|
+
return records.flatMap((record) => {
|
|
125
|
+
if (!isRecord(record.payload) ||
|
|
126
|
+
record.type !== 'tool.started' ||
|
|
127
|
+
record.payload.parentCallId !== parentCallId)
|
|
128
|
+
return [];
|
|
129
|
+
const call = record.payload;
|
|
130
|
+
const completedPatch = call.toolName === 'apply_patch' &&
|
|
131
|
+
records.some((next) => next.sequence > record.sequence &&
|
|
132
|
+
next.type === 'tool.completed' &&
|
|
133
|
+
isRecord(next.payload) &&
|
|
134
|
+
next.payload.callId === call.callId &&
|
|
135
|
+
next.payload.toolName === 'apply_patch' &&
|
|
136
|
+
next.payload.parentCallId === parentCallId &&
|
|
137
|
+
contextGcPatchResultFromCompletedPayload(next.payload) !== undefined) &&
|
|
138
|
+
!records.some((next) => next.sequence > record.sequence &&
|
|
139
|
+
next.type === 'tool.failed' &&
|
|
140
|
+
isRecord(next.payload) &&
|
|
141
|
+
next.payload.callId === call.callId);
|
|
142
|
+
// Successful patches have durable file evidence; other inputs retain their direct-mode semantics.
|
|
143
|
+
return completedPatch
|
|
144
|
+
? []
|
|
145
|
+
: [{ callId: call.callId, toolName: call.toolName, input: call.input }];
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function isRecord(value) {
|
|
149
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
150
|
+
}
|
|
@@ -4,7 +4,7 @@ export interface ContextGcCodeModeInput {
|
|
|
4
4
|
readonly inputMode: 'freeform' | 'json';
|
|
5
5
|
}
|
|
6
6
|
export declare function normalizeContextGcCodeModeInput(arguments_: unknown): ContextGcCodeModeInput | undefined;
|
|
7
|
-
export declare function contextGcCodeModeInputReplacement(input: ContextGcCodeModeInput): unknown;
|
|
7
|
+
export declare function contextGcCodeModeInputReplacement(input: ContextGcCodeModeInput, retainedInputs?: readonly unknown[]): unknown;
|
|
8
8
|
export declare function contextGcCodeModeOutputReplacement(originalContent: string, truncated: boolean): string;
|
|
9
9
|
export interface ContextGcPatchFile {
|
|
10
10
|
readonly path: string;
|
|
@@ -14,9 +14,13 @@ export function normalizeContextGcCodeModeInput(arguments_) {
|
|
|
14
14
|
return { code: arguments_.code, inputMode: 'json' };
|
|
15
15
|
return undefined;
|
|
16
16
|
}
|
|
17
|
-
export function contextGcCodeModeInputReplacement(input) {
|
|
17
|
+
export function contextGcCodeModeInputReplacement(input, retainedInputs = []) {
|
|
18
18
|
const replacement = `<context_gc kind="completed_code_mode_input" originalBytes="${Buffer.byteLength(input.code)}" lines="${lineCount(input.code)}" inputMode="${input.inputMode}">Completed Code Mode source was reclaimed after six successful rollouts. The paired output, images, completion evidence, and nested tool side effects remain in history.</context_gc>`;
|
|
19
|
-
|
|
19
|
+
const content = replacement +
|
|
20
|
+
(retainedInputs.length
|
|
21
|
+
? `\nRetained tool instructions: ${JSON.stringify(retainedInputs)}`
|
|
22
|
+
: '');
|
|
23
|
+
return input.inputMode === 'freeform' ? content : { code: content };
|
|
20
24
|
}
|
|
21
25
|
export function contextGcCodeModeOutputReplacement(originalContent, truncated) {
|
|
22
26
|
const preview = unicodeHeadTail(originalContent, CODE_MODE_OUTPUT_PREVIEW_CHARACTERS);
|