dsh-loop-engine-allinone 0.0.0-stage → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +100 -0
- package/CONTRIBUTING.md +78 -0
- package/LICENSE +23 -0
- package/NOTICE +45 -0
- package/README.md +221 -2
- package/README.zh.md +89 -0
- package/SECURITY.md +39 -0
- package/cordis.patch.yml +3 -0
- package/lib/client.js +2166 -0
- package/lib/index.js +11621 -0
- package/lib/invariant.js +453 -0
- package/lib/types/agent-preset-ids.d.ts +276 -0
- package/lib/types/client/LoopEngineBadge.d.ts +71 -0
- package/lib/types/client/LoopEngineComposerSelect.d.ts +126 -0
- package/lib/types/client/LoopEngineSection.d.ts +35 -0
- package/lib/types/client/engine-marks.d.ts +87 -0
- package/lib/types/client/index.d.ts +39 -0
- package/lib/types/client/locales.d.ts +182 -0
- package/lib/types/client/reload.d.ts +135 -0
- package/lib/types/client/session-engine.d.ts +508 -0
- package/lib/types/client/store.d.ts +103 -0
- package/lib/types/client/turn-status.d.ts +234 -0
- package/lib/types/client/use-session-engine.d.ts +74 -0
- package/lib/types/commands.d.ts +77 -0
- package/lib/types/compat.d.ts +25 -0
- package/lib/types/driver-acp/agent.d.ts +289 -0
- package/lib/types/driver-acp/approval.d.ts +27 -0
- package/lib/types/driver-acp/capabilities.d.ts +200 -0
- package/lib/types/driver-acp/client.d.ts +297 -0
- package/lib/types/driver-acp/executable.d.ts +53 -0
- package/lib/types/driver-acp/mapping.d.ts +76 -0
- package/lib/types/driver-acp/profile.d.ts +126 -0
- package/lib/types/driver-acp/runtime.d.ts +45 -0
- package/lib/types/driver-acp/subprocess.d.ts +19 -0
- package/lib/types/driver-acp/terminal.d.ts +98 -0
- package/lib/types/driver-acp/transport.d.ts +43 -0
- package/lib/types/driver-acp/types.d.ts +152 -0
- package/lib/types/driver-cli/capability.d.ts +42 -0
- package/lib/types/driver-cli/cli-agent.d.ts +258 -0
- package/lib/types/driver-cli/cli-loop.d.ts +46 -0
- package/lib/types/driver-cli/flatten.d.ts +35 -0
- package/lib/types/driver-cli/frames.d.ts +128 -0
- package/lib/types/driver-cli/ndjson.d.ts +106 -0
- package/lib/types/driver-cli/session-sink.d.ts +333 -0
- package/lib/types/driver-cli/stream-json.d.ts +61 -0
- package/lib/types/driver-cli/text.d.ts +66 -0
- package/lib/types/driver-cli/transport.d.ts +84 -0
- package/lib/types/driver-core/agents-md-skill-provider.d.ts +72 -0
- package/lib/types/driver-core/assistant-stream.d.ts +68 -0
- package/lib/types/driver-core/context-files.d.ts +62 -0
- package/lib/types/driver-core/host-servers.d.ts +119 -0
- package/lib/types/driver-core/hosted-engine-runtime.d.ts +190 -0
- package/lib/types/driver-core/hosted-tool-vocabulary.d.ts +78 -0
- package/lib/types/driver-core/idle-child.d.ts +57 -0
- package/lib/types/driver-core/image-access.d.ts +25 -0
- package/lib/types/driver-core/inbox.d.ts +104 -0
- package/lib/types/driver-core/model-handover.d.ts +134 -0
- package/lib/types/driver-core/ownership.d.ts +41 -0
- package/lib/types/driver-core/permission-knobs.d.ts +26 -0
- package/lib/types/driver-core/prompt.d.ts +64 -0
- package/lib/types/driver-core/session-lifetime.d.ts +62 -0
- package/lib/types/driver-core/session-model.d.ts +128 -0
- package/lib/types/driver-core/skill-inject.d.ts +59 -0
- package/lib/types/driver-core/step-close.d.ts +49 -0
- package/lib/types/driver-core/step-images.d.ts +62 -0
- package/lib/types/driver-core/step-tools.d.ts +43 -0
- package/lib/types/driver-core/system-head.d.ts +43 -0
- package/lib/types/engine-agy/agent.d.ts +67 -0
- package/lib/types/engine-agy/frames.d.ts +90 -0
- package/lib/types/engine-agy/loop.d.ts +64 -0
- package/lib/types/engine-agy/process.d.ts +173 -0
- package/lib/types/engine-claude/agent.d.ts +186 -0
- package/lib/types/engine-claude/loop.d.ts +73 -0
- package/lib/types/engine-claude/mapping.d.ts +108 -0
- package/lib/types/engine-claude/permission.d.ts +41 -0
- package/lib/types/engine-claude/process.d.ts +59 -0
- package/lib/types/engine-claude/sdk.d.ts +67 -0
- package/lib/types/engine-claude/types.d.ts +28 -0
- package/lib/types/engine-codex/agent.d.ts +216 -0
- package/lib/types/engine-codex/appserver/client.d.ts +80 -0
- package/lib/types/engine-codex/appserver/mapping.d.ts +67 -0
- package/lib/types/engine-codex/appserver/thread.d.ts +66 -0
- package/lib/types/engine-codex/appserver/types.d.ts +225 -0
- package/lib/types/engine-codex/loop.d.ts +75 -0
- package/lib/types/engine-codex/model-handover.d.ts +56 -0
- package/lib/types/engine-codex/permission.d.ts +126 -0
- package/lib/types/engine-codex/skills.d.ts +28 -0
- package/lib/types/engine-codex/types.d.ts +36 -0
- package/lib/types/engine-drivers.d.ts +132 -0
- package/lib/types/engine-grok/agent.d.ts +24 -0
- package/lib/types/engine-grok/loop.d.ts +61 -0
- package/lib/types/engine-grok/process.d.ts +46 -0
- package/lib/types/engine-grok/profile.d.ts +82 -0
- package/lib/types/engine-hermes/agent.d.ts +47 -0
- package/lib/types/engine-hermes/loop.d.ts +56 -0
- package/lib/types/engine-hermes/process.d.ts +92 -0
- package/lib/types/engine-kimi/acp/client.d.ts +123 -0
- package/lib/types/engine-kimi/acp/mapping.d.ts +73 -0
- package/lib/types/engine-kimi/acp/types.d.ts +143 -0
- package/lib/types/engine-kimi/agent.d.ts +24 -0
- package/lib/types/engine-kimi/commands.d.ts +44 -0
- package/lib/types/engine-kimi/loop.d.ts +62 -0
- package/lib/types/engine-kimi/model-handover.d.ts +32 -0
- package/lib/types/engine-kimi/permission.d.ts +28 -0
- package/lib/types/engine-kimi/process.d.ts +47 -0
- package/lib/types/engine-kimi/profile.d.ts +19 -0
- package/lib/types/engine-kimi/skills.d.ts +52 -0
- package/lib/types/engine-kimi/types.d.ts +25 -0
- package/lib/types/engine-minimaxcode/agent.d.ts +24 -0
- package/lib/types/engine-minimaxcode/loop.d.ts +83 -0
- package/lib/types/engine-minimaxcode/process.d.ts +53 -0
- package/lib/types/engine-minimaxcode/profile.d.ts +72 -0
- package/lib/types/engine-of-session.d.ts +97 -0
- package/lib/types/engine-pi/agent.d.ts +230 -0
- package/lib/types/engine-pi/loop.d.ts +72 -0
- package/lib/types/engine-pi/model-handover.d.ts +84 -0
- package/lib/types/engine-pi/permission.d.ts +47 -0
- package/lib/types/engine-pi/rpc/client.d.ts +107 -0
- package/lib/types/engine-pi/rpc/mapping.d.ts +37 -0
- package/lib/types/engine-pi/rpc/types.d.ts +249 -0
- package/lib/types/engine-pi/skills.d.ts +47 -0
- package/lib/types/engine-pi/types.d.ts +36 -0
- package/lib/types/engine-qoderclicn/agent.d.ts +59 -0
- package/lib/types/engine-qoderclicn/loop.d.ts +51 -0
- package/lib/types/engine-qoderclicn/process.d.ts +113 -0
- package/lib/types/engine-registry.d.ts +584 -0
- package/lib/types/engine-remote.d.ts +192 -0
- package/lib/types/engine-surface.d.ts +36 -0
- package/lib/types/engine-zcode/agent.d.ts +50 -0
- package/lib/types/engine-zcode/loop.d.ts +47 -0
- package/lib/types/engine-zcode/process.d.ts +111 -0
- package/lib/types/index.d.ts +205 -0
- package/lib/types/invariant.d.ts +26 -0
- package/lib/types/model-selection-reset.d.ts +271 -0
- package/lib/types/namespace.d.ts +25 -0
- package/lib/types/patch-manager.d.ts +104 -0
- package/lib/types/preset.d.ts +254 -0
- package/lib/types/provider-route.d.ts +245 -0
- package/lib/types/router-loop.d.ts +458 -0
- package/lib/types/session-engine-store.d.ts +138 -0
- package/lib/types/settings.d.ts +60 -0
- package/lib/types/skills.d.ts +85 -0
- package/package.json +150 -4
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One Claude Agent SDK query: options assembly, process seam projection, and
|
|
3
|
+
* the headless interaction policy. The driver runs exactly one query per dsh
|
|
4
|
+
* step; this module owns no session state.
|
|
5
|
+
*
|
|
6
|
+
* @module dsh-loop-engine-allinone/engine-claude/sdk
|
|
7
|
+
*/
|
|
8
|
+
import type { Options, PermissionMode } from '@anthropic-ai/claude-agent-sdk';
|
|
9
|
+
import type { SubprocessHandle, SubprocessSpawnSpec } from '@deepseek-ai/dsh-subprocess';
|
|
10
|
+
/** Native lock-down mode fixed for every query unless deployment overrides it. */
|
|
11
|
+
export declare const DEFAULT_PERMISSION_MODE: "dontAsk";
|
|
12
|
+
/** Grace in milliseconds for Claude Code process-tree termination. */
|
|
13
|
+
export declare const DEFAULT_DISPOSE_GRACE_MS = 3000;
|
|
14
|
+
export type { PermissionMode };
|
|
15
|
+
/** Deployment-owned process-spawn capability handed over from the plugin. */
|
|
16
|
+
export type SpawnCapability = (spec: SubprocessSpawnSpec) => SubprocessHandle;
|
|
17
|
+
/** Everything one SDK query needs, resolved at step time. */
|
|
18
|
+
export interface ClaudeCodeQuerySpec {
|
|
19
|
+
/** Absolute workspace the Claude Code process runs in. */
|
|
20
|
+
readonly cwd: string;
|
|
21
|
+
/** Native permission handling for this query. */
|
|
22
|
+
readonly permissionMode: PermissionMode;
|
|
23
|
+
/** Explicit environment entries layered over the scrubbed parent environment. */
|
|
24
|
+
readonly env?: Record<string, string>;
|
|
25
|
+
/** Grace in milliseconds for process-tree termination. */
|
|
26
|
+
readonly disposeGraceMs: number;
|
|
27
|
+
/** Model override for the SDK, when the deployment pins one. */
|
|
28
|
+
readonly model?: string;
|
|
29
|
+
/** Cap on the number of conversation turns before the query stops. */
|
|
30
|
+
readonly maxTurns?: number;
|
|
31
|
+
/**
|
|
32
|
+
* An external Claude Code executable for the SDK to launch instead of its own
|
|
33
|
+
* bundled copy (`Options.pathToClaudeCodeExecutable`).
|
|
34
|
+
*
|
|
35
|
+
* A public SDK option rather than a workaround: the SDK spawns whatever path
|
|
36
|
+
* this names, so a deployment can run an install it signed in itself — with
|
|
37
|
+
* credentials the bundled copy's own login directory would not have. Absent
|
|
38
|
+
* keeps the bundled binary, which is what every earlier release did.
|
|
39
|
+
*/
|
|
40
|
+
readonly bin?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Decide one native permission request through the dsh approval seam.
|
|
43
|
+
* When present, `canUseTool` forwards to it instead of auto-denying.
|
|
44
|
+
*/
|
|
45
|
+
readonly onToolPermission?: (toolName: string, input: Record<string, unknown>, signal: AbortSignal) => Promise<'allow' | 'deny'>;
|
|
46
|
+
/** Spawn the Claude Code child under the shared process owner. */
|
|
47
|
+
readonly spawn: SpawnCapability;
|
|
48
|
+
/** Receive a human-readable denial or decline for one unattended interaction. */
|
|
49
|
+
readonly onUnattended?: (description: string) => void;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Diagnose one auto-answered interaction in headless mode.
|
|
53
|
+
* @param mode - permission mode in force.
|
|
54
|
+
* @param kind - what the interaction was.
|
|
55
|
+
* @param answer - what the driver did.
|
|
56
|
+
* @param why - reason the driver cannot forward the interaction.
|
|
57
|
+
* @returns a stable one-line diagnostic.
|
|
58
|
+
*/
|
|
59
|
+
export declare function unattendedDiagnostic(mode: PermissionMode, kind: string, answer: string, why: string): string;
|
|
60
|
+
/**
|
|
61
|
+
* Build the fixed official SDK options for one step's query.
|
|
62
|
+
* @param spec - workspace, environment, process seam, and disposal policy.
|
|
63
|
+
* @param controller - per-query cancellation owner.
|
|
64
|
+
* @returns the options for one stateless query.
|
|
65
|
+
*/
|
|
66
|
+
export declare function claudeQueryOptions(spec: ClaudeCodeQuerySpec, controller: AbortController): Options;
|
|
67
|
+
//# sourceMappingURL=sdk.d.ts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public types of the Claude Code loop driver. Types only — no runtime code.
|
|
3
|
+
*
|
|
4
|
+
* @module dsh-loop-engine-allinone/engine-claude/types
|
|
5
|
+
*/
|
|
6
|
+
import type { PermissionMode } from '@anthropic-ai/claude-agent-sdk';
|
|
7
|
+
/** Claude Code permission modes that never wait for a human response. */
|
|
8
|
+
export type ClaudeCodePermissionMode = Extract<PermissionMode, 'dontAsk' | 'acceptEdits' | 'auto' | 'plan' | 'bypassPermissions'>;
|
|
9
|
+
/** Driver configuration after defaults and load-time validation. */
|
|
10
|
+
export interface ResolvedConfig {
|
|
11
|
+
/** Pinned native mode; `undefined` follows the session's dsh permission knobs per query. */
|
|
12
|
+
readonly permissionMode: ClaudeCodePermissionMode | undefined;
|
|
13
|
+
readonly env: Record<string, string>;
|
|
14
|
+
readonly model: string | undefined;
|
|
15
|
+
readonly disposeGraceMs: number;
|
|
16
|
+
readonly maxTurns: number | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* An EXTERNAL Claude Code executable to run instead of the SDK's own bundled
|
|
19
|
+
* one, or `undefined` to keep the bundled binary.
|
|
20
|
+
*
|
|
21
|
+
* Handed to the SDK's own `pathToClaudeCodeExecutable` option, which is a
|
|
22
|
+
* public SDK surface — the SDK then launches this binary rather than the copy
|
|
23
|
+
* it ships. The bundled copy keeps its own credential semantics, so a
|
|
24
|
+
* deployment that pins a path must have signed that install in itself.
|
|
25
|
+
*/
|
|
26
|
+
readonly bin: string | undefined;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex loop Agent: drives one session through turn and step boundaries by
|
|
3
|
+
* spawning a `codex app-server` child process and speaking JSON-RPC over stdio.
|
|
4
|
+
* Codex owns its prompt, tools, and sandbox; the durable session log remains
|
|
5
|
+
* the source of truth and the thread input is a pure projection of it — the
|
|
6
|
+
* serialized history, plus one `localImage` path item per image the step
|
|
7
|
+
* delivers (codex opens those files itself, so no bytes cross the wire).
|
|
8
|
+
* The app-server streams token-level deltas via `item/agentMessage/delta` and
|
|
9
|
+
* `item/reasoning/summaryTextDelta`, so the visible partial paints
|
|
10
|
+
* progressively as the model generates — not all at once at the end. Native
|
|
11
|
+
* approval requests (the `item/…/requestApproval` family) are server-initiated
|
|
12
|
+
* requests, not notifications: the client answers them through the dsh approval
|
|
13
|
+
* seam (`agent/requestPermission` → `ctx.approval`), while the thread still
|
|
14
|
+
* starts with a declarative `sandboxMode`/`approvalPolicy` stance.
|
|
15
|
+
*
|
|
16
|
+
* @module dsh-loop-engine-allinone/engine-codex/agent
|
|
17
|
+
*/
|
|
18
|
+
import type { Agent, AgentCancelCause, AgentOptions, AgentStatus, CancelOptions, InboxTarget } from '@deepseek-ai/dsh-agent';
|
|
19
|
+
import type { Scope } from '@deepseek-ai/dsh-scope';
|
|
20
|
+
import type { Session, SessionId, UserMessage } from '@deepseek-ai/dsh-session';
|
|
21
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
22
|
+
import type { ResolvedConfig } from './types.ts';
|
|
23
|
+
import { DriverInbox } from '../driver-core/inbox.ts';
|
|
24
|
+
/**
|
|
25
|
+
* Provider route label this driver logs into request/header snapshots and
|
|
26
|
+
* message provenance — the ONE route every hosted engine shares
|
|
27
|
+
* ({@link HOSTED_ROUTE_LABEL}), so all four engines select `external/default`
|
|
28
|
+
* and the model menu carries a single group instead of one per engine.
|
|
29
|
+
*/
|
|
30
|
+
export declare const PROVIDER = "external";
|
|
31
|
+
/** Drives one session through turn and step boundaries on Codex. */
|
|
32
|
+
export declare class CodexAgent implements Agent {
|
|
33
|
+
private loopCtx;
|
|
34
|
+
readonly id: SessionId;
|
|
35
|
+
readonly options: AgentOptions;
|
|
36
|
+
readonly session: Session;
|
|
37
|
+
private readonly config;
|
|
38
|
+
readonly inbox: DriverInbox;
|
|
39
|
+
private phase;
|
|
40
|
+
private activityDone;
|
|
41
|
+
/** The agent-scoped registration boundary; the lifecycle owner unwinds it after the driver exits. */
|
|
42
|
+
readonly scope: Scope;
|
|
43
|
+
readonly ctx: Context;
|
|
44
|
+
/** Fused dispatcher, built once in the constructor so hot-path dispatches never allocate. */
|
|
45
|
+
private readonly dispatch;
|
|
46
|
+
/** Whether this loop instance has appended its initial/resume request anchor. */
|
|
47
|
+
private requestHeaderLogged;
|
|
48
|
+
/** Agent-lifecycle-local counter naming each streamed attempt. */
|
|
49
|
+
private streamAttempts;
|
|
50
|
+
/**
|
|
51
|
+
* Tool results logged into the currently open step. A result means the
|
|
52
|
+
* segment that requested the call is finished, so the next assistant content
|
|
53
|
+
* opens the next step (see {@link beginSegment}).
|
|
54
|
+
*/
|
|
55
|
+
private stepSettledTools;
|
|
56
|
+
/**
|
|
57
|
+
* The current step's calls, and which of them already carry a result.
|
|
58
|
+
*
|
|
59
|
+
* Codex reports a call and its outcome as one item, so this pairing settles as
|
|
60
|
+
* it is written and the closing pass is normally a net — it is wired anyway,
|
|
61
|
+
* because the Session V4 rule it enforces is the step's, not the item's: a
|
|
62
|
+
* call may not be given a second result in one step, and a step may not end
|
|
63
|
+
* while a call it announced has no result at all ({@link closeStep} writes the
|
|
64
|
+
* missing outcome).
|
|
65
|
+
*
|
|
66
|
+
* Reset per step (see {@link step}), never on an internal segment rotation:
|
|
67
|
+
* call ids are unique for the life of the session, so retaining the marks only
|
|
68
|
+
* widens duplicate suppression and can never hide a legitimate result.
|
|
69
|
+
*/
|
|
70
|
+
private readonly stepTools;
|
|
71
|
+
/**
|
|
72
|
+
* Rotate to the next step when the segment that ran a tool has finished, so
|
|
73
|
+
* each assistant segment lands in its own step.
|
|
74
|
+
*
|
|
75
|
+
* Called as new assistant content begins. A step holding a settled tool
|
|
76
|
+
* result means the previous segment is complete, and the content about to be
|
|
77
|
+
* written belongs to the next one. Rotating here (rather than when a call is
|
|
78
|
+
* announced) keeps calls announced together — one model turn — in one step.
|
|
79
|
+
*
|
|
80
|
+
* A step that still OWES a result does not rotate: a call whose outcome Codex
|
|
81
|
+
* has not reported yet would be stranded in a step that can never resolve it
|
|
82
|
+
* (`step/end leaves unresolved tool call …`). Such a call runs one model turn
|
|
83
|
+
* later instead, which is what it belongs to, and a call the engine never
|
|
84
|
+
* answers is closed by {@link closeStep} rather than by moving on.
|
|
85
|
+
* @param phase - the running phase carrying the open step's position.
|
|
86
|
+
*/
|
|
87
|
+
private beginSegment;
|
|
88
|
+
/** Lazily created app-server client, reused across steps and released on scope teardown. */
|
|
89
|
+
private appServer;
|
|
90
|
+
/**
|
|
91
|
+
* The spawn configuration (`argv` + `env`) the cached client was built from.
|
|
92
|
+
* Codex's endpoint lives in the child's own command line, so a handover change
|
|
93
|
+
* must respawn the child rather than reuse one configured for another endpoint.
|
|
94
|
+
*/
|
|
95
|
+
private appServerConfig;
|
|
96
|
+
/**
|
|
97
|
+
* Countdown that shuts the child down once this agent has been idle past the
|
|
98
|
+
* configured window, so an idle session stops paying for a process nothing
|
|
99
|
+
* is driving. Armed and cancelled by {@link setPhase}.
|
|
100
|
+
*/
|
|
101
|
+
private readonly idleChild;
|
|
102
|
+
/**
|
|
103
|
+
* Resolves the read-only path behind each image block of the prompt. The
|
|
104
|
+
* attachment service is read lazily on every call, so a host that composes it
|
|
105
|
+
* after this agent still reaches the transcript.
|
|
106
|
+
*/
|
|
107
|
+
private readonly imageAccess;
|
|
108
|
+
constructor(loopCtx: Context, id: SessionId, options: AgentOptions, session: Session, config: ResolvedConfig);
|
|
109
|
+
/** Shut the cached child down; the next step's {@link appServerClient} spawns a fresh one. */
|
|
110
|
+
private closeChild;
|
|
111
|
+
/**
|
|
112
|
+
* Return the cached app-server client, spawning one on first use, after a dead
|
|
113
|
+
* process, or when the resolved dsh endpoint changed since the last spawn.
|
|
114
|
+
*
|
|
115
|
+
* A handover is codex's own `-c` configuration for a dsh provider, so a
|
|
116
|
+
* different endpoint (different provider, base URL, protocol, or credential)
|
|
117
|
+
* needs a different child — the config is fixed when the process starts.
|
|
118
|
+
* @param handover - the session's resolved dsh endpoint, or undefined to leave codex to its own configuration.
|
|
119
|
+
*/
|
|
120
|
+
private appServerClient;
|
|
121
|
+
/**
|
|
122
|
+
* Answer one server-initiated interaction. Approvals go through the dsh
|
|
123
|
+
* approval seam; a `request_user_input` question goes to the user-questions
|
|
124
|
+
* seam (both fail closed when their seam is absent), and an MCP elicitation is
|
|
125
|
+
* declined outright. Anything else is a protocol error.
|
|
126
|
+
* @param method - the server request method.
|
|
127
|
+
* @param params - the server request params.
|
|
128
|
+
* @returns the JSON-RPC outcome to send back.
|
|
129
|
+
*/
|
|
130
|
+
private answerRequest;
|
|
131
|
+
/** Resolve one native Codex approval request through the dsh approval seam. */
|
|
132
|
+
private answerApproval;
|
|
133
|
+
/**
|
|
134
|
+
* Put one `request_user_input` question to the human through the dsh
|
|
135
|
+
* user-questions seam. The seam itself fails closed (`NO_PROVIDER`) when no
|
|
136
|
+
* answerer is composed, so a refusal degrades to "no answers given" and the
|
|
137
|
+
* turn continues; asking is never silently skipped, and the degradation is
|
|
138
|
+
* logged rather than swallowed.
|
|
139
|
+
* @param params - the request params carrying the questions.
|
|
140
|
+
* @returns the response payload (or the empty answer when nobody answered).
|
|
141
|
+
*/
|
|
142
|
+
private answerUserInput;
|
|
143
|
+
/** Ask the dsh approval seam; fail closed to a denial when it is absent. */
|
|
144
|
+
private requestApproval;
|
|
145
|
+
get status(): AgentStatus;
|
|
146
|
+
/** Commit a phase and publish its externally visible status transition. */
|
|
147
|
+
private setPhase;
|
|
148
|
+
send(message: UserMessage, target: InboxTarget, wakeup: boolean): void;
|
|
149
|
+
/**
|
|
150
|
+
* Queue a message for the next turn and wake the driver.
|
|
151
|
+
* @param input - the user message to deliver.
|
|
152
|
+
*/
|
|
153
|
+
followup(input: UserMessage): void;
|
|
154
|
+
/**
|
|
155
|
+
* Queue a message for the running step and wake the driver.
|
|
156
|
+
* @param input - the user message to deliver.
|
|
157
|
+
*/
|
|
158
|
+
steer(input: UserMessage): void;
|
|
159
|
+
/**
|
|
160
|
+
* Queue a message for the running step without waking the driver.
|
|
161
|
+
* @param input - the user message to deliver.
|
|
162
|
+
*/
|
|
163
|
+
inject(input: UserMessage): void;
|
|
164
|
+
cancel(cause: AgentCancelCause, options?: CancelOptions): void;
|
|
165
|
+
/**
|
|
166
|
+
* Run a maintenance job while the agent is idle.
|
|
167
|
+
* @param job - the maintenance operation, receiving the phase abort signal.
|
|
168
|
+
* @returns the maintenance result.
|
|
169
|
+
*/
|
|
170
|
+
runMaintenance<T>(job: (signal: AbortSignal) => Promise<T>): Promise<T>;
|
|
171
|
+
/**
|
|
172
|
+
* Start one driver, or latch its wake behind maintenance or an aborted
|
|
173
|
+
* activity. A wake sent while idle always opens its turn boundary, even
|
|
174
|
+
* when its message was cleared; only a latched replay is suppressed when
|
|
175
|
+
* the queue no longer holds the wake.
|
|
176
|
+
* @param wakeAfterAbort - the {@link send} classification, captured before
|
|
177
|
+
* the inbox insertion so a reentrant cancel cannot reclassify it.
|
|
178
|
+
*/
|
|
179
|
+
private wakeDriver;
|
|
180
|
+
whenIdle(): Promise<void>;
|
|
181
|
+
/** Report one failure at its live boundary, then preserve it for driver containment. */
|
|
182
|
+
private throwError;
|
|
183
|
+
private kick;
|
|
184
|
+
private preStep;
|
|
185
|
+
/**
|
|
186
|
+
* Scan the step's user messages for `/name` skill gestures, load each
|
|
187
|
+
* matching skill, and inject the rendered skill content into the message
|
|
188
|
+
* batch. This mirrors what dsh-tool-skill does for the in-process engine.
|
|
189
|
+
* @param messages - the current step's message batch.
|
|
190
|
+
* @param signal - cancellation signal (aborted loads are silently dropped).
|
|
191
|
+
* @returns the original batch when no skill was invoked, or an extended
|
|
192
|
+
* batch with injected skill-content messages appended.
|
|
193
|
+
*/
|
|
194
|
+
private injectSkills;
|
|
195
|
+
/**
|
|
196
|
+
* Resolve the declarative permission stance for one query. Deployment-pinned
|
|
197
|
+
* fields win per field; anything unpinned follows the session's durable dsh
|
|
198
|
+
* permission knobs, re-folded per query so mid-session preset switches take
|
|
199
|
+
* effect on the next step.
|
|
200
|
+
* @returns the permission fields of the query spec.
|
|
201
|
+
*/
|
|
202
|
+
private queryPermission;
|
|
203
|
+
/** Open one turn before claiming its first proposed step. */
|
|
204
|
+
private turn;
|
|
205
|
+
/** Model label recorded in the request header for one lifecycle. */
|
|
206
|
+
private modelLabel;
|
|
207
|
+
/** Append the request header snapshot once per loop instance. */
|
|
208
|
+
private assertRequestHeader;
|
|
209
|
+
/**
|
|
210
|
+
* Run one Codex thread for the current step and map its transcript into the session log.
|
|
211
|
+
* @param messages - the messages this step delivers; each of its images rides
|
|
212
|
+
* along as a `localImage` path item, and only they.
|
|
213
|
+
*/
|
|
214
|
+
private step;
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON-RPC client over stdio for the codex app-server. Spawns
|
|
3
|
+
* `codex app-server` as a child process, sends JSON-RPC 2.0 requests over
|
|
4
|
+
* stdin, and reads newline-delimited JSON responses/notifications from stdout.
|
|
5
|
+
*
|
|
6
|
+
* @module dsh-loop-engine-allinone/engine-codex/appserver/client
|
|
7
|
+
*/
|
|
8
|
+
import type { InitializeResult, ThreadResumeParams, ThreadStartParams, ThreadStartResult, TurnInterruptParams, TurnStartParams, TurnStartResult } from './types.ts';
|
|
9
|
+
/** Callback for receiving server notifications. */
|
|
10
|
+
export type NotificationHandler = (method: string, params: unknown) => void;
|
|
11
|
+
/** A JSON-RPC reply the client writes back for one inbound server request. */
|
|
12
|
+
export type RequestOutcome = {
|
|
13
|
+
readonly result: unknown;
|
|
14
|
+
} | {
|
|
15
|
+
readonly error: {
|
|
16
|
+
readonly code: number;
|
|
17
|
+
readonly message: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
/** Callback answering one server-initiated JSON-RPC request. */
|
|
21
|
+
export type RequestHandler = (method: string, params: unknown, id: number | string) => RequestOutcome | Promise<RequestOutcome>;
|
|
22
|
+
/** Callback for receiving raw stderr lines from the server process. */
|
|
23
|
+
export type StderrHandler = (line: string) => void;
|
|
24
|
+
/** JSON-RPC client for the codex app-server. */
|
|
25
|
+
export declare class AppServerClient {
|
|
26
|
+
private process;
|
|
27
|
+
private rl;
|
|
28
|
+
private reqId;
|
|
29
|
+
private pending;
|
|
30
|
+
private notificationHandler;
|
|
31
|
+
private requestHandler;
|
|
32
|
+
private stderrHandler;
|
|
33
|
+
private disposed;
|
|
34
|
+
/** Whether this client was disposed or its server process exited. */
|
|
35
|
+
get closed(): boolean;
|
|
36
|
+
/** Create a client by spawning `codex app-server`. */
|
|
37
|
+
private constructor();
|
|
38
|
+
/**
|
|
39
|
+
* Spawn the pinned app-server dependency and initialize the client.
|
|
40
|
+
*
|
|
41
|
+
* `argv` appends the driver's own overrides to the bare `app-server`
|
|
42
|
+
* subcommand (codex's `-c key=value` configuration), and `env` layers the
|
|
43
|
+
* driver's explicit entries over the ambient environment — the child still
|
|
44
|
+
* needs `PATH` and, under a user's own codex setup, the ambient auth facts its
|
|
45
|
+
* configuration reads, so this is an overlay, not a replacement. Both default
|
|
46
|
+
* to nothing, which is the bare `codex app-server` the driver used before a
|
|
47
|
+
* dsh endpoint was ever handed over.
|
|
48
|
+
* @param argv - extra arguments after the `app-server` subcommand.
|
|
49
|
+
* @param env - explicit environment entries layered over the ambient one.
|
|
50
|
+
* @param bin - an external codex executable to launch instead of the bundled
|
|
51
|
+
* dependency; absent runs the bundled copy, byte-for-byte the old argv.
|
|
52
|
+
* @returns the initialized client.
|
|
53
|
+
*/
|
|
54
|
+
static create(argv?: readonly string[], env?: NodeJS.ProcessEnv, bin?: string): Promise<AppServerClient>;
|
|
55
|
+
/** Set the notification handler for streaming events. */
|
|
56
|
+
onNotification(handler: NotificationHandler): void;
|
|
57
|
+
/** Set the handler for server-initiated requests (e.g. approvals). */
|
|
58
|
+
onRequest(handler: RequestHandler): void;
|
|
59
|
+
/** Set the stderr handler for server log lines. */
|
|
60
|
+
onStderr(handler: StderrHandler): void;
|
|
61
|
+
/** Send the initialize handshake. */
|
|
62
|
+
initialize(): Promise<InitializeResult>;
|
|
63
|
+
/** Create a new thread. */
|
|
64
|
+
threadStart(params: ThreadStartParams): Promise<ThreadStartResult>;
|
|
65
|
+
/** Resume an existing thread. */
|
|
66
|
+
threadResume(params: ThreadResumeParams): Promise<ThreadStartResult>;
|
|
67
|
+
/** Start a turn with the given input. */
|
|
68
|
+
turnStart(params: TurnStartParams): Promise<TurnStartResult>;
|
|
69
|
+
/** Interrupt an active turn. */
|
|
70
|
+
turnInterrupt(params: TurnInterruptParams): Promise<unknown>;
|
|
71
|
+
/** Dispose the client and kill the server process. */
|
|
72
|
+
dispose(): void;
|
|
73
|
+
/** Send a JSON-RPC request and wait for the response. */
|
|
74
|
+
private request;
|
|
75
|
+
/** Handle one line of stdout from the server. */
|
|
76
|
+
private handleLine;
|
|
77
|
+
/** Resolve one inbound server request and write the JSON-RPC reply to stdin. */
|
|
78
|
+
private answerRequest;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps completed app-server items and turn usage to dsh session-log events.
|
|
3
|
+
* Only these end-state projections live here: token-level streaming deltas are
|
|
4
|
+
* folded inline by the driver's step loop; this module turns the item that
|
|
5
|
+
* finished a stream into the durable tool/call + tool/result events and folds
|
|
6
|
+
* a finished turn's usage into a TokenUsage.
|
|
7
|
+
*
|
|
8
|
+
* @module dsh-loop-engine-allinone/engine-codex/appserver/mapping
|
|
9
|
+
*/
|
|
10
|
+
import type { TokenUsage, ToolResultMessage } from '@deepseek-ai/dsh-llm';
|
|
11
|
+
import { ToolCallId } from '@deepseek-ai/dsh-llm';
|
|
12
|
+
/** Map app-server turn usage to dsh TokenUsage. */
|
|
13
|
+
export declare function mapUsage(usage: {
|
|
14
|
+
inputTokens: number;
|
|
15
|
+
outputTokens: number;
|
|
16
|
+
cachedInputTokens?: number;
|
|
17
|
+
reasoningOutputTokens?: number;
|
|
18
|
+
}): TokenUsage;
|
|
19
|
+
/** Map a completed commandExecution item to tool call and result message. */
|
|
20
|
+
export declare function mapCommandExecution(item: {
|
|
21
|
+
id: string;
|
|
22
|
+
command?: string;
|
|
23
|
+
aggregatedOutput?: string | null;
|
|
24
|
+
exitCode?: number | null;
|
|
25
|
+
status?: string;
|
|
26
|
+
}): {
|
|
27
|
+
call: {
|
|
28
|
+
callId: ToolCallId;
|
|
29
|
+
name: string;
|
|
30
|
+
arguments: string;
|
|
31
|
+
};
|
|
32
|
+
result: ToolResultMessage;
|
|
33
|
+
};
|
|
34
|
+
/** Map a completed fileChange item to tool call and result message. */
|
|
35
|
+
export declare function mapFileChange(item: {
|
|
36
|
+
id: string;
|
|
37
|
+
changes?: unknown[];
|
|
38
|
+
status?: string;
|
|
39
|
+
}): {
|
|
40
|
+
call: {
|
|
41
|
+
callId: ToolCallId;
|
|
42
|
+
name: string;
|
|
43
|
+
arguments: string;
|
|
44
|
+
};
|
|
45
|
+
result: ToolResultMessage;
|
|
46
|
+
};
|
|
47
|
+
/** Map a completed mcpToolCall item to tool call and result message. */
|
|
48
|
+
export declare function mapMcpToolCall(item: {
|
|
49
|
+
id: string;
|
|
50
|
+
server?: string;
|
|
51
|
+
tool?: string;
|
|
52
|
+
arguments?: unknown;
|
|
53
|
+
result?: {
|
|
54
|
+
content?: unknown[];
|
|
55
|
+
};
|
|
56
|
+
error?: {
|
|
57
|
+
message?: string;
|
|
58
|
+
};
|
|
59
|
+
}): {
|
|
60
|
+
call: {
|
|
61
|
+
callId: ToolCallId;
|
|
62
|
+
name: string;
|
|
63
|
+
arguments: string;
|
|
64
|
+
};
|
|
65
|
+
result: ToolResultMessage;
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=mapping.d.ts.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thread lifecycle management for the codex app-server. Wraps a codex thread
|
|
3
|
+
* and its turn-level streaming, producing dsh-native events from the
|
|
4
|
+
* app-server's JSON-RPC notifications.
|
|
5
|
+
*
|
|
6
|
+
* @module dsh-loop-engine-allinone/engine-codex/appserver/thread
|
|
7
|
+
*/
|
|
8
|
+
import type { AppServerClient } from './client.ts';
|
|
9
|
+
import type { ErrorNotification, ItemCompletedNotification, ThreadStartParams, ThreadTokenUsageUpdatedNotification, TurnCompletedNotification, TurnInput } from './types.ts';
|
|
10
|
+
/** An event yielded during a turn's streaming. */
|
|
11
|
+
export type AppServerEvent = {
|
|
12
|
+
readonly kind: 'turn-started';
|
|
13
|
+
readonly turnId: string;
|
|
14
|
+
} | {
|
|
15
|
+
readonly kind: 'item-started';
|
|
16
|
+
readonly itemType: string;
|
|
17
|
+
readonly itemId: string;
|
|
18
|
+
} | {
|
|
19
|
+
readonly kind: 'agent-delta';
|
|
20
|
+
readonly itemId: string;
|
|
21
|
+
readonly delta: string;
|
|
22
|
+
} | {
|
|
23
|
+
readonly kind: 'reasoning-summary-delta';
|
|
24
|
+
readonly itemId: string;
|
|
25
|
+
readonly delta: string;
|
|
26
|
+
readonly summaryIndex: number;
|
|
27
|
+
} | {
|
|
28
|
+
readonly kind: 'reasoning-text-delta';
|
|
29
|
+
readonly itemId: string;
|
|
30
|
+
readonly delta: string;
|
|
31
|
+
readonly contentIndex: number;
|
|
32
|
+
} | {
|
|
33
|
+
readonly kind: 'plan-delta';
|
|
34
|
+
readonly itemId: string;
|
|
35
|
+
readonly delta: string;
|
|
36
|
+
} | {
|
|
37
|
+
readonly kind: 'item-completed';
|
|
38
|
+
readonly item: ItemCompletedNotification['item'];
|
|
39
|
+
} | {
|
|
40
|
+
readonly kind: 'turn-completed';
|
|
41
|
+
readonly turn: TurnCompletedNotification['turn'];
|
|
42
|
+
} | {
|
|
43
|
+
readonly kind: 'token-usage';
|
|
44
|
+
readonly usage: ThreadTokenUsageUpdatedNotification['tokenUsage'];
|
|
45
|
+
} | {
|
|
46
|
+
readonly kind: 'error';
|
|
47
|
+
readonly error: ErrorNotification['error'];
|
|
48
|
+
readonly willRetry: boolean;
|
|
49
|
+
};
|
|
50
|
+
/** Wraps one codex thread and its streaming turns. */
|
|
51
|
+
export declare class AppServerThread {
|
|
52
|
+
private readonly client;
|
|
53
|
+
readonly threadId: string;
|
|
54
|
+
constructor(client: AppServerClient, threadId: string);
|
|
55
|
+
/** Create a new thread on the app-server. */
|
|
56
|
+
static create(client: AppServerClient, params: ThreadStartParams): Promise<AppServerThread>;
|
|
57
|
+
/**
|
|
58
|
+
* Start a turn and stream its events as an async generator.
|
|
59
|
+
* The generator ends when the turn completes or an error occurs.
|
|
60
|
+
*/
|
|
61
|
+
turn(input: readonly TurnInput[], options: {
|
|
62
|
+
signal?: AbortSignal;
|
|
63
|
+
params?: Partial<Omit<import('./types.ts').TurnStartParams, 'threadId' | 'input'>>;
|
|
64
|
+
}): AsyncGenerator<AppServerEvent, void, void>;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=thread.d.ts.map
|