@pwrdrvr/agent-client 0.1.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/LICENSE +21 -0
- package/dist/index.d.ts +532 -0
- package/dist/index.js +1527 -0
- package/dist/index.js.map +1 -0
- package/package.json +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 PwrDrvr LLC
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
import { AgentBackendApprovalHandler, AgentBackend, Logger, NormalizedThreadEvent, AgentBackendToolCallHandler, AgentStartThreadOptions, AgentStartTurnOptions, NormalizedTokenUsage, NormalizedApprovalRequest, NormalizedToolCall, NormalizedThreadSettings, NormalizedThreadView, NormalizedMessage, ThreadStore, NormalizedApprovalDecision } from '@pwrdrvr/agent-core';
|
|
2
|
+
import { JsonRpcTransport } from '@pwrdrvr/agent-transport';
|
|
3
|
+
import { DynamicToolSpec, UserInput, Model, DynamicToolCallParams, ThreadItem, ThreadSettingsUpdatedNotification, ThreadTokenUsage, DynamicToolCallOutputContentItem, DynamicToolCallResponse } from '@pwrdrvr/codex-app-server-protocol/v2';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
|
|
6
|
+
type CodexThreadClientTransportFactory = (command: string) => JsonRpcTransport;
|
|
7
|
+
type CodexThreadClientOptions = {
|
|
8
|
+
/** Configured command to resolve. `"codex"` (or empty) triggers discovery. */
|
|
9
|
+
command?: string;
|
|
10
|
+
/** Identity sent as `clientInfo.name` at `initialize`. Defaults to "agent-kit". */
|
|
11
|
+
clientName?: string;
|
|
12
|
+
/** Human title sent as `clientInfo.title`. Defaults to `clientName`. */
|
|
13
|
+
clientTitle?: string;
|
|
14
|
+
/** Version sent as `clientInfo.version`. Defaults to "0.0.0". */
|
|
15
|
+
clientVersion?: string;
|
|
16
|
+
/** Default `serviceName` applied at `thread/start` when the caller omits one. */
|
|
17
|
+
serviceName?: string;
|
|
18
|
+
requestTimeoutMs?: number;
|
|
19
|
+
turnTimeoutMs?: number;
|
|
20
|
+
/** Process env passed to the spawned codex. Defaults to `process.env`. */
|
|
21
|
+
env?: NodeJS.ProcessEnv;
|
|
22
|
+
/** Override the transport (tests inject an in-memory fake). When supplied,
|
|
23
|
+
* no discovery/spawn happens. */
|
|
24
|
+
transportFactory?: CodexThreadClientTransportFactory;
|
|
25
|
+
logger?: Logger;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Codex-NATIVE thread/start options. **No longer the public `startThread`
|
|
29
|
+
* surface** — `CodexThreadClient` now implements the non-generic `AgentBackend`
|
|
30
|
+
* and its public `startThread` takes neutral `AgentStartThreadOptions`. This
|
|
31
|
+
* type is retained as the internal mapping target (and is still exported for
|
|
32
|
+
* hosts that want to construct the native shape directly via
|
|
33
|
+
* `startThreadNative`). The neutral→native mapping lives in `startThread`.
|
|
34
|
+
*/
|
|
35
|
+
type CodexStartThreadOptions = {
|
|
36
|
+
approvalPolicy?: string;
|
|
37
|
+
sandbox?: string;
|
|
38
|
+
baseInstructions?: string;
|
|
39
|
+
dynamicTools?: DynamicToolSpec[];
|
|
40
|
+
cwd?: string;
|
|
41
|
+
runtimeWorkspaceRoots?: string[];
|
|
42
|
+
serviceName?: string;
|
|
43
|
+
personality?: string;
|
|
44
|
+
/** Model id to start the thread on (ThreadStartParams.model). Omit for the
|
|
45
|
+
* Codex default. The host drives this from its settings (per-surface default). */
|
|
46
|
+
model?: string;
|
|
47
|
+
/** Model provider id (ThreadStartParams.modelProvider) — the "provider" a host
|
|
48
|
+
* picks when more than one is configured. Omit for the Codex default. */
|
|
49
|
+
modelProvider?: string;
|
|
50
|
+
/** Service tier (ThreadStartParams.serviceTier), when the host pins one. */
|
|
51
|
+
serviceTier?: string;
|
|
52
|
+
/** Per-thread Codex config overlay (the `-c key=value` mechanism). Used to
|
|
53
|
+
* disable Codex prompt/tool scaffolding that belongs to coding-agent threads. */
|
|
54
|
+
config?: Record<string, unknown>;
|
|
55
|
+
/** Thread environments. **Empty array disables exec-environment access**,
|
|
56
|
+
* dropping Codex's built-in shell / unified_exec / apply_patch tools. Dynamic
|
|
57
|
+
* tools are added before that gate, so they survive. */
|
|
58
|
+
environments?: unknown[];
|
|
59
|
+
};
|
|
60
|
+
/** Codex-NATIVE turn/start options. Internal mapping target (see
|
|
61
|
+
* `startThreadNative`'s sibling `startTurnNative`); the public `startTurn`
|
|
62
|
+
* takes neutral `AgentStartTurnOptions`. */
|
|
63
|
+
type CodexStartTurnOptions = {
|
|
64
|
+
threadId: string;
|
|
65
|
+
input: UserInput[];
|
|
66
|
+
effort?: string;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Handles a tool-call ServerRequest. Reconciled to the canonical
|
|
70
|
+
* `AgentBackendToolCallHandler` shape so the controller drives Codex and ACP
|
|
71
|
+
* identically: the handler receives a neutral `AgentBackendToolCall`
|
|
72
|
+
* (`{ method, params }`) and returns an `unknown` payload the client forwards
|
|
73
|
+
* back to Codex verbatim. For Codex the `params` is a `DynamicToolCallParams`
|
|
74
|
+
* (cast at the dispatch site) and the returned payload is a
|
|
75
|
+
* `DynamicToolCallResponse`.
|
|
76
|
+
*/
|
|
77
|
+
type CodexToolCallHandler = AgentBackendToolCallHandler;
|
|
78
|
+
/** Handles an approval ServerRequest; resolves to a neutral decision. Identical
|
|
79
|
+
* to the canonical `AgentBackendApprovalHandler`. */
|
|
80
|
+
type CodexApprovalHandler = AgentBackendApprovalHandler;
|
|
81
|
+
type Unsubscribe = () => void;
|
|
82
|
+
type StartThreadResult = {
|
|
83
|
+
threadId: string;
|
|
84
|
+
model: string;
|
|
85
|
+
modelProvider: string;
|
|
86
|
+
serviceTier: string | null;
|
|
87
|
+
};
|
|
88
|
+
declare class CodexThreadClient implements AgentBackend {
|
|
89
|
+
private readonly options;
|
|
90
|
+
private readonly requestTimeoutMs;
|
|
91
|
+
private readonly turnTimeoutMs;
|
|
92
|
+
private readonly logger;
|
|
93
|
+
private readonly transportFactory;
|
|
94
|
+
private resolvedCommand;
|
|
95
|
+
private connection;
|
|
96
|
+
private initializeResponse;
|
|
97
|
+
private readonly eventListeners;
|
|
98
|
+
private toolCallHandler;
|
|
99
|
+
private approvalHandler;
|
|
100
|
+
private readonly loadedThreadIds;
|
|
101
|
+
constructor(options?: CodexThreadClientOptions);
|
|
102
|
+
/** Subscribe to the normalized event stream. Every native notification is
|
|
103
|
+
* routed through `normalizeNotification` before listeners see it. */
|
|
104
|
+
onEvent(cb: (event: NormalizedThreadEvent) => void): Unsubscribe;
|
|
105
|
+
/** Register the dynamic-tool ServerRequest handler (one at a time). */
|
|
106
|
+
onToolCall(handler: CodexToolCallHandler): Unsubscribe;
|
|
107
|
+
/** Register the approval ServerRequest handler (one at a time). */
|
|
108
|
+
onApprovalRequest(handler: CodexApprovalHandler): Unsubscribe;
|
|
109
|
+
/**
|
|
110
|
+
* Public `AgentBackend.startThread`: accepts NEUTRAL `AgentStartThreadOptions`
|
|
111
|
+
* and maps them onto Codex-native `CodexStartThreadOptions` before delegating
|
|
112
|
+
* to `startThreadNative`. Mapping:
|
|
113
|
+
* instructions→baseInstructions, cwd, workspaceRoots→runtimeWorkspaceRoots,
|
|
114
|
+
* model/modelProvider, serviceTier (drop `null`), approvalPolicy, sandbox,
|
|
115
|
+
* serviceName, config, environments, tools (cast to DynamicToolSpec[])→
|
|
116
|
+
* dynamicTools.
|
|
117
|
+
*/
|
|
118
|
+
startThread(opts?: AgentStartThreadOptions): Promise<StartThreadResult>;
|
|
119
|
+
/** Codex-native thread/start. Builds `ThreadStartParams` directly. Exposed for
|
|
120
|
+
* hosts that want full Codex control; the neutral `startThread` delegates here. */
|
|
121
|
+
startThreadNative(opts?: CodexStartThreadOptions): Promise<StartThreadResult>;
|
|
122
|
+
resumeThread(threadId: string): Promise<void>;
|
|
123
|
+
clearThreadGitInfo(threadId: string): Promise<void>;
|
|
124
|
+
/**
|
|
125
|
+
* Public `AgentBackend.startTurn`: accepts NEUTRAL `AgentStartTurnOptions` and
|
|
126
|
+
* maps them onto Codex-native `UserInput[]`. The neutral `input.text` becomes a
|
|
127
|
+
* leading `{ type: "text" }` item; each `input.imagePaths` entry becomes a
|
|
128
|
+
* `{ type: "localImage", path }` item appended after the text. `reasoning`
|
|
129
|
+
* maps to Codex's `effort`.
|
|
130
|
+
*/
|
|
131
|
+
startTurn(opts: AgentStartTurnOptions): Promise<{
|
|
132
|
+
turnId: string;
|
|
133
|
+
}>;
|
|
134
|
+
/** Codex-native turn/start. Takes pre-built `UserInput[]`. The neutral
|
|
135
|
+
* `startTurn` delegates here after mapping text + image paths. */
|
|
136
|
+
startTurnNative(opts: CodexStartTurnOptions): Promise<{
|
|
137
|
+
turnId: string;
|
|
138
|
+
}>;
|
|
139
|
+
interruptTurn(threadId: string): Promise<void>;
|
|
140
|
+
archiveThread(threadId: string): Promise<void>;
|
|
141
|
+
close(): Promise<void>;
|
|
142
|
+
private emit;
|
|
143
|
+
private resolveCommand;
|
|
144
|
+
private initialize;
|
|
145
|
+
private getConnection;
|
|
146
|
+
private handleNotification;
|
|
147
|
+
private handleServerRequest;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
type CodexOneShotTransportFactory = (command: string) => JsonRpcTransport;
|
|
151
|
+
type CodexModelOption = {
|
|
152
|
+
id: string;
|
|
153
|
+
model: string;
|
|
154
|
+
displayName: string;
|
|
155
|
+
description: string;
|
|
156
|
+
hidden: boolean;
|
|
157
|
+
inputModalities: Model["inputModalities"];
|
|
158
|
+
defaultServiceTier: string | null;
|
|
159
|
+
isDefault: boolean;
|
|
160
|
+
};
|
|
161
|
+
type CodexOneShotClientOptions = {
|
|
162
|
+
command?: string;
|
|
163
|
+
/** Identity sent as `clientInfo.name`. Defaults to "agent-kit". */
|
|
164
|
+
clientName?: string;
|
|
165
|
+
clientTitle?: string;
|
|
166
|
+
clientVersion?: string;
|
|
167
|
+
/** serviceName for the worker thread. Defaults to "agent-kit". */
|
|
168
|
+
serviceName?: string;
|
|
169
|
+
/** Working dir for the persistent worker thread (keeps it out of any repo). */
|
|
170
|
+
workspaceDir?: string;
|
|
171
|
+
/** Human-readable name set on the worker thread. */
|
|
172
|
+
workerThreadName?: string;
|
|
173
|
+
/** Per-thread Codex config overlay applied to the worker thread. */
|
|
174
|
+
threadConfig?: Record<string, unknown>;
|
|
175
|
+
requestTimeoutMs?: number;
|
|
176
|
+
turnTimeoutMs?: number;
|
|
177
|
+
env?: NodeJS.ProcessEnv;
|
|
178
|
+
transportFactory?: CodexOneShotTransportFactory;
|
|
179
|
+
logger?: Logger;
|
|
180
|
+
};
|
|
181
|
+
type CodexOneShotRequest = {
|
|
182
|
+
/** The user-message text (the caller's prompt) for this turn. */
|
|
183
|
+
prompt: string;
|
|
184
|
+
/** Local image file paths fed as `localImage` inputs (not inlined as base64). */
|
|
185
|
+
imagePaths?: readonly string[];
|
|
186
|
+
/** JSON Schema constraining the final assistant message (`outputSchema`). */
|
|
187
|
+
outputSchema?: unknown;
|
|
188
|
+
/** Base instructions for the worker thread (set once; changing it re-creates
|
|
189
|
+
* the worker thread). */
|
|
190
|
+
baseInstructions?: string;
|
|
191
|
+
/** Reasoning effort for the turn. Defaults to "low". */
|
|
192
|
+
effort?: string;
|
|
193
|
+
model?: string | null;
|
|
194
|
+
/** Model provider (ThreadStartParams.modelProvider) for the worker thread.
|
|
195
|
+
* Omit for the Codex default. Part of the worker-thread cache key. */
|
|
196
|
+
modelProvider?: string | null;
|
|
197
|
+
abortSignal?: AbortSignal;
|
|
198
|
+
};
|
|
199
|
+
type CodexOneShotResponse = {
|
|
200
|
+
/** The raw assistant message text. Caller parses/validates against its schema. */
|
|
201
|
+
rawText: string;
|
|
202
|
+
threadId: string;
|
|
203
|
+
turnId: string;
|
|
204
|
+
userAgent: string;
|
|
205
|
+
model: string;
|
|
206
|
+
modelProvider: string;
|
|
207
|
+
serviceTier: string | null;
|
|
208
|
+
tokenUsage: NormalizedTokenUsage | null;
|
|
209
|
+
};
|
|
210
|
+
declare class CodexOneShotClient {
|
|
211
|
+
private readonly options;
|
|
212
|
+
private readonly requestTimeoutMs;
|
|
213
|
+
private readonly turnTimeoutMs;
|
|
214
|
+
private readonly logger;
|
|
215
|
+
private readonly transportFactory;
|
|
216
|
+
private resolvedCommand;
|
|
217
|
+
private connection;
|
|
218
|
+
private initializeResponse;
|
|
219
|
+
private pendingTurn;
|
|
220
|
+
private workerThread;
|
|
221
|
+
private queue;
|
|
222
|
+
constructor(options?: CodexOneShotClientOptions);
|
|
223
|
+
/** Run one structured-output turn. Calls are serialized — only one turn is in
|
|
224
|
+
* flight at a time against the shared worker thread. */
|
|
225
|
+
run(request: CodexOneShotRequest): Promise<CodexOneShotResponse>;
|
|
226
|
+
private runInner;
|
|
227
|
+
listModels(input?: {
|
|
228
|
+
includeHidden?: boolean;
|
|
229
|
+
}): Promise<CodexModelOption[]>;
|
|
230
|
+
close(): Promise<void>;
|
|
231
|
+
private getWorkerThread;
|
|
232
|
+
private rollbackWorkerThread;
|
|
233
|
+
private prepareWorkspace;
|
|
234
|
+
private clearThreadGitInfo;
|
|
235
|
+
private setWorkerThreadName;
|
|
236
|
+
private resolveCommand;
|
|
237
|
+
private initialize;
|
|
238
|
+
private getConnection;
|
|
239
|
+
private waitForTurn;
|
|
240
|
+
private handleNotification;
|
|
241
|
+
private handleItemCompleted;
|
|
242
|
+
private handleRawResponseItemCompleted;
|
|
243
|
+
private handleTurnCompleted;
|
|
244
|
+
private handleThreadTokenUsageUpdated;
|
|
245
|
+
private handleServerRequest;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Generic "disable coding-agent scaffolding" config overlay. Hosts spread this
|
|
250
|
+
* into `CodexStartThreadOptions.config` (optionally merging their own keys).
|
|
251
|
+
*/
|
|
252
|
+
declare const DISABLE_CODING_AGENT_THREAD_CONFIG: Record<string, unknown>;
|
|
253
|
+
|
|
254
|
+
declare const CODEX_NOTIFICATION_METHODS: {
|
|
255
|
+
readonly agentMessageDelta: "item/agentMessage/delta";
|
|
256
|
+
readonly reasoningDelta: "item/reasoning/delta";
|
|
257
|
+
readonly reasoningTextDelta: "item/reasoning/textDelta";
|
|
258
|
+
readonly itemStarted: "item/started";
|
|
259
|
+
readonly itemCompleted: "item/completed";
|
|
260
|
+
readonly turnStarted: "turn/started";
|
|
261
|
+
readonly turnCompleted: "turn/completed";
|
|
262
|
+
readonly tokenUsage: "thread/tokenUsage/updated";
|
|
263
|
+
readonly threadSettings: "thread/settings/updated";
|
|
264
|
+
readonly modelRerouted: "model/rerouted";
|
|
265
|
+
readonly error: "error";
|
|
266
|
+
};
|
|
267
|
+
/** Codex approval ServerRequest methods, normalized into `approval_request`. */
|
|
268
|
+
declare const CODEX_APPROVAL_METHODS: Set<string>;
|
|
269
|
+
/** The dynamic-tool ServerRequest method Codex routes tool invocations on. */
|
|
270
|
+
declare const CODEX_TOOL_CALL_METHOD = "item/tool/call";
|
|
271
|
+
/** Map a Codex `ThreadTokenUsage` (its `last` breakdown) to the neutral shape. */
|
|
272
|
+
declare function normalizeTokenUsage(usage: ThreadTokenUsage): NormalizedTokenUsage;
|
|
273
|
+
/**
|
|
274
|
+
* Build a `NormalizedToolCall` from a tool-ish `ThreadItem`. Returns `null` for
|
|
275
|
+
* non-tool items. `kind` defaults to `inferToolKind(name)` unless the item's
|
|
276
|
+
* native shape already classifies it (a command execution is always "command").
|
|
277
|
+
*/
|
|
278
|
+
declare function normalizeThreadItemToolCall(item: ThreadItem): NormalizedToolCall | null;
|
|
279
|
+
/**
|
|
280
|
+
* Build a `NormalizedToolCall` from a `DynamicToolCallParams` (the ServerRequest
|
|
281
|
+
* the adapter must answer). `kind` defaults to `inferToolKind(name)`.
|
|
282
|
+
*/
|
|
283
|
+
declare function normalizeDynamicToolCall(params: DynamicToolCallParams): NormalizedToolCall;
|
|
284
|
+
/** Normalize a Codex approval ServerRequest into a neutral approval request. */
|
|
285
|
+
declare function normalizeApprovalRequest(method: string, params: unknown, approvalId: string): NormalizedApprovalRequest;
|
|
286
|
+
declare function normalizeThreadSettings(notification: ThreadSettingsUpdatedNotification): NormalizedThreadSettings;
|
|
287
|
+
/**
|
|
288
|
+
* Normalize one native Codex notification into a `NormalizedThreadEvent`.
|
|
289
|
+
* Returns `null` when the method/payload yields no neutral event (an unknown
|
|
290
|
+
* method, or an `item/*` carrying a non-streamable item).
|
|
291
|
+
*
|
|
292
|
+
* `item/started` for a tool-ish item becomes a `tool_call`; the matching
|
|
293
|
+
* `item/completed` becomes a `tool_call_update` (so the controller correlates
|
|
294
|
+
* them by id and merges via `mergeToolCall`). An `agentMessage` `item/completed`
|
|
295
|
+
* becomes a final `agent_message`.
|
|
296
|
+
*/
|
|
297
|
+
declare function normalizeNotification(method: string, params: unknown): NormalizedThreadEvent | null;
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Result of a tool `dispatch`. The agent only ever sees text or image content,
|
|
301
|
+
* so a structured host error is collapsed to a plain string at this boundary.
|
|
302
|
+
*/
|
|
303
|
+
type ToolDispatchResult = {
|
|
304
|
+
ok: true;
|
|
305
|
+
data: unknown;
|
|
306
|
+
} | {
|
|
307
|
+
ok: true;
|
|
308
|
+
contentItems: DynamicToolCallOutputContentItem[];
|
|
309
|
+
} | {
|
|
310
|
+
ok: false;
|
|
311
|
+
error: string;
|
|
312
|
+
};
|
|
313
|
+
/**
|
|
314
|
+
* One chat tool. The single audit unit: description (what the agent reads),
|
|
315
|
+
* `argsSchema` (what the agent must satisfy — validated before dispatch), and
|
|
316
|
+
* `dispatch` (the host-injected body it resolves to).
|
|
317
|
+
*/
|
|
318
|
+
type ToolSpec<TArgs> = {
|
|
319
|
+
/** Namespace this tool lives under; matched against `DynamicToolCallParams.namespace`. */
|
|
320
|
+
namespace: string;
|
|
321
|
+
/** snake_case agent-facing name, e.g. "library_list". */
|
|
322
|
+
name: string;
|
|
323
|
+
/** Agent-readable, terse. Shown verbatim to Codex. */
|
|
324
|
+
description: string;
|
|
325
|
+
/** zod schema for the tool arguments; also the source of `inputSchema`. */
|
|
326
|
+
argsSchema: z.ZodType<TArgs>;
|
|
327
|
+
/**
|
|
328
|
+
* Behaviour hints surfaced to the agent / approval UI. Optional per tool;
|
|
329
|
+
* omit (rather than set `undefined`) when not applicable —
|
|
330
|
+
* `exactOptionalPropertyTypes` is on.
|
|
331
|
+
*/
|
|
332
|
+
annotations?: {
|
|
333
|
+
destructiveHint?: boolean;
|
|
334
|
+
readOnlyHint?: boolean;
|
|
335
|
+
idempotentHint?: boolean;
|
|
336
|
+
};
|
|
337
|
+
/**
|
|
338
|
+
* The host-injected dispatch this tool resolves to. Receives the zod-validated
|
|
339
|
+
* args (typed as `TArgs`) plus the calling thread id.
|
|
340
|
+
*/
|
|
341
|
+
dispatch: (args: TArgs, ctx: {
|
|
342
|
+
threadId: string;
|
|
343
|
+
}) => Promise<ToolDispatchResult>;
|
|
344
|
+
};
|
|
345
|
+
/**
|
|
346
|
+
* Identity helper that preserves `TArgs` inference at each call site, so a
|
|
347
|
+
* tool's `dispatch` body is fully type-checked against its own `argsSchema`
|
|
348
|
+
* without any cast.
|
|
349
|
+
*/
|
|
350
|
+
declare function defineTool<TArgs>(spec: ToolSpec<TArgs>): ToolSpec<TArgs>;
|
|
351
|
+
/**
|
|
352
|
+
* A `ToolSpec` with its argument type erased — the shape a heterogeneous catalog
|
|
353
|
+
* holds. `defineTool(...)`'s typed result is assignable to this, so a host writes
|
|
354
|
+
* `[defineTool(a), defineTool(b)]` and passes it straight to `buildToolCatalog` /
|
|
355
|
+
* `dispatchToolCall`. Args are validated at runtime, so the erasure is safe.
|
|
356
|
+
*/
|
|
357
|
+
type AnyToolSpec = ToolSpec<any>;
|
|
358
|
+
/**
|
|
359
|
+
* Convert a `ToolSpec` into the protocol `DynamicToolSpec` registered with Codex
|
|
360
|
+
* at `thread/start`. The `inputSchema` is derived from the tool's zod
|
|
361
|
+
* `argsSchema` via zod v4's `z.toJSONSchema()` (JSON Schema draft 2020-12).
|
|
362
|
+
*/
|
|
363
|
+
declare function toDynamicToolSpec(spec: AnyToolSpec): DynamicToolSpec;
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Build the `DynamicToolSpec[]` registered with Codex at `thread/start`. Pure
|
|
367
|
+
* projection of the catalog — an empty catalog yields an empty spec list.
|
|
368
|
+
*/
|
|
369
|
+
declare function buildToolCatalog(catalog: ReadonlyArray<AnyToolSpec>): DynamicToolSpec[];
|
|
370
|
+
/**
|
|
371
|
+
* Route an incoming `DynamicToolCallParams` to its catalog entry and run it.
|
|
372
|
+
* Always resolves — never throws — so a malformed or unknown call comes back as
|
|
373
|
+
* a `success: false` response the agent can recover from.
|
|
374
|
+
*/
|
|
375
|
+
declare function dispatchToolCall(params: DynamicToolCallParams, catalog: ReadonlyArray<AnyToolSpec>): Promise<DynamicToolCallResponse>;
|
|
376
|
+
|
|
377
|
+
/** The backend the controller drives. Codex (`CodexThreadClient`) and ACP
|
|
378
|
+
* (`AcpAgentClient`) both implement the non-generic `AgentBackend`; the
|
|
379
|
+
* controller builds NEUTRAL thread/turn options, so any backend drops in
|
|
380
|
+
* identically with no per-backend branching. Retained as an alias to
|
|
381
|
+
* `AgentBackend` so existing hosts that name `ChatBackend` keep compiling. */
|
|
382
|
+
type ChatBackend = AgentBackend;
|
|
383
|
+
/** Builds the per-thread system prompt (base + host guidance). Injected as
|
|
384
|
+
* `baseInstructions` at thread/start. Receives the frozen settings snapshot and
|
|
385
|
+
* the thread's anchor; the controller never inspects `TSettings`. */
|
|
386
|
+
type ChatSystemPromptBuilder<TSettings = unknown> = (input: {
|
|
387
|
+
settings: TSettings;
|
|
388
|
+
anchorId: string | null;
|
|
389
|
+
}) => string;
|
|
390
|
+
/**
|
|
391
|
+
* The neutral event union the controller broadcasts. The host maps these to its
|
|
392
|
+
* own IPC. Surface-agnostic: a library-chat host and a sizzle-chat host map the
|
|
393
|
+
* same union. Generalizes PwrSnap's six typed `events:*Chat:*` channels.
|
|
394
|
+
*/
|
|
395
|
+
type ChatControllerEvent = {
|
|
396
|
+
type: "thread_updated";
|
|
397
|
+
thread: NormalizedThreadView;
|
|
398
|
+
} | {
|
|
399
|
+
type: "stream_delta";
|
|
400
|
+
threadId: string;
|
|
401
|
+
turnId: string;
|
|
402
|
+
messageId: string;
|
|
403
|
+
delta: string;
|
|
404
|
+
} | {
|
|
405
|
+
type: "tool_call";
|
|
406
|
+
threadId: string;
|
|
407
|
+
turnId: string;
|
|
408
|
+
toolCall: NormalizedToolCall;
|
|
409
|
+
} | {
|
|
410
|
+
type: "message_committed";
|
|
411
|
+
threadId: string;
|
|
412
|
+
message: NormalizedMessage;
|
|
413
|
+
} | {
|
|
414
|
+
type: "turn_interrupted";
|
|
415
|
+
threadId: string;
|
|
416
|
+
turnId: string;
|
|
417
|
+
} | {
|
|
418
|
+
type: "approval_requested";
|
|
419
|
+
threadId: string;
|
|
420
|
+
turnId: string;
|
|
421
|
+
approval: NormalizedApprovalRequest;
|
|
422
|
+
};
|
|
423
|
+
/** Re-broadcasts the controller's neutral event stream to the host's UI. */
|
|
424
|
+
type ChatBroadcast = (event: ChatControllerEvent) => void;
|
|
425
|
+
/** Friendly present-tense labels for tool activity chips, keyed by tool name. */
|
|
426
|
+
type ToolLabelMap = Record<string, string>;
|
|
427
|
+
type ChatThreadControllerDeps<TSettings = unknown> = {
|
|
428
|
+
/** The shared backend (Codex or ACP). */
|
|
429
|
+
client: ChatBackend;
|
|
430
|
+
/** Host persistence: thread index + per-turn journal + usage accounting. */
|
|
431
|
+
store: ThreadStore;
|
|
432
|
+
/** Reads the current host settings snapshot (frozen per turn). */
|
|
433
|
+
readSettings: () => Promise<TSettings>;
|
|
434
|
+
/** Re-broadcasts neutral controller events to the host UI. */
|
|
435
|
+
broadcast: ChatBroadcast;
|
|
436
|
+
/** Builds the per-thread system prompt. */
|
|
437
|
+
buildSystemPrompt: ChatSystemPromptBuilder<TSettings>;
|
|
438
|
+
/** Per-turn runtime context (L3), sent as a leading turn item framed as
|
|
439
|
+
* system-generated — never folded into the user's message. Receives the
|
|
440
|
+
* turn's anchor. Omit for no per-turn context. */
|
|
441
|
+
buildTurnContext?: (anchor: string) => string;
|
|
442
|
+
/** DynamicToolSpec[] registered on every thread/start. */
|
|
443
|
+
catalog?: DynamicToolSpec[];
|
|
444
|
+
/** Routes an incoming tool call to the host's tools. Defaults to a no-tools
|
|
445
|
+
* responder when omitted. */
|
|
446
|
+
dispatchToolCall?: (params: DynamicToolCallParams) => Promise<DynamicToolCallResponse>;
|
|
447
|
+
/** Friendly chip labels for tool activity. */
|
|
448
|
+
toolLabels?: ToolLabelMap;
|
|
449
|
+
/** Default-Access policy applied to every chat thread. */
|
|
450
|
+
approvalPolicy?: string;
|
|
451
|
+
sandbox?: string;
|
|
452
|
+
/** Default serviceName for thread/start. */
|
|
453
|
+
serviceName?: string;
|
|
454
|
+
/** Per-thread Codex config overlay applied on every thread/start. */
|
|
455
|
+
threadConfig?: Record<string, unknown>;
|
|
456
|
+
/** Thread environments. `[]` disables exec-environment access. */
|
|
457
|
+
threadEnvironments?: unknown[];
|
|
458
|
+
/** Reasoning effort for turns. Defaults to "medium". */
|
|
459
|
+
effort?: string;
|
|
460
|
+
/** Default model id for thread/start (host's per-surface default). Omit for Codex default. */
|
|
461
|
+
model?: string;
|
|
462
|
+
/** Default model provider for thread/start — the "provider" a host picks when
|
|
463
|
+
* more than one is configured. Omit for Codex default. */
|
|
464
|
+
modelProvider?: string;
|
|
465
|
+
logger?: Logger;
|
|
466
|
+
/** Injectable clock for tests. */
|
|
467
|
+
now?: () => number;
|
|
468
|
+
};
|
|
469
|
+
declare class ChatThreadController<TSettings = unknown> {
|
|
470
|
+
private readonly deps;
|
|
471
|
+
private readonly logger;
|
|
472
|
+
private readonly turns;
|
|
473
|
+
private readonly pendingApprovals;
|
|
474
|
+
/** Per-thread recent turn timestamps for rate limiting. */
|
|
475
|
+
private readonly turnTimestamps;
|
|
476
|
+
private readonly threadModels;
|
|
477
|
+
private wired;
|
|
478
|
+
constructor(deps: ChatThreadControllerDeps<TSettings>);
|
|
479
|
+
/** Wire the shared backend's subscription hooks ONCE. Idempotent. */
|
|
480
|
+
wire(): void;
|
|
481
|
+
private now;
|
|
482
|
+
createThread(opts?: {
|
|
483
|
+
name?: string;
|
|
484
|
+
anchorId?: string | null;
|
|
485
|
+
}): Promise<NormalizedThreadView>;
|
|
486
|
+
listThreads(opts?: {
|
|
487
|
+
includeArchived?: boolean;
|
|
488
|
+
anchorId?: string | null;
|
|
489
|
+
}): Promise<NormalizedThreadView[]>;
|
|
490
|
+
rename(threadId: string, name: string): Promise<NormalizedThreadView>;
|
|
491
|
+
archive(threadId: string, archived: boolean): Promise<NormalizedThreadView>;
|
|
492
|
+
sendMessage(input: {
|
|
493
|
+
threadId: string;
|
|
494
|
+
text: string;
|
|
495
|
+
anchorId?: string | null;
|
|
496
|
+
/** Local image file paths to attach to this turn. Forwarded neutrally as
|
|
497
|
+
* `AgentTurnInput.imagePaths`; the backend maps to its native attachment
|
|
498
|
+
* (Codex `localImage`, ACP `image` blocks). */
|
|
499
|
+
imagePaths?: readonly string[];
|
|
500
|
+
}): Promise<{
|
|
501
|
+
turnId: string;
|
|
502
|
+
}>;
|
|
503
|
+
getHistory(threadId: string): Promise<NormalizedMessage[]>;
|
|
504
|
+
interrupt(threadId: string): Promise<void>;
|
|
505
|
+
resolveApproval(input: {
|
|
506
|
+
threadId: string;
|
|
507
|
+
turnId: string;
|
|
508
|
+
approvalId: string;
|
|
509
|
+
decision: NormalizedApprovalDecision;
|
|
510
|
+
}): Promise<void>;
|
|
511
|
+
private onBackendEvent;
|
|
512
|
+
private onDelta;
|
|
513
|
+
private onTurnCompleted;
|
|
514
|
+
private onTokenUsage;
|
|
515
|
+
private onToolCall;
|
|
516
|
+
private onApprovalRequest;
|
|
517
|
+
private finalizeAssistant;
|
|
518
|
+
private recordUsage;
|
|
519
|
+
private commitMessage;
|
|
520
|
+
private readJournalMessages;
|
|
521
|
+
private currentAnchor;
|
|
522
|
+
private enforceRateLimit;
|
|
523
|
+
private recordTurn;
|
|
524
|
+
private broadcastThreadStatus;
|
|
525
|
+
private toView;
|
|
526
|
+
private defaultName;
|
|
527
|
+
private randomId;
|
|
528
|
+
}
|
|
529
|
+
/** Local-timezone `YYYY-MM-DD` stamp (NOT `toISOString()`, which is UTC). */
|
|
530
|
+
declare function localDateStamp(d: Date): string;
|
|
531
|
+
|
|
532
|
+
export { type AnyToolSpec, CODEX_APPROVAL_METHODS, CODEX_NOTIFICATION_METHODS, CODEX_TOOL_CALL_METHOD, type ChatBackend, type ChatBroadcast, type ChatControllerEvent, type ChatSystemPromptBuilder, ChatThreadController, type ChatThreadControllerDeps, type CodexApprovalHandler, type CodexModelOption, CodexOneShotClient, type CodexOneShotClientOptions, type CodexOneShotRequest, type CodexOneShotResponse, type CodexOneShotTransportFactory, type CodexStartThreadOptions, type CodexStartTurnOptions, CodexThreadClient, type CodexThreadClientOptions, type CodexThreadClientTransportFactory, type CodexToolCallHandler, DISABLE_CODING_AGENT_THREAD_CONFIG, type StartThreadResult, type ToolDispatchResult, type ToolLabelMap, type ToolSpec, type Unsubscribe, buildToolCatalog, defineTool, dispatchToolCall, localDateStamp, normalizeApprovalRequest, normalizeDynamicToolCall, normalizeNotification, normalizeThreadItemToolCall, normalizeThreadSettings, normalizeTokenUsage, toDynamicToolSpec };
|