@vidge/dsh-agent-hub 0.1.0-rc1
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/LICENSE +21 -0
- package/README.md +133 -0
- package/README.zh.md +115 -0
- package/cordis.patch.yml +22 -0
- package/lib/client.js +1494 -0
- package/lib/index.js +5045 -0
- package/lib/invariant.js +96 -0
- package/lib/types/client/LoopEngineComposerSelect.d.ts +73 -0
- package/lib/types/client/LoopEngineSection.d.ts +43 -0
- package/lib/types/client/engine-rpc.d.ts +74 -0
- package/lib/types/client/index.d.ts +28 -0
- package/lib/types/client/locales.d.ts +44 -0
- package/lib/types/client/session-location.d.ts +63 -0
- package/lib/types/client/store.d.ts +58 -0
- package/lib/types/commands.d.ts +69 -0
- package/lib/types/driver-core/context-files.d.ts +62 -0
- package/lib/types/driver-core/ownership.d.ts +40 -0
- package/lib/types/driver-core/permission-knobs.d.ts +26 -0
- package/lib/types/driver-core/prompt.d.ts +23 -0
- package/lib/types/driver-core/skill-inject.d.ts +59 -0
- package/lib/types/engine-claude/agent.d.ts +116 -0
- package/lib/types/engine-claude/loop.d.ts +99 -0
- package/lib/types/engine-claude/mapping.d.ts +84 -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/provider-env.d.ts +50 -0
- package/lib/types/engine-claude/sdk.d.ts +101 -0
- package/lib/types/engine-claude/types.d.ts +28 -0
- package/lib/types/engine-codex/agent.d.ts +109 -0
- package/lib/types/engine-codex/appserver/client.d.ts +49 -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 +215 -0
- package/lib/types/engine-codex/loop.d.ts +92 -0
- package/lib/types/engine-codex/permission.d.ts +32 -0
- package/lib/types/engine-codex/skills.d.ts +29 -0
- package/lib/types/engine-codex/types.d.ts +19 -0
- package/lib/types/engine-pi/agent.d.ts +125 -0
- package/lib/types/engine-pi/loop.d.ts +96 -0
- package/lib/types/engine-pi/permission.d.ts +43 -0
- package/lib/types/engine-pi/rpc/client.d.ts +105 -0
- package/lib/types/engine-pi/rpc/mapping.d.ts +37 -0
- package/lib/types/engine-pi/rpc/types.d.ts +235 -0
- package/lib/types/engine-pi/skills.d.ts +55 -0
- package/lib/types/engine-pi/types.d.ts +27 -0
- package/lib/types/engine-record.d.ts +124 -0
- package/lib/types/index.d.ts +138 -0
- package/lib/types/invariant.d.ts +23 -0
- package/lib/types/llm-compat.d.ts +32 -0
- package/lib/types/namespace.d.ts +19 -0
- package/lib/types/patch-manager.d.ts +78 -0
- package/lib/types/router.d.ts +189 -0
- package/lib/types/rpc.d.ts +113 -0
- package/lib/types/settings.d.ts +29 -0
- package/lib/types/skills.d.ts +93 -0
- package/package.json +107 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public types of the Claude Code loop driver. Types only — no runtime code.
|
|
3
|
+
*
|
|
4
|
+
* @module dsh-agent-hub/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
|
+
/**
|
|
10
|
+
* Which provider backend the CLI child is pointed at.
|
|
11
|
+
*
|
|
12
|
+
* The CLI resolves backends by precedence rather than by merging, so a host
|
|
13
|
+
* environment carrying two of them silently runs on the wrong one. `auto`
|
|
14
|
+
* picks the first configured backend in the order relay, Bedrock, Vertex,
|
|
15
|
+
* direct; the explicit values pin one and drop the others.
|
|
16
|
+
*/
|
|
17
|
+
export type ClaudeCodeBackend = 'auto' | 'relay' | 'bedrock' | 'vertex' | 'anthropic';
|
|
18
|
+
/** Driver configuration after defaults and load-time validation. */
|
|
19
|
+
export interface ResolvedConfig {
|
|
20
|
+
/** Pinned native mode; `undefined` follows the session's dsh permission knobs per query. */
|
|
21
|
+
readonly permissionMode: ClaudeCodePermissionMode | undefined;
|
|
22
|
+
readonly env: Record<string, string>;
|
|
23
|
+
readonly model: string | undefined;
|
|
24
|
+
readonly backend: ClaudeCodeBackend;
|
|
25
|
+
readonly disposeGraceMs: number;
|
|
26
|
+
readonly maxTurns: number | undefined;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,109 @@
|
|
|
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 serialization of it.
|
|
6
|
+
* The app-server streams token-level deltas via `item/agentMessage/delta` and
|
|
7
|
+
* `item/reasoning/summaryTextDelta`, so the visible partial paints
|
|
8
|
+
* progressively as the model generates — not all at once at the end. It offers
|
|
9
|
+
* no interactive approval callback, so permissions are folded declaratively
|
|
10
|
+
* into each thread's `sandboxMode`/`approvalPolicy`.
|
|
11
|
+
*
|
|
12
|
+
* @module dsh-agent-hub/engine-codex/agent
|
|
13
|
+
*/
|
|
14
|
+
import type { Agent, AgentCancelCause, AgentOptions, AgentStatus, CancelOptions, InboxTarget } from '@deepseek-ai/dsh-agent';
|
|
15
|
+
import { Inbox } from '@deepseek-ai/dsh-agent';
|
|
16
|
+
import type { Scope } from '@deepseek-ai/dsh-scope';
|
|
17
|
+
import type { Session, SessionId, UserMessage } from '@deepseek-ai/dsh-session';
|
|
18
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
19
|
+
import type { ResolvedConfig } from './types.ts';
|
|
20
|
+
/** Drives one session through turn and step boundaries on Codex. */
|
|
21
|
+
export declare class CodexAgent implements Agent {
|
|
22
|
+
private loopCtx;
|
|
23
|
+
readonly id: SessionId;
|
|
24
|
+
readonly options: AgentOptions;
|
|
25
|
+
readonly session: Session;
|
|
26
|
+
private readonly config;
|
|
27
|
+
readonly inbox: Inbox;
|
|
28
|
+
private phase;
|
|
29
|
+
private activityDone;
|
|
30
|
+
/** The agent-scoped registration boundary; the lifecycle owner unwinds it after the driver exits. */
|
|
31
|
+
readonly scope: Scope;
|
|
32
|
+
readonly ctx: Context;
|
|
33
|
+
/** Fused dispatcher, built once in the constructor so hot-path dispatches never allocate. */
|
|
34
|
+
private readonly dispatch;
|
|
35
|
+
/** Whether this loop instance has appended its initial/resume request anchor. */
|
|
36
|
+
private requestHeaderLogged;
|
|
37
|
+
/** Lazily created app-server client, reused across steps and released on scope teardown. */
|
|
38
|
+
private appServer;
|
|
39
|
+
constructor(loopCtx: Context, id: SessionId, options: AgentOptions, session: Session, config: ResolvedConfig);
|
|
40
|
+
/** Return the cached app-server client, spawning one on first use or after a dead process. */
|
|
41
|
+
private appServerClient;
|
|
42
|
+
get status(): AgentStatus;
|
|
43
|
+
/** Commit a phase and publish its externally visible status transition. */
|
|
44
|
+
private setPhase;
|
|
45
|
+
send(message: UserMessage, target: InboxTarget, wakeup: boolean): void;
|
|
46
|
+
/**
|
|
47
|
+
* Queue a message for the next turn and wake the driver.
|
|
48
|
+
* @param input - the user message to deliver.
|
|
49
|
+
*/
|
|
50
|
+
followup(input: UserMessage): void;
|
|
51
|
+
/**
|
|
52
|
+
* Queue a message for the running step and wake the driver.
|
|
53
|
+
* @param input - the user message to deliver.
|
|
54
|
+
*/
|
|
55
|
+
steer(input: UserMessage): void;
|
|
56
|
+
/**
|
|
57
|
+
* Queue a message for the running step without waking the driver.
|
|
58
|
+
* @param input - the user message to deliver.
|
|
59
|
+
*/
|
|
60
|
+
inject(input: UserMessage): void;
|
|
61
|
+
cancel(cause: AgentCancelCause, options?: CancelOptions): void;
|
|
62
|
+
/**
|
|
63
|
+
* Run a maintenance job while the agent is idle.
|
|
64
|
+
* @param job - the maintenance operation, receiving the phase abort signal.
|
|
65
|
+
* @returns the maintenance result.
|
|
66
|
+
*/
|
|
67
|
+
runMaintenance<T>(job: (signal: AbortSignal) => Promise<T>): Promise<T>;
|
|
68
|
+
/**
|
|
69
|
+
* Start one driver, or latch its wake behind maintenance or an aborted
|
|
70
|
+
* activity. A wake sent while idle always opens its turn boundary, even
|
|
71
|
+
* when its message was cleared; only a latched replay is suppressed when
|
|
72
|
+
* the queue no longer holds the wake.
|
|
73
|
+
* @param wakeAfterAbort - the {@link send} classification, captured before
|
|
74
|
+
* the inbox insertion so a reentrant cancel cannot reclassify it.
|
|
75
|
+
*/
|
|
76
|
+
private wakeDriver;
|
|
77
|
+
whenIdle(): Promise<void>;
|
|
78
|
+
/** Report one failure at its live boundary, then preserve it for driver containment. */
|
|
79
|
+
private throwError;
|
|
80
|
+
private kick;
|
|
81
|
+
private preStep;
|
|
82
|
+
/**
|
|
83
|
+
* Scan the step's user messages for `/name` skill gestures, load each
|
|
84
|
+
* matching skill, and inject the rendered skill content into the message
|
|
85
|
+
* batch. This mirrors what dsh-tool-skill does for the in-process engine.
|
|
86
|
+
* @param messages - the current step's message batch.
|
|
87
|
+
* @param signal - cancellation signal (aborted loads are silently dropped).
|
|
88
|
+
* @returns the original batch when no skill was invoked, or an extended
|
|
89
|
+
* batch with injected skill-content messages appended.
|
|
90
|
+
*/
|
|
91
|
+
private injectSkills;
|
|
92
|
+
/**
|
|
93
|
+
* Resolve the declarative permission stance for one query. Deployment-pinned
|
|
94
|
+
* fields win per field; anything unpinned follows the session's durable dsh
|
|
95
|
+
* permission knobs, re-folded per query so mid-session preset switches take
|
|
96
|
+
* effect on the next step.
|
|
97
|
+
* @returns the permission fields of the query spec.
|
|
98
|
+
*/
|
|
99
|
+
private queryPermission;
|
|
100
|
+
/** Open one turn before claiming its first proposed step. */
|
|
101
|
+
private turn;
|
|
102
|
+
/** Model label recorded in the request header for one lifecycle. */
|
|
103
|
+
private modelLabel;
|
|
104
|
+
/** Append the request header snapshot once per loop instance. */
|
|
105
|
+
private assertRequestHeader;
|
|
106
|
+
/** Run one Codex thread for the current step and map its transcript into the session log. */
|
|
107
|
+
private step;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1,49 @@
|
|
|
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-agent-hub/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
|
+
/** Callback for receiving raw stderr lines from the server process. */
|
|
12
|
+
export type StderrHandler = (line: string) => void;
|
|
13
|
+
/** JSON-RPC client for the codex app-server. */
|
|
14
|
+
export declare class AppServerClient {
|
|
15
|
+
private process;
|
|
16
|
+
private rl;
|
|
17
|
+
private reqId;
|
|
18
|
+
private pending;
|
|
19
|
+
private notificationHandler;
|
|
20
|
+
private stderrHandler;
|
|
21
|
+
private disposed;
|
|
22
|
+
/** Whether this client was disposed or its server process exited. */
|
|
23
|
+
get closed(): boolean;
|
|
24
|
+
/** Create a client by spawning `codex app-server`. */
|
|
25
|
+
private constructor();
|
|
26
|
+
/** Spawn the pinned app-server dependency and initialize the client. */
|
|
27
|
+
static create(): Promise<AppServerClient>;
|
|
28
|
+
/** Set the notification handler for streaming events. */
|
|
29
|
+
onNotification(handler: NotificationHandler): void;
|
|
30
|
+
/** Set the stderr handler for server log lines. */
|
|
31
|
+
onStderr(handler: StderrHandler): void;
|
|
32
|
+
/** Send the initialize handshake. */
|
|
33
|
+
initialize(): Promise<InitializeResult>;
|
|
34
|
+
/** Create a new thread. */
|
|
35
|
+
threadStart(params: ThreadStartParams): Promise<ThreadStartResult>;
|
|
36
|
+
/** Resume an existing thread. */
|
|
37
|
+
threadResume(params: ThreadResumeParams): Promise<ThreadStartResult>;
|
|
38
|
+
/** Start a turn with the given input. */
|
|
39
|
+
turnStart(params: TurnStartParams): Promise<TurnStartResult>;
|
|
40
|
+
/** Interrupt an active turn. */
|
|
41
|
+
turnInterrupt(params: TurnInterruptParams): Promise<unknown>;
|
|
42
|
+
/** Dispose the client and kill the server process. */
|
|
43
|
+
dispose(): void;
|
|
44
|
+
/** Send a JSON-RPC request and wait for the response. */
|
|
45
|
+
private request;
|
|
46
|
+
/** Handle one line of stdout from the server. */
|
|
47
|
+
private handleLine;
|
|
48
|
+
}
|
|
49
|
+
//# 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-agent-hub/engine-codex/appserver/mapping
|
|
9
|
+
*/
|
|
10
|
+
import type { TokenUsage, ToolResultMessage } from '@deepseek-ai/dsh-llm';
|
|
11
|
+
import { CallId } from '../../llm-compat.ts';
|
|
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: CallId;
|
|
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: CallId;
|
|
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: CallId;
|
|
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-agent-hub/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
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App-server protocol type definitions. A minimal subset of the types generated
|
|
3
|
+
* by `codex app-server generate-ts`, covering only what the driver needs for
|
|
4
|
+
* streaming (initialize, thread/start, turn/start, notifications).
|
|
5
|
+
*
|
|
6
|
+
* @module dsh-agent-hub/engine-codex/appserver/types
|
|
7
|
+
*/
|
|
8
|
+
/** A JSON-RPC 2.0 request sent to the app-server. */
|
|
9
|
+
export interface JsonRpcRequest {
|
|
10
|
+
readonly jsonrpc: '2.0';
|
|
11
|
+
readonly id: number;
|
|
12
|
+
readonly method: string;
|
|
13
|
+
readonly params?: unknown;
|
|
14
|
+
}
|
|
15
|
+
/** A JSON-RPC 2.0 response (success or error). */
|
|
16
|
+
export interface JsonRpcResponse {
|
|
17
|
+
readonly id: number;
|
|
18
|
+
readonly result?: unknown;
|
|
19
|
+
readonly error?: {
|
|
20
|
+
readonly code: number;
|
|
21
|
+
readonly message: string;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** A JSON-RPC 2.0 notification (no id). */
|
|
25
|
+
export interface JsonRpcNotification {
|
|
26
|
+
readonly method: string;
|
|
27
|
+
readonly params: unknown;
|
|
28
|
+
}
|
|
29
|
+
export interface InitializeParams {
|
|
30
|
+
readonly clientInfo: {
|
|
31
|
+
readonly name: string;
|
|
32
|
+
readonly title: string | null;
|
|
33
|
+
readonly version: string;
|
|
34
|
+
};
|
|
35
|
+
readonly capabilities: {
|
|
36
|
+
readonly experimentalApi: boolean;
|
|
37
|
+
readonly requestAttestation: boolean;
|
|
38
|
+
} | null;
|
|
39
|
+
}
|
|
40
|
+
export interface InitializeResult {
|
|
41
|
+
readonly userAgent: string;
|
|
42
|
+
readonly codexHome: string;
|
|
43
|
+
readonly platformFamily: string;
|
|
44
|
+
readonly platformOs: string;
|
|
45
|
+
}
|
|
46
|
+
/** Sandbox mode accepted by `thread/start`; unlike turn policies, this is a string enum. */
|
|
47
|
+
export type SandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access';
|
|
48
|
+
/** Internally tagged sandbox override accepted by `turn/start`. */
|
|
49
|
+
export type SandboxPolicy = {
|
|
50
|
+
readonly type: 'dangerFullAccess';
|
|
51
|
+
} | {
|
|
52
|
+
readonly type: 'readOnly';
|
|
53
|
+
readonly networkAccess: boolean;
|
|
54
|
+
} | {
|
|
55
|
+
readonly type: 'externalSandbox';
|
|
56
|
+
readonly networkAccess: 'restricted' | 'enabled';
|
|
57
|
+
} | {
|
|
58
|
+
readonly type: 'workspaceWrite';
|
|
59
|
+
readonly writableRoots: readonly string[];
|
|
60
|
+
readonly networkAccess: boolean;
|
|
61
|
+
readonly excludeTmpdirEnvVar: boolean;
|
|
62
|
+
readonly excludeSlashTmp: boolean;
|
|
63
|
+
};
|
|
64
|
+
export interface ThreadStartParams {
|
|
65
|
+
readonly model?: string | null;
|
|
66
|
+
readonly modelProvider?: string | null;
|
|
67
|
+
readonly cwd?: string | null;
|
|
68
|
+
readonly approvalPolicy?: string | null;
|
|
69
|
+
readonly sandbox?: SandboxMode | null;
|
|
70
|
+
readonly ephemeral?: boolean | null;
|
|
71
|
+
readonly [key: string]: unknown;
|
|
72
|
+
}
|
|
73
|
+
export interface ThreadInfo {
|
|
74
|
+
readonly id: string;
|
|
75
|
+
readonly sessionId: string;
|
|
76
|
+
readonly modelProvider: string;
|
|
77
|
+
readonly [key: string]: unknown;
|
|
78
|
+
}
|
|
79
|
+
export interface ThreadStartResult {
|
|
80
|
+
readonly thread: ThreadInfo;
|
|
81
|
+
}
|
|
82
|
+
export interface ThreadResumeParams {
|
|
83
|
+
readonly threadId: string;
|
|
84
|
+
readonly cwd?: string | null;
|
|
85
|
+
readonly approvalPolicy?: string | null;
|
|
86
|
+
readonly sandbox?: string | null;
|
|
87
|
+
readonly [key: string]: unknown;
|
|
88
|
+
}
|
|
89
|
+
export interface TurnStartParams {
|
|
90
|
+
readonly threadId: string;
|
|
91
|
+
readonly input: readonly TurnInput[];
|
|
92
|
+
readonly cwd?: string | null;
|
|
93
|
+
readonly approvalPolicy?: string | null;
|
|
94
|
+
readonly sandboxPolicy?: SandboxPolicy | null;
|
|
95
|
+
readonly model?: string | null;
|
|
96
|
+
readonly [key: string]: unknown;
|
|
97
|
+
}
|
|
98
|
+
export interface TurnInput {
|
|
99
|
+
readonly type: 'text';
|
|
100
|
+
readonly text: string;
|
|
101
|
+
}
|
|
102
|
+
export interface TurnInfo {
|
|
103
|
+
readonly id: string;
|
|
104
|
+
readonly status: string;
|
|
105
|
+
readonly error: {
|
|
106
|
+
readonly message: string;
|
|
107
|
+
} | null;
|
|
108
|
+
readonly items: readonly unknown[];
|
|
109
|
+
readonly [key: string]: unknown;
|
|
110
|
+
}
|
|
111
|
+
export interface TurnStartResult {
|
|
112
|
+
readonly turn: TurnInfo;
|
|
113
|
+
}
|
|
114
|
+
export interface TurnInterruptParams {
|
|
115
|
+
readonly threadId: string;
|
|
116
|
+
readonly turnId: string;
|
|
117
|
+
}
|
|
118
|
+
/** item/agentMessage/delta — agent message token delta. */
|
|
119
|
+
export interface AgentMessageDeltaNotification {
|
|
120
|
+
readonly threadId: string;
|
|
121
|
+
readonly turnId: string;
|
|
122
|
+
readonly itemId: string;
|
|
123
|
+
readonly delta: string;
|
|
124
|
+
}
|
|
125
|
+
/** item/reasoning/summaryTextDelta — reasoning summary token delta. */
|
|
126
|
+
export interface ReasoningSummaryTextDeltaNotification {
|
|
127
|
+
readonly threadId: string;
|
|
128
|
+
readonly turnId: string;
|
|
129
|
+
readonly itemId: string;
|
|
130
|
+
readonly delta: string;
|
|
131
|
+
readonly summaryIndex: number;
|
|
132
|
+
}
|
|
133
|
+
/** item/reasoning/textDelta — reasoning content token delta. */
|
|
134
|
+
export interface ReasoningTextDeltaNotification {
|
|
135
|
+
readonly threadId: string;
|
|
136
|
+
readonly turnId: string;
|
|
137
|
+
readonly itemId: string;
|
|
138
|
+
readonly delta: string;
|
|
139
|
+
readonly contentIndex: number;
|
|
140
|
+
}
|
|
141
|
+
/** item/plan/delta — plan delta. */
|
|
142
|
+
export interface PlanDeltaNotification {
|
|
143
|
+
readonly threadId: string;
|
|
144
|
+
readonly turnId: string;
|
|
145
|
+
readonly itemId: string;
|
|
146
|
+
readonly delta: string;
|
|
147
|
+
}
|
|
148
|
+
/** item/started — item lifecycle start. */
|
|
149
|
+
export interface ItemStartedNotification {
|
|
150
|
+
readonly threadId: string;
|
|
151
|
+
readonly turnId: string;
|
|
152
|
+
readonly item: {
|
|
153
|
+
readonly type: string;
|
|
154
|
+
readonly id: string;
|
|
155
|
+
readonly [key: string]: unknown;
|
|
156
|
+
};
|
|
157
|
+
readonly startedAtMs: number;
|
|
158
|
+
}
|
|
159
|
+
/** item/completed — item lifecycle end. */
|
|
160
|
+
export interface ItemCompletedNotification {
|
|
161
|
+
readonly threadId: string;
|
|
162
|
+
readonly turnId: string;
|
|
163
|
+
readonly item: {
|
|
164
|
+
readonly type: string;
|
|
165
|
+
readonly id: string;
|
|
166
|
+
readonly text?: string;
|
|
167
|
+
readonly [key: string]: unknown;
|
|
168
|
+
};
|
|
169
|
+
readonly completedAtMs: number;
|
|
170
|
+
}
|
|
171
|
+
/** turn/completed — turn end with usage. */
|
|
172
|
+
export interface TurnCompletedNotification {
|
|
173
|
+
readonly threadId: string;
|
|
174
|
+
readonly turn: TurnInfo & {
|
|
175
|
+
readonly usage?: {
|
|
176
|
+
readonly inputTokens: number;
|
|
177
|
+
readonly cachedInputTokens?: number;
|
|
178
|
+
readonly outputTokens: number;
|
|
179
|
+
readonly reasoningOutputTokens?: number;
|
|
180
|
+
};
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/** thread/tokenUsage/updated — token usage update. */
|
|
184
|
+
export interface ThreadTokenUsageUpdatedNotification {
|
|
185
|
+
readonly threadId: string;
|
|
186
|
+
readonly turnId: string;
|
|
187
|
+
readonly tokenUsage: {
|
|
188
|
+
readonly total: {
|
|
189
|
+
readonly totalTokens: number;
|
|
190
|
+
readonly inputTokens: number;
|
|
191
|
+
readonly cachedInputTokens: number;
|
|
192
|
+
readonly outputTokens: number;
|
|
193
|
+
readonly reasoningOutputTokens: number;
|
|
194
|
+
};
|
|
195
|
+
readonly last: {
|
|
196
|
+
readonly totalTokens: number;
|
|
197
|
+
readonly inputTokens: number;
|
|
198
|
+
readonly cachedInputTokens: number;
|
|
199
|
+
readonly outputTokens: number;
|
|
200
|
+
readonly reasoningOutputTokens: number;
|
|
201
|
+
};
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
/** error notification. */
|
|
205
|
+
export interface ErrorNotification {
|
|
206
|
+
readonly threadId: string;
|
|
207
|
+
readonly turnId: string;
|
|
208
|
+
readonly error: {
|
|
209
|
+
readonly message: string;
|
|
210
|
+
readonly codexErrorInfo?: string | null;
|
|
211
|
+
readonly additionalDetails?: string | null;
|
|
212
|
+
};
|
|
213
|
+
readonly willRetry: boolean;
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex loop engine module: hosts the AgentFactory that drives every session
|
|
3
|
+
* through the OpenAI Codex SDK, one stateless thread per dsh step, with the
|
|
4
|
+
* durable session log as the sole source of model context. dsh-agent-hub
|
|
5
|
+
* constructs this factory when the Codex engine is selected; this module is a
|
|
6
|
+
* library, not a Cordis plugin entry. The Codex SDK spawns its own CLI binary
|
|
7
|
+
* (no spawn injection seam), so this loop deliberately does not inject the dsh
|
|
8
|
+
* subprocess service.
|
|
9
|
+
*
|
|
10
|
+
* @module dsh-agent-hub/engine-codex
|
|
11
|
+
*/
|
|
12
|
+
import { Service } from '@deepseek-ai/cordis';
|
|
13
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
14
|
+
import z from '@deepseek-ai/schemastery';
|
|
15
|
+
import type { AgentFactory, AgentHandle, CreateAgentOptions, ResumeAgentOptions } from '@deepseek-ai/dsh-agent';
|
|
16
|
+
import type { CodexApprovalPolicy, CodexSandboxMode, ResolvedConfig } from './types.ts';
|
|
17
|
+
/** Codex CLI sandbox modes a deployment may pin. */
|
|
18
|
+
export declare const CODEX_SANDBOX_MODES: readonly CodexSandboxMode[];
|
|
19
|
+
/** Codex CLI approval policies a deployment may pin. */
|
|
20
|
+
export declare const CODEX_APPROVAL_POLICIES: readonly CodexApprovalPolicy[];
|
|
21
|
+
/** Deployment-owned configuration for the Codex loop plugin. */
|
|
22
|
+
export interface Config {
|
|
23
|
+
/**
|
|
24
|
+
* Pinned sandbox mode for every thread. When omitted, each query follows the
|
|
25
|
+
* session's dsh permission knobs (`sandbox/mode` and `approval/policy`):
|
|
26
|
+
* full access maps to `danger-full-access`, an `ask` policy maps to
|
|
27
|
+
* `workspace-write`, and anything else fails closed with `read-only`.
|
|
28
|
+
*/
|
|
29
|
+
sandboxMode?: CodexSandboxMode;
|
|
30
|
+
/**
|
|
31
|
+
* Pinned approval policy for every thread. When omitted, each query follows
|
|
32
|
+
* the session's dsh permission knobs: an `ask` policy maps to `on-request`
|
|
33
|
+
* (the CLI's own interactive prompt degrades to a denial in the unattended
|
|
34
|
+
* dsh runtime) and anything else maps to `never`.
|
|
35
|
+
*/
|
|
36
|
+
approvalPolicy?: CodexApprovalPolicy;
|
|
37
|
+
/** Explicit environment entries layered over the credential-scrubbed parent environment. */
|
|
38
|
+
env?: Record<string, string>;
|
|
39
|
+
/** Model override for the SDK; Codex native settings own the model when omitted. */
|
|
40
|
+
model?: string;
|
|
41
|
+
}
|
|
42
|
+
/** Schema of the Codex loop plugin configuration. */
|
|
43
|
+
export declare const Config: z<Config>;
|
|
44
|
+
/** Host-face ctx key for the Codex loop service. */
|
|
45
|
+
declare module '@deepseek-ai/cordis' {
|
|
46
|
+
interface Context {
|
|
47
|
+
agentLoopCodex: CodexLoop;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Concrete AgentFactory and driver service of the Codex loop. Creation and
|
|
52
|
+
* resume follow the registry factory contract and the shared publication
|
|
53
|
+
* transaction: prepare, run setup, then publish through both registries,
|
|
54
|
+
* announce, and emit `agent/session-start`.
|
|
55
|
+
*/
|
|
56
|
+
export declare class CodexLoop extends Service implements AgentFactory {
|
|
57
|
+
/** Services the loop resolves through its own fiber; blessed identically to the package-level entry inject. */
|
|
58
|
+
static inject: string[];
|
|
59
|
+
/** Validated configuration owned by the loop plugin. */
|
|
60
|
+
readonly config: ResolvedConfig;
|
|
61
|
+
private readonly ownership;
|
|
62
|
+
/** Plain holder prevents Cordis from re-tracing the factory's dependency context through a caller shadow. */
|
|
63
|
+
private readonly runtime;
|
|
64
|
+
constructor(ctx: Context, config: Config);
|
|
65
|
+
/**
|
|
66
|
+
* Construct the driver, scope, and one memoized reverse teardown for a new
|
|
67
|
+
* agent. The teardown is registered with the factory and the owner fiber
|
|
68
|
+
* BEFORE publication, so a mid-setup unload rolls everything back; `signal`
|
|
69
|
+
* fuses caller cancellation with lifecycle teardown for setup awaits.
|
|
70
|
+
*/
|
|
71
|
+
private prepare;
|
|
72
|
+
/** Prepare one Agent around an acquired Session, run setup, and publish it. */
|
|
73
|
+
private setupAndPublish;
|
|
74
|
+
/**
|
|
75
|
+
* Create an agent and session under one caller-supplied identity, owned by
|
|
76
|
+
* the accessing fiber.
|
|
77
|
+
* @param ownerCtx - caller context that structurally owns the lifecycle.
|
|
78
|
+
* @param options - identities, session seed/metadata, loop options, setup, and cancellation.
|
|
79
|
+
* @returns the published handle.
|
|
80
|
+
*/
|
|
81
|
+
createAgent(ownerCtx: Context, options: CreateAgentOptions): Promise<AgentHandle>;
|
|
82
|
+
/**
|
|
83
|
+
* Resume an owned agent from the configured persistence service.
|
|
84
|
+
* @param ownerCtx - caller context that owns load, setup, and the live lifecycle.
|
|
85
|
+
* @param options - persisted identity, loop options, setup, and cancellation.
|
|
86
|
+
* @returns the published handle.
|
|
87
|
+
*/
|
|
88
|
+
resume(ownerCtx: Context, options: ResumeAgentOptions): Promise<AgentHandle>;
|
|
89
|
+
/** Resume through an explicit persistence handle. */
|
|
90
|
+
private resumeWith;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=loop.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mapping from the dsh session's durable permission knobs to one Codex query's
|
|
3
|
+
* declarative permission stance. Codex has no interactive approval callback:
|
|
4
|
+
* permissions are the `sandboxMode` + `approvalPolicy` pair chosen when the
|
|
5
|
+
* thread starts, so the fold maps the session's `sandbox/mode` and
|
|
6
|
+
* `approval/policy` events directly, mirroring the web surface's presets:
|
|
7
|
+
* - full access → `danger-full-access` + `never` (no native checks at all),
|
|
8
|
+
* - an `ask` policy → `workspace-write` + `on-request` (the CLI's own
|
|
9
|
+
* interactive prompt degrades to a denial in the unattended dsh runtime),
|
|
10
|
+
* - anything else fails closed → `read-only` + `never`.
|
|
11
|
+
*
|
|
12
|
+
* @module dsh-agent-hub/engine-codex/permission
|
|
13
|
+
*/
|
|
14
|
+
import type { PermissionEvent } from '../driver-core/permission-knobs.ts';
|
|
15
|
+
import type { CodexApprovalPolicy, CodexSandboxMode } from './types.ts';
|
|
16
|
+
/** The declarative permission stance one Codex thread runs under. */
|
|
17
|
+
export interface CodexPermission {
|
|
18
|
+
readonly sandboxMode: CodexSandboxMode;
|
|
19
|
+
readonly approvalPolicy: CodexApprovalPolicy;
|
|
20
|
+
}
|
|
21
|
+
/** Conservative unattended default: read-only sandbox, never ask. */
|
|
22
|
+
export declare const DEFAULT_CODEX_PERMISSION: CodexPermission;
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the session's effective Codex permission stance. Full access wins
|
|
25
|
+
* outright; otherwise an `ask` policy maps to the CLI's on-request approval
|
|
26
|
+
* inside a workspace-write sandbox; anything else — including a session with
|
|
27
|
+
* no recorded knobs — fails closed.
|
|
28
|
+
* @param events - the durable session log.
|
|
29
|
+
* @returns the stance one query should run under.
|
|
30
|
+
*/
|
|
31
|
+
export declare function resolveSessionPermission(events: readonly PermissionEvent[]): CodexPermission;
|
|
32
|
+
//# sourceMappingURL=permission.d.ts.map
|