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.
Files changed (143) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/CONTRIBUTING.md +78 -0
  3. package/LICENSE +23 -0
  4. package/NOTICE +45 -0
  5. package/README.md +221 -2
  6. package/README.zh.md +89 -0
  7. package/SECURITY.md +39 -0
  8. package/cordis.patch.yml +3 -0
  9. package/lib/client.js +2166 -0
  10. package/lib/index.js +11621 -0
  11. package/lib/invariant.js +453 -0
  12. package/lib/types/agent-preset-ids.d.ts +276 -0
  13. package/lib/types/client/LoopEngineBadge.d.ts +71 -0
  14. package/lib/types/client/LoopEngineComposerSelect.d.ts +126 -0
  15. package/lib/types/client/LoopEngineSection.d.ts +35 -0
  16. package/lib/types/client/engine-marks.d.ts +87 -0
  17. package/lib/types/client/index.d.ts +39 -0
  18. package/lib/types/client/locales.d.ts +182 -0
  19. package/lib/types/client/reload.d.ts +135 -0
  20. package/lib/types/client/session-engine.d.ts +508 -0
  21. package/lib/types/client/store.d.ts +103 -0
  22. package/lib/types/client/turn-status.d.ts +234 -0
  23. package/lib/types/client/use-session-engine.d.ts +74 -0
  24. package/lib/types/commands.d.ts +77 -0
  25. package/lib/types/compat.d.ts +25 -0
  26. package/lib/types/driver-acp/agent.d.ts +289 -0
  27. package/lib/types/driver-acp/approval.d.ts +27 -0
  28. package/lib/types/driver-acp/capabilities.d.ts +200 -0
  29. package/lib/types/driver-acp/client.d.ts +297 -0
  30. package/lib/types/driver-acp/executable.d.ts +53 -0
  31. package/lib/types/driver-acp/mapping.d.ts +76 -0
  32. package/lib/types/driver-acp/profile.d.ts +126 -0
  33. package/lib/types/driver-acp/runtime.d.ts +45 -0
  34. package/lib/types/driver-acp/subprocess.d.ts +19 -0
  35. package/lib/types/driver-acp/terminal.d.ts +98 -0
  36. package/lib/types/driver-acp/transport.d.ts +43 -0
  37. package/lib/types/driver-acp/types.d.ts +152 -0
  38. package/lib/types/driver-cli/capability.d.ts +42 -0
  39. package/lib/types/driver-cli/cli-agent.d.ts +258 -0
  40. package/lib/types/driver-cli/cli-loop.d.ts +46 -0
  41. package/lib/types/driver-cli/flatten.d.ts +35 -0
  42. package/lib/types/driver-cli/frames.d.ts +128 -0
  43. package/lib/types/driver-cli/ndjson.d.ts +106 -0
  44. package/lib/types/driver-cli/session-sink.d.ts +333 -0
  45. package/lib/types/driver-cli/stream-json.d.ts +61 -0
  46. package/lib/types/driver-cli/text.d.ts +66 -0
  47. package/lib/types/driver-cli/transport.d.ts +84 -0
  48. package/lib/types/driver-core/agents-md-skill-provider.d.ts +72 -0
  49. package/lib/types/driver-core/assistant-stream.d.ts +68 -0
  50. package/lib/types/driver-core/context-files.d.ts +62 -0
  51. package/lib/types/driver-core/host-servers.d.ts +119 -0
  52. package/lib/types/driver-core/hosted-engine-runtime.d.ts +190 -0
  53. package/lib/types/driver-core/hosted-tool-vocabulary.d.ts +78 -0
  54. package/lib/types/driver-core/idle-child.d.ts +57 -0
  55. package/lib/types/driver-core/image-access.d.ts +25 -0
  56. package/lib/types/driver-core/inbox.d.ts +104 -0
  57. package/lib/types/driver-core/model-handover.d.ts +134 -0
  58. package/lib/types/driver-core/ownership.d.ts +41 -0
  59. package/lib/types/driver-core/permission-knobs.d.ts +26 -0
  60. package/lib/types/driver-core/prompt.d.ts +64 -0
  61. package/lib/types/driver-core/session-lifetime.d.ts +62 -0
  62. package/lib/types/driver-core/session-model.d.ts +128 -0
  63. package/lib/types/driver-core/skill-inject.d.ts +59 -0
  64. package/lib/types/driver-core/step-close.d.ts +49 -0
  65. package/lib/types/driver-core/step-images.d.ts +62 -0
  66. package/lib/types/driver-core/step-tools.d.ts +43 -0
  67. package/lib/types/driver-core/system-head.d.ts +43 -0
  68. package/lib/types/engine-agy/agent.d.ts +67 -0
  69. package/lib/types/engine-agy/frames.d.ts +90 -0
  70. package/lib/types/engine-agy/loop.d.ts +64 -0
  71. package/lib/types/engine-agy/process.d.ts +173 -0
  72. package/lib/types/engine-claude/agent.d.ts +186 -0
  73. package/lib/types/engine-claude/loop.d.ts +73 -0
  74. package/lib/types/engine-claude/mapping.d.ts +108 -0
  75. package/lib/types/engine-claude/permission.d.ts +41 -0
  76. package/lib/types/engine-claude/process.d.ts +59 -0
  77. package/lib/types/engine-claude/sdk.d.ts +67 -0
  78. package/lib/types/engine-claude/types.d.ts +28 -0
  79. package/lib/types/engine-codex/agent.d.ts +216 -0
  80. package/lib/types/engine-codex/appserver/client.d.ts +80 -0
  81. package/lib/types/engine-codex/appserver/mapping.d.ts +67 -0
  82. package/lib/types/engine-codex/appserver/thread.d.ts +66 -0
  83. package/lib/types/engine-codex/appserver/types.d.ts +225 -0
  84. package/lib/types/engine-codex/loop.d.ts +75 -0
  85. package/lib/types/engine-codex/model-handover.d.ts +56 -0
  86. package/lib/types/engine-codex/permission.d.ts +126 -0
  87. package/lib/types/engine-codex/skills.d.ts +28 -0
  88. package/lib/types/engine-codex/types.d.ts +36 -0
  89. package/lib/types/engine-drivers.d.ts +132 -0
  90. package/lib/types/engine-grok/agent.d.ts +24 -0
  91. package/lib/types/engine-grok/loop.d.ts +61 -0
  92. package/lib/types/engine-grok/process.d.ts +46 -0
  93. package/lib/types/engine-grok/profile.d.ts +82 -0
  94. package/lib/types/engine-hermes/agent.d.ts +47 -0
  95. package/lib/types/engine-hermes/loop.d.ts +56 -0
  96. package/lib/types/engine-hermes/process.d.ts +92 -0
  97. package/lib/types/engine-kimi/acp/client.d.ts +123 -0
  98. package/lib/types/engine-kimi/acp/mapping.d.ts +73 -0
  99. package/lib/types/engine-kimi/acp/types.d.ts +143 -0
  100. package/lib/types/engine-kimi/agent.d.ts +24 -0
  101. package/lib/types/engine-kimi/commands.d.ts +44 -0
  102. package/lib/types/engine-kimi/loop.d.ts +62 -0
  103. package/lib/types/engine-kimi/model-handover.d.ts +32 -0
  104. package/lib/types/engine-kimi/permission.d.ts +28 -0
  105. package/lib/types/engine-kimi/process.d.ts +47 -0
  106. package/lib/types/engine-kimi/profile.d.ts +19 -0
  107. package/lib/types/engine-kimi/skills.d.ts +52 -0
  108. package/lib/types/engine-kimi/types.d.ts +25 -0
  109. package/lib/types/engine-minimaxcode/agent.d.ts +24 -0
  110. package/lib/types/engine-minimaxcode/loop.d.ts +83 -0
  111. package/lib/types/engine-minimaxcode/process.d.ts +53 -0
  112. package/lib/types/engine-minimaxcode/profile.d.ts +72 -0
  113. package/lib/types/engine-of-session.d.ts +97 -0
  114. package/lib/types/engine-pi/agent.d.ts +230 -0
  115. package/lib/types/engine-pi/loop.d.ts +72 -0
  116. package/lib/types/engine-pi/model-handover.d.ts +84 -0
  117. package/lib/types/engine-pi/permission.d.ts +47 -0
  118. package/lib/types/engine-pi/rpc/client.d.ts +107 -0
  119. package/lib/types/engine-pi/rpc/mapping.d.ts +37 -0
  120. package/lib/types/engine-pi/rpc/types.d.ts +249 -0
  121. package/lib/types/engine-pi/skills.d.ts +47 -0
  122. package/lib/types/engine-pi/types.d.ts +36 -0
  123. package/lib/types/engine-qoderclicn/agent.d.ts +59 -0
  124. package/lib/types/engine-qoderclicn/loop.d.ts +51 -0
  125. package/lib/types/engine-qoderclicn/process.d.ts +113 -0
  126. package/lib/types/engine-registry.d.ts +584 -0
  127. package/lib/types/engine-remote.d.ts +192 -0
  128. package/lib/types/engine-surface.d.ts +36 -0
  129. package/lib/types/engine-zcode/agent.d.ts +50 -0
  130. package/lib/types/engine-zcode/loop.d.ts +47 -0
  131. package/lib/types/engine-zcode/process.d.ts +111 -0
  132. package/lib/types/index.d.ts +205 -0
  133. package/lib/types/invariant.d.ts +26 -0
  134. package/lib/types/model-selection-reset.d.ts +271 -0
  135. package/lib/types/namespace.d.ts +25 -0
  136. package/lib/types/patch-manager.d.ts +104 -0
  137. package/lib/types/preset.d.ts +254 -0
  138. package/lib/types/provider-route.d.ts +245 -0
  139. package/lib/types/router-loop.d.ts +458 -0
  140. package/lib/types/session-engine-store.d.ts +138 -0
  141. package/lib/types/settings.d.ts +60 -0
  142. package/lib/types/skills.d.ts +85 -0
  143. package/package.json +150 -4
@@ -0,0 +1,225 @@
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-loop-engine-allinone/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
+ /**
99
+ * One item of a `turn/start` input array. Codex's `UserInput` is a union of
100
+ * text, image, local-image, audio, skill, and mention items; this driver sends
101
+ * the step's serialized prompt as a text item and then one `localImage` item
102
+ * per image the step carries. `localImage` names a host file rather than
103
+ * carrying bytes, so codex's app-server opens the image itself.
104
+ */
105
+ export type TurnInput = {
106
+ readonly type: 'text';
107
+ readonly text: string;
108
+ } | {
109
+ readonly type: 'localImage';
110
+ readonly path: string;
111
+ };
112
+ export interface TurnInfo {
113
+ readonly id: string;
114
+ readonly status: string;
115
+ readonly error: {
116
+ readonly message: string;
117
+ } | null;
118
+ readonly items: readonly unknown[];
119
+ readonly [key: string]: unknown;
120
+ }
121
+ export interface TurnStartResult {
122
+ readonly turn: TurnInfo;
123
+ }
124
+ export interface TurnInterruptParams {
125
+ readonly threadId: string;
126
+ readonly turnId: string;
127
+ }
128
+ /** item/agentMessage/delta — agent message token delta. */
129
+ export interface AgentMessageDeltaNotification {
130
+ readonly threadId: string;
131
+ readonly turnId: string;
132
+ readonly itemId: string;
133
+ readonly delta: string;
134
+ }
135
+ /** item/reasoning/summaryTextDelta — reasoning summary token delta. */
136
+ export interface ReasoningSummaryTextDeltaNotification {
137
+ readonly threadId: string;
138
+ readonly turnId: string;
139
+ readonly itemId: string;
140
+ readonly delta: string;
141
+ readonly summaryIndex: number;
142
+ }
143
+ /** item/reasoning/textDelta — reasoning content token delta. */
144
+ export interface ReasoningTextDeltaNotification {
145
+ readonly threadId: string;
146
+ readonly turnId: string;
147
+ readonly itemId: string;
148
+ readonly delta: string;
149
+ readonly contentIndex: number;
150
+ }
151
+ /** item/plan/delta — plan delta. */
152
+ export interface PlanDeltaNotification {
153
+ readonly threadId: string;
154
+ readonly turnId: string;
155
+ readonly itemId: string;
156
+ readonly delta: string;
157
+ }
158
+ /** item/started — item lifecycle start. */
159
+ export interface ItemStartedNotification {
160
+ readonly threadId: string;
161
+ readonly turnId: string;
162
+ readonly item: {
163
+ readonly type: string;
164
+ readonly id: string;
165
+ readonly [key: string]: unknown;
166
+ };
167
+ readonly startedAtMs: number;
168
+ }
169
+ /** item/completed — item lifecycle end. */
170
+ export interface ItemCompletedNotification {
171
+ readonly threadId: string;
172
+ readonly turnId: string;
173
+ readonly item: {
174
+ readonly type: string;
175
+ readonly id: string;
176
+ readonly text?: string;
177
+ readonly [key: string]: unknown;
178
+ };
179
+ readonly completedAtMs: number;
180
+ }
181
+ /** turn/completed — turn end with usage. */
182
+ export interface TurnCompletedNotification {
183
+ readonly threadId: string;
184
+ readonly turn: TurnInfo & {
185
+ readonly usage?: {
186
+ readonly inputTokens: number;
187
+ readonly cachedInputTokens?: number;
188
+ readonly outputTokens: number;
189
+ readonly reasoningOutputTokens?: number;
190
+ };
191
+ };
192
+ }
193
+ /** thread/tokenUsage/updated — token usage update. */
194
+ export interface ThreadTokenUsageUpdatedNotification {
195
+ readonly threadId: string;
196
+ readonly turnId: string;
197
+ readonly tokenUsage: {
198
+ readonly total: {
199
+ readonly totalTokens: number;
200
+ readonly inputTokens: number;
201
+ readonly cachedInputTokens: number;
202
+ readonly outputTokens: number;
203
+ readonly reasoningOutputTokens: number;
204
+ };
205
+ readonly last: {
206
+ readonly totalTokens: number;
207
+ readonly inputTokens: number;
208
+ readonly cachedInputTokens: number;
209
+ readonly outputTokens: number;
210
+ readonly reasoningOutputTokens: number;
211
+ };
212
+ };
213
+ }
214
+ /** error notification. */
215
+ export interface ErrorNotification {
216
+ readonly threadId: string;
217
+ readonly turnId: string;
218
+ readonly error: {
219
+ readonly message: string;
220
+ readonly codexErrorInfo?: string | null;
221
+ readonly additionalDetails?: string | null;
222
+ };
223
+ readonly willRetry: boolean;
224
+ }
225
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Codex loop engine module: drives every session it is handed through the
3
+ * OpenAI Codex SDK, one stateless thread per dsh step, with the durable
4
+ * session log as the sole source of model context. The router routes a session
5
+ * here on the plugin's own engine record, else its agent preset; this module is
6
+ * a 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-loop-engine-allinone/engine-codex
11
+ */
12
+ import type { Context } from '@deepseek-ai/cordis';
13
+ import z from '@deepseek-ai/schemastery';
14
+ import type { AgentOptions } from '@deepseek-ai/dsh-agent';
15
+ import type { Session, SessionId } from '@deepseek-ai/dsh-session';
16
+ import { CodexAgent } from './agent.ts';
17
+ import type { CodexApprovalPolicy, CodexSandboxMode, ResolvedConfig } from './types.ts';
18
+ import { HostedEngineRuntime } from '../driver-core/hosted-engine-runtime.ts';
19
+ /** Codex CLI sandbox modes a deployment may pin. */
20
+ export declare const CODEX_SANDBOX_MODES: readonly CodexSandboxMode[];
21
+ /** Codex CLI approval policies a deployment may pin. */
22
+ export declare const CODEX_APPROVAL_POLICIES: readonly CodexApprovalPolicy[];
23
+ /** Deployment-owned configuration for the Codex loop plugin. */
24
+ export interface Config {
25
+ /**
26
+ * Pinned sandbox mode for every thread. When omitted, each query follows the
27
+ * session's dsh permission knobs (`sandbox/mode` and `approval/policy`):
28
+ * full access maps to `danger-full-access`, an `ask` policy maps to
29
+ * `workspace-write`, and anything else fails closed with `read-only`.
30
+ */
31
+ sandboxMode?: CodexSandboxMode;
32
+ /**
33
+ * Pinned approval policy for every thread. When omitted, each query follows
34
+ * the session's dsh permission knobs: an `ask` policy maps to `on-request`
35
+ * (the CLI's own interactive prompt degrades to a denial in the unattended
36
+ * dsh runtime) and anything else maps to `never`.
37
+ */
38
+ approvalPolicy?: CodexApprovalPolicy;
39
+ /** Explicit environment entries layered over the credential-scrubbed parent environment. */
40
+ env?: Record<string, string>;
41
+ /** Fallback model for the app-server thread, used when the session selects none; Codex native settings own the model when omitted. */
42
+ model?: string;
43
+ /**
44
+ * Idle window in milliseconds before a session's `codex app-server` child is
45
+ * shut down, spawned again by the next step. Omitted or non-positive keeps
46
+ * the child for the session's whole life.
47
+ */
48
+ childIdleMs?: number;
49
+ /**
50
+ * An EXTERNAL `codex` executable, replacing this package's bundled
51
+ * `@openai/codex` dependency. Omitted keeps the bundled copy, which is what
52
+ * every earlier release ran.
53
+ */
54
+ bin?: string;
55
+ }
56
+ /** Schema of the Codex loop plugin configuration. */
57
+ export declare const Config: z<Config>;
58
+ /** Host-face ctx key this engine's runtime is registered under. */
59
+ export declare const CODEX_ENGINE_LABEL = "agentLoopCodex";
60
+ declare module '@deepseek-ai/cordis' {
61
+ interface Context {
62
+ agentLoopCodex: CodexLoop;
63
+ }
64
+ }
65
+ /**
66
+ * Creation/resume machinery for the Codex engine. The process-wide
67
+ * AgentFactory slot belongs to the router, which delegates each session to the
68
+ * engine its preset names; this class is that engine's driver, not a plugin.
69
+ */
70
+ export declare class CodexLoop extends HostedEngineRuntime<ResolvedConfig, CodexAgent> {
71
+ constructor(ctx: Context, config: Config);
72
+ /** Construct the Codex driver for one prepared session. */
73
+ protected buildAgent(loopCtx: Context, id: SessionId, options: AgentOptions, session: Session): CodexAgent;
74
+ }
75
+ //# sourceMappingURL=loop.d.ts.map
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Codex's dialect for a dsh endpoint: the `codex app-server` configuration
3
+ * overrides and environment that point it at dsh's model.
4
+ *
5
+ * Codex resolves a custom endpoint through `model_providers.<id>` in its own
6
+ * `config.toml` (`name`, `base_url`, `wire_api`, and an `env_key` naming the
7
+ * variable the credential is read from), and `codex app-server` accepts those as
8
+ * `-c key=value` overrides — so the handover needs no edit of `~/.codex`. The
9
+ * credential travels in the child's environment under {@link CODEX_DSH_API_KEY_ENV},
10
+ * which the `env_key` names.
11
+ *
12
+ * `name` is not optional in practice even though the CLI's own docs describe it
13
+ * as display metadata: codex 0.149.1 (the version this plugin pins) refuses to
14
+ * load a provider whose `name` is empty — "provider name must not be empty in
15
+ * `model_providers`" — and that config error kills `app-server` on startup, which
16
+ * the driver can only report as "process exited unexpectedly". Omitting it looked
17
+ * correct and failed before any request was ever sent, so every override this
18
+ * module builds carries it (verified against the pinned binary).
19
+ *
20
+ * Codex speaks only OpenAI's `responses` wire as of the version this plugin pins
21
+ * (0.149.1 dropped `chat`). A dsh protocol with no codex equivalent (Anthropic
22
+ * Messages, and now OpenAI Chat Completions) is NOT guessed: `wire_api` is
23
+ * omitted, so codex falls back to its own default wire and fails loud on the
24
+ * request — the honest outcome, since the plugin cannot make codex speak a
25
+ * protocol it does not implement. That default is `responses` as of 0.149.1: the
26
+ * request lands on `<baseURL>/responses`, which an Anthropic Messages or Chat
27
+ * Completions endpoint does not serve.
28
+ *
29
+ * @module dsh-loop-engine-allinone/engine-codex/model-handover
30
+ */
31
+ import type { DshModelHandover } from '../driver-core/model-handover.ts';
32
+ /** Provider id codex is configured with when dsh's endpoint is handed over. */
33
+ export declare const CODEX_DSH_PROVIDER = "dsh";
34
+ /** Environment variable codex reads the handed-over credential from. */
35
+ export declare const CODEX_DSH_API_KEY_ENV = "DSH_LOOP_ENGINE_API_KEY";
36
+ /** The `codex app-server` argv/env that hand one dsh endpoint over. */
37
+ export interface CodexModelConfig {
38
+ /** `-c` overrides to append to the `app-server` subcommand. */
39
+ readonly argv: string[];
40
+ /** Environment the child needs to read the endpoint's credential. */
41
+ readonly env: Record<string, string>;
42
+ }
43
+ /**
44
+ * Translate one dsh endpoint handover into codex's `-c` overrides and the
45
+ * environment carrying the credential.
46
+ *
47
+ * The provider id ({@link CODEX_DSH_PROVIDER}) is a plugin-owned name: it exists
48
+ * only in this child's command line, so it cannot collide with a provider the
49
+ * user configured, and the model itself is still handed over as the thread's own
50
+ * `model` param. The provider's `name` repeats that id because codex rejects an
51
+ * empty one at config load, before any request is made.
52
+ * @param handover - the resolved dsh endpoint for the session's selection.
53
+ * @returns the argv entries and environment to spawn the app-server with.
54
+ */
55
+ export declare function codexModelConfig(handover: DshModelHandover): CodexModelConfig;
56
+ //# sourceMappingURL=model-handover.d.ts.map
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Mapping from the dsh session's durable permission knobs to one Codex query's
3
+ * declarative permission stance, plus the replies to every server-initiated
4
+ * interaction Codex can raise. Codex surfaces interactive approval as
5
+ * server-initiated JSON-RPC requests answered through the dsh approval seam
6
+ * (see `approvalReason` / `resolveApprovalRequest` below), while the thread
7
+ * still starts with the `sandboxMode` + `approvalPolicy` pair chosen at
8
+ * creation. The fold maps the session's `sandbox/mode` and `approval/policy`
9
+ * events directly, mirroring the web surface's presets:
10
+ * - full access → `danger-full-access` + `never` (no native checks at all),
11
+ * - an `ask` policy → `workspace-write` + `on-request` (approvals are then
12
+ * routed to the dsh approval seam, failing closed when it is absent),
13
+ * - anything else fails closed → `read-only` + `never`.
14
+ *
15
+ * The other two interactions (`item/tool/requestUserInput` and
16
+ * `mcpServer/elicitation/request`) have no approval to grant: one asks the human
17
+ * a question, the other asks for MCP input. Both are mapped here so the driver
18
+ * answers them in-vocabulary instead of failing them with a protocol error that
19
+ * the model reads as a broken tool.
20
+ *
21
+ * @module dsh-loop-engine-allinone/engine-codex/permission
22
+ */
23
+ import type { PermissionEvent } from '../driver-core/permission-knobs.ts';
24
+ import type { CodexApprovalPolicy, CodexSandboxMode } from './types.ts';
25
+ /** The declarative permission stance one Codex thread runs under. */
26
+ export interface CodexPermission {
27
+ readonly sandboxMode: CodexSandboxMode;
28
+ readonly approvalPolicy: CodexApprovalPolicy;
29
+ }
30
+ /** Conservative unattended default: read-only sandbox, never ask. */
31
+ export declare const DEFAULT_CODEX_PERMISSION: CodexPermission;
32
+ /**
33
+ * One question to put to the human, in the shape the dsh user-questions seam
34
+ * accepts. Declared inline (a structural subset) to avoid a peer dep on
35
+ * `@deepseek-ai/dsh-user-questions`, matching the approval seam's treatment.
36
+ */
37
+ export interface UserQuestionItem {
38
+ /** Stable question id, echoed back by the answer and by our reply. */
39
+ readonly id: string;
40
+ /** The question to display. */
41
+ readonly question: string;
42
+ /** Optional short heading/group label. */
43
+ readonly header?: string;
44
+ /** Optional choices a UI renders as a menu. */
45
+ readonly options?: readonly {
46
+ readonly label: string;
47
+ readonly description?: string;
48
+ }[];
49
+ }
50
+ /** The human's answer, in the shape the dsh user-questions seam returns. */
51
+ export interface UserQuestionAnswer {
52
+ /** One entry per answered question; unanswered questions are simply absent. */
53
+ readonly answers: readonly {
54
+ readonly id: string;
55
+ readonly selected: readonly string[];
56
+ /** Optional free-text answer, carried alongside `selected`. */
57
+ readonly custom?: string;
58
+ }[];
59
+ }
60
+ /** The `item/tool/requestUserInput` result Codex expects. */
61
+ export interface CodexUserInputResponse {
62
+ /** Answer lists keyed by question id; an empty map means "no answers given". */
63
+ readonly answers: Record<string, {
64
+ readonly answers: string[];
65
+ }>;
66
+ }
67
+ /**
68
+ * Read the answerable questions of one `item/tool/requestUserInput` request. The
69
+ * wire is untrusted, so an entry with no usable id or wording is dropped: the
70
+ * reply is keyed by question id, and a synthesized key would answer a question
71
+ * Codex never asked.
72
+ * @param params - the request params.
73
+ * @returns the questions to put to the human, possibly none.
74
+ */
75
+ export declare function userInputQuestions(params: unknown): UserQuestionItem[];
76
+ /**
77
+ * Project one human answer onto Codex's response shape. A free-text answer rides
78
+ * along as a further entry of the question's answer list, and no answer at all
79
+ * (no seam, or the human dismissed it) becomes an empty map — the honest "asked,
80
+ * answered nothing", never an invented answer.
81
+ * @param answer - the seam's answer, or undefined when none was obtained.
82
+ * @returns the response payload.
83
+ */
84
+ export declare function userInputResponse(answer: UserQuestionAnswer | undefined): CodexUserInputResponse;
85
+ /**
86
+ * The reply to one `mcpServer/elicitation/request`. An unattended driver cannot
87
+ * render an elicitation form, so it declines — the same stance the Claude Code
88
+ * driver takes for the equivalent callback, and the one answer that never
89
+ * fabricates input the user did not give.
90
+ * @returns the response payload.
91
+ */
92
+ export declare function elicitationResponse(): {
93
+ action: 'decline';
94
+ };
95
+ /**
96
+ * Resolve the session's effective Codex permission stance. Full access wins
97
+ * outright; otherwise an `ask` policy maps to the CLI's on-request approval
98
+ * inside a workspace-write sandbox; anything else — including a session with
99
+ * no recorded knobs — fails closed.
100
+ * @param events - the durable session log.
101
+ * @returns the stance one query should run under.
102
+ */
103
+ export declare function resolveSessionPermission(events: readonly PermissionEvent[]): CodexPermission;
104
+ /** The closed outcome of one dsh approval request (mirrors the dsh-user-approval seam). */
105
+ export type ApprovalOutcome = 'allowed-once' | 'rejected' | 'cancelled' | 'unavailable';
106
+ /** Short tool identity for the dsh approval request carrying one native Codex approval. */
107
+ export declare function approvalToolName(method: string): string;
108
+ /** Human-readable reason for one native Codex approval request. */
109
+ export declare function approvalReason(method: string, params: unknown): string;
110
+ /** The native decision a command/file-change approval resolves to. */
111
+ export declare function approvalDecision(outcome: ApprovalOutcome): 'accept' | 'decline';
112
+ /** The native permissions-request response for one approval outcome. */
113
+ export declare function permissionsGrant(outcome: ApprovalOutcome, requested: unknown): {
114
+ permissions: unknown;
115
+ scope: 'turn';
116
+ };
117
+ /** Build the JSON-RPC reply payload for one inbound Codex approval request. */
118
+ export declare function resolveApprovalRequest(method: string, params: unknown, outcome: ApprovalOutcome): {
119
+ result: unknown;
120
+ } | {
121
+ error: {
122
+ code: number;
123
+ message: string;
124
+ };
125
+ };
126
+ //# sourceMappingURL=permission.d.ts.map
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Codex skill provider: exposes the codex CLI's instruction files as DSH
3
+ * skills.
4
+ *
5
+ * Codex has no per-skill catalog like the agents-skill standard; its
6
+ * instructions are `AGENTS.md` files read from the session cwd up to the git
7
+ * root, plus the global `~/.codex/AGENTS.md`. Each file set is surfaced as one
8
+ * user-invocable `agents-md` skill whose body is the concatenated file
9
+ * contents, so the dsh skill-injection seam (`/name` gestures) can carry it
10
+ * into the prompt.
11
+ *
12
+ * The discovery algorithm itself lives in {@link AgentsMdSkillProvider}; this
13
+ * module supplies only Codex's locations and ranks — and, having no skills
14
+ * catalog, no `skills` entry.
15
+ *
16
+ * @module dsh-loop-engine-allinone/engine-codex/skills
17
+ */
18
+ import { AgentsMdSkillProvider } from '../driver-core/agents-md-skill-provider.ts';
19
+ import type { SkillProviderControl } from '../skills.ts';
20
+ /**
21
+ * Skill provider that discovers `AGENTS.md` from every directory between the
22
+ * project cwd and the git root, plus the user home `~/.codex/AGENTS.md`.
23
+ */
24
+ export declare class CodexSkillProvider extends AgentsMdSkillProvider {
25
+ constructor(control: SkillProviderControl);
26
+ }
27
+ export default CodexSkillProvider;
28
+ //# sourceMappingURL=skills.d.ts.map
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Public types of the Codex loop driver. Types only — no runtime code.
3
+ *
4
+ * @module dsh-loop-engine-allinone/engine-codex/types
5
+ */
6
+ /** Codex CLI sandbox modes, as spoken by the app-server `sandbox` field. */
7
+ export type CodexSandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access';
8
+ /** Codex CLI approval policies, as spoken by the app-server `approvalPolicy` field. */
9
+ export type CodexApprovalPolicy = 'never' | 'on-request' | 'on-failure' | 'untrusted';
10
+ /** Driver configuration after defaults and load-time validation. */
11
+ export interface ResolvedConfig {
12
+ /** Pinned sandbox mode; `undefined` follows the session's dsh permission knobs per query. */
13
+ readonly sandboxMode: CodexSandboxMode | undefined;
14
+ /** Pinned approval policy; `undefined` follows the session's dsh permission knobs per query. */
15
+ readonly approvalPolicy: CodexApprovalPolicy | undefined;
16
+ readonly env: Record<string, string>;
17
+ readonly model: string | undefined;
18
+ /**
19
+ * How long an idle session keeps its `codex app-server` child, in
20
+ * milliseconds; zero or less keeps it for the session's whole life. See
21
+ * `driver-core/idle-child.ts` for why the child, and not the agent, is what
22
+ * gets released.
23
+ */
24
+ readonly childIdleMs: number;
25
+ /**
26
+ * An EXTERNAL `codex` executable to launch instead of this package's bundled
27
+ * `@openai/codex`, or `undefined` to keep the bundled copy.
28
+ *
29
+ * The bundled dependency is a Node script, so the driver runs it under the
30
+ * current node; an external path may be either — a `.js` entrypoint is run
31
+ * under node, anything else is spawned directly. That distinction is why the
32
+ * resolver returns a whole argv prefix rather than a single path.
33
+ */
34
+ readonly bin: string | undefined;
35
+ }
36
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,132 @@
1
+ /**
2
+ * The node-side half of the engine registry: which class drives which engine.
3
+ *
4
+ * {@link ENGINE_REGISTRY} (`./engine-registry.ts`) declares what every engine
5
+ * IS, in data the browser bundle can also read. This module is the one place
6
+ * that has to import the driver classes themselves, and it is deliberately
7
+ * node-only: `./client/**` must never reach it, or the browser artifact would
8
+ * pull `node:fs`, the SDKs and every engine driver with it.
9
+ *
10
+ * The two are kept in step by the type system rather than by discipline:
11
+ * {@link ENGINE_DRIVER_FACTORIES} is a total `Record` over
12
+ * {@link HostedEngineId}, so adding an id to the registry without adding its
13
+ * driver fails the build. The reverse (a driver with no id) cannot happen —
14
+ * the record's keys are the ids.
15
+ *
16
+ * ## What a driver factory receives
17
+ *
18
+ * Every engine is constructed from the SAME composition-entry config object
19
+ * (`Config` in `./index.ts`), because the entry is an engine-agnostic superset:
20
+ * any session may select any engine at any moment, so the entry carries every
21
+ * engine's knobs at once. Each factory picks the fields its engine owns and
22
+ * drops the rest — which is why the per-engine config projections live here
23
+ * rather than in the entry's schema.
24
+ *
25
+ * @module dsh-loop-engine-allinone/engine-drivers
26
+ */
27
+ import type { Context } from '@deepseek-ai/cordis';
28
+ import type { ClaudeCodePermissionMode } from './engine-claude/types.ts';
29
+ import type { CodexApprovalPolicy, CodexSandboxMode } from './engine-codex/types.ts';
30
+ import type { PiSandboxMode } from './engine-pi/types.ts';
31
+ import type { AgyEffort, AgyMode } from './engine-agy/process.ts';
32
+ import type { HostedEngineId } from './engine-registry.ts';
33
+ import type { RouterEngine } from './router-loop.ts';
34
+ /**
35
+ * The engine knobs one composition entry carries, as this module reads them.
36
+ *
37
+ * Declared structurally rather than imported from `./index.ts` so the
38
+ * dependency runs one way: `index.ts` imports the dispatch table, and the table
39
+ * does not import the entry's schema. Every field is optional, matching the
40
+ * entry's permissive schema — a deployment configures only the engines it uses.
41
+ */
42
+ export interface EngineDriverConfig {
43
+ /** Claude Code: pinned permission mode (overrides the session's own knobs). */
44
+ permissionMode?: ClaudeCodePermissionMode;
45
+ /** Explicit environment entries layered over the credential-scrubbed parent environment. */
46
+ env?: Record<string, string>;
47
+ /** Fallback model, used when the session selects none. */
48
+ model?: string;
49
+ /** Claude Code: grace for process-tree termination. */
50
+ disposeGraceMs?: number;
51
+ /** Claude Code: cap on agent turns per query. */
52
+ maxTurns?: number;
53
+ /** Codex / Pi: pinned sandbox mode. */
54
+ sandboxMode?: CodexSandboxMode | PiSandboxMode;
55
+ /** Codex: pinned approval policy. */
56
+ approvalPolicy?: CodexApprovalPolicy;
57
+ /** Pi: pinned LLM provider. */
58
+ piProvider?: string;
59
+ /** Pi: thinking/reasoning level. */
60
+ piThinking?: string;
61
+ /** Idle window before a persistent child is shut down (Kimi, Codex). */
62
+ childIdleMs?: number;
63
+ /** Antigravity: pinned execution mode (`--mode`). */
64
+ agyMode?: AgyMode;
65
+ /** Antigravity: pinned reasoning effort (`--effort`). */
66
+ agyEffort?: AgyEffort;
67
+ /** Antigravity: pinned terminal-restriction flag. */
68
+ agySandbox?: boolean;
69
+ /** Antigravity: pinned auto-approve flag, overriding the session's sandbox knob. */
70
+ agyDangerouslySkipPermissions?: boolean;
71
+ /** Qoder CN: pinned permission mode, overriding the session's dsh knobs. */
72
+ qoderPermissionMode?: string;
73
+ /** Hermes: pinned reasoning level (`--reasoning`). */
74
+ hermesReasoning?: string;
75
+ /**
76
+ * The Kimi engine's executable, as every release before the registry exposed
77
+ * it.
78
+ *
79
+ * Kept as a working alias rather than removed: it is a published composition
80
+ * field, so a deployment that set it must keep working unchanged, and silently
81
+ * ignoring a configured path would point the engine at a different binary than
82
+ * the operator chose. {@link EngineDriverConfig.bins} WINS when both are set —
83
+ * the newer, engine-agnostic form is the one to prefer.
84
+ *
85
+ * @deprecated use `bins.kimiBin`.
86
+ */
87
+ kimiBin?: string;
88
+ /**
89
+ * Per-engine executable overrides, keyed by each descriptor's
90
+ * {@link EngineDescriptor.binConfigKey}.
91
+ *
92
+ * One open map rather than a field per engine: the registry already names the
93
+ * key each engine reads, so a new engine adds no schema field and no
94
+ * projection branch — it reads `config.bins?.[descriptor.binConfigKey]`.
95
+ */
96
+ bins?: Readonly<Record<string, string>>;
97
+ /**
98
+ * Per-engine account REGION overrides, keyed by each descriptor's own
99
+ * {@link EngineRegion.configKey}.
100
+ *
101
+ * The same open-map shape as {@link EngineDriverConfig.bins}, for the same
102
+ * reason: an engine whose CLI scopes accounts by region declares the knob in the
103
+ * registry, and a deployment overrides it here without a per-engine schema
104
+ * field. Today only MiniMax Code declares one (`regions.mcodeRegion`, default
105
+ * `cn`).
106
+ */
107
+ regions?: Readonly<Record<string, string>>;
108
+ }
109
+ /** Builds one engine's driver runtime. */
110
+ export type EngineDriverFactory = (ctx: Context, config: EngineDriverConfig) => RouterEngine;
111
+ /**
112
+ * One factory per hosted engine.
113
+ *
114
+ * Total over {@link HostedEngineId} by type: the compiler refuses a missing row,
115
+ * which is what makes "add an id to the registry" an incomplete change until the
116
+ * driver is wired too.
117
+ */
118
+ export declare const ENGINE_DRIVER_FACTORIES: Readonly<Record<HostedEngineId, EngineDriverFactory>>;
119
+ /**
120
+ * Build one hosted engine's driver runtime.
121
+ *
122
+ * The one dispatch point the router calls, replacing the per-engine `switch`
123
+ * that used to live in `./index.ts`: adding an engine is now a registry row plus
124
+ * a factory row, and the `switch` that would have needed a new `case` — and a
125
+ * new `default` to keep TypeScript quiet — is gone.
126
+ * @param engine - the engine to build.
127
+ * @param ctx - the context the runtime's effects belong to.
128
+ * @param config - the composition entry's engine knobs.
129
+ * @returns the engine's driver runtime.
130
+ */
131
+ export declare function buildEngineDriver(engine: HostedEngineId, ctx: Context, config: EngineDriverConfig): RouterEngine;
132
+ //# sourceMappingURL=engine-drivers.d.ts.map