@coder/ai-sdk-agent 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 +202 -0
- package/README.md +188 -0
- package/dist/index.d.ts +526 -0
- package/dist/index.js +930 -0
- package/dist/index.js.map +1 -0
- package/package.json +83 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
import { ToolSet, Agent, SystemModelMessage, ToolChoice, StopCondition, ToolLoopAgent } from 'ai';
|
|
2
|
+
import { LanguageModelV3, LanguageModelV3CallOptions, LanguageModelV3StreamResult, LanguageModelV3GenerateResult, LanguageModelV3StreamPart, LanguageModelV3Prompt } from '@ai-sdk/provider';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Wire types for Coder's experimental `chatd` chat API
|
|
6
|
+
* (`/api/experimental/chats`). These mirror the Go types in
|
|
7
|
+
* `coder/coder`'s `codersdk/chats.go` (JSON shapes), restricted to the subset
|
|
8
|
+
* this client uses. Field names use snake_case to match the wire format.
|
|
9
|
+
*
|
|
10
|
+
* NOTE: The chatd API is experimental and may change between Coder releases.
|
|
11
|
+
*/
|
|
12
|
+
type ChatInputPartType = "text" | "file" | "file-reference";
|
|
13
|
+
interface ChatInputPart {
|
|
14
|
+
type: ChatInputPartType;
|
|
15
|
+
text?: string;
|
|
16
|
+
file_id?: string;
|
|
17
|
+
file_name?: string;
|
|
18
|
+
start_line?: number;
|
|
19
|
+
end_line?: number;
|
|
20
|
+
content?: string;
|
|
21
|
+
}
|
|
22
|
+
type ChatClientType = "ui" | "api";
|
|
23
|
+
type ChatPlanMode = "" | "plan";
|
|
24
|
+
type ChatBusyBehavior = "queue" | "interrupt";
|
|
25
|
+
/**
|
|
26
|
+
* A client-executed ("dynamic") tool definition. chatd never executes these;
|
|
27
|
+
* when the model calls one, the chat enters `requires_action` and the client
|
|
28
|
+
* must execute it and submit results via {@link SubmitToolResultsRequest}.
|
|
29
|
+
*
|
|
30
|
+
* NOTE: the JSON key is `input_schema` (snake_case), per chatd.
|
|
31
|
+
*/
|
|
32
|
+
interface DynamicTool {
|
|
33
|
+
name: string;
|
|
34
|
+
description?: string;
|
|
35
|
+
/** A JSON Schema object describing the tool input. */
|
|
36
|
+
input_schema: unknown;
|
|
37
|
+
}
|
|
38
|
+
interface CreateChatRequest {
|
|
39
|
+
organization_id: string;
|
|
40
|
+
content: ChatInputPart[];
|
|
41
|
+
system_prompt?: string;
|
|
42
|
+
workspace_id?: string;
|
|
43
|
+
model_config_id?: string;
|
|
44
|
+
mcp_server_ids?: string[];
|
|
45
|
+
labels?: Record<string, string>;
|
|
46
|
+
unsafe_dynamic_tools?: DynamicTool[];
|
|
47
|
+
plan_mode?: ChatPlanMode;
|
|
48
|
+
client_type?: ChatClientType;
|
|
49
|
+
}
|
|
50
|
+
interface CreateChatMessageRequest {
|
|
51
|
+
content: ChatInputPart[];
|
|
52
|
+
model_config_id?: string;
|
|
53
|
+
mcp_server_ids?: string[];
|
|
54
|
+
busy_behavior?: ChatBusyBehavior;
|
|
55
|
+
plan_mode?: ChatPlanMode;
|
|
56
|
+
}
|
|
57
|
+
/** Result of a single client-executed tool call. */
|
|
58
|
+
interface ToolResult {
|
|
59
|
+
tool_call_id: string;
|
|
60
|
+
/** JSON-serializable tool output. */
|
|
61
|
+
output: unknown;
|
|
62
|
+
is_error?: boolean;
|
|
63
|
+
}
|
|
64
|
+
interface SubmitToolResultsRequest {
|
|
65
|
+
results: ToolResult[];
|
|
66
|
+
}
|
|
67
|
+
interface UpdateChatRequest {
|
|
68
|
+
title?: string;
|
|
69
|
+
archived?: boolean;
|
|
70
|
+
}
|
|
71
|
+
type ChatStatus = "waiting" | "pending" | "running" | "paused" | "completed" | "error" | "requires_action" | "interrupting";
|
|
72
|
+
type ChatMessageRole = "system" | "user" | "assistant" | "tool";
|
|
73
|
+
type ChatMessagePartType = "text" | "reasoning" | "tool-call" | "tool-result" | "source" | "file" | "file-reference" | "context-file" | "skill";
|
|
74
|
+
/**
|
|
75
|
+
* A part of a chat message. chatd models this as a single flat struct with a
|
|
76
|
+
* `type` discriminator and many optional fields (see `codersdk.ChatMessagePart`),
|
|
77
|
+
* so we mirror that shape rather than a strict discriminated union.
|
|
78
|
+
*/
|
|
79
|
+
interface ChatMessagePart {
|
|
80
|
+
type: ChatMessagePartType;
|
|
81
|
+
text?: string;
|
|
82
|
+
signature?: string;
|
|
83
|
+
tool_call_id?: string;
|
|
84
|
+
tool_name?: string;
|
|
85
|
+
mcp_server_config_id?: string | null;
|
|
86
|
+
/** tool-call: complete arguments (JSON value). */
|
|
87
|
+
args?: unknown;
|
|
88
|
+
/** tool-call: incremental argument text chunk during streaming. */
|
|
89
|
+
args_delta?: string;
|
|
90
|
+
parsed_commands?: string[][];
|
|
91
|
+
/** tool-result: complete result (JSON value). */
|
|
92
|
+
result?: unknown;
|
|
93
|
+
/** tool-result: incremental result text chunk during streaming. */
|
|
94
|
+
result_delta?: string;
|
|
95
|
+
result_reset?: boolean;
|
|
96
|
+
is_error?: boolean;
|
|
97
|
+
is_media?: boolean;
|
|
98
|
+
provider_executed?: boolean;
|
|
99
|
+
created_at?: string;
|
|
100
|
+
completed_at?: string;
|
|
101
|
+
source_id?: string;
|
|
102
|
+
url?: string;
|
|
103
|
+
title?: string;
|
|
104
|
+
media_type?: string;
|
|
105
|
+
name?: string;
|
|
106
|
+
file_id?: string | null;
|
|
107
|
+
file_name?: string;
|
|
108
|
+
start_line?: number;
|
|
109
|
+
end_line?: number;
|
|
110
|
+
content?: string;
|
|
111
|
+
skill_name?: string;
|
|
112
|
+
skill_description?: string;
|
|
113
|
+
}
|
|
114
|
+
interface ChatMessageUsage {
|
|
115
|
+
input_tokens?: number;
|
|
116
|
+
output_tokens?: number;
|
|
117
|
+
total_tokens?: number;
|
|
118
|
+
reasoning_tokens?: number;
|
|
119
|
+
cache_creation_tokens?: number;
|
|
120
|
+
cache_read_tokens?: number;
|
|
121
|
+
context_limit?: number;
|
|
122
|
+
}
|
|
123
|
+
interface ChatMessage {
|
|
124
|
+
id: number;
|
|
125
|
+
chat_id: string;
|
|
126
|
+
created_by?: string;
|
|
127
|
+
model_config_id?: string;
|
|
128
|
+
created_at: string;
|
|
129
|
+
role: ChatMessageRole;
|
|
130
|
+
content?: ChatMessagePart[];
|
|
131
|
+
usage?: ChatMessageUsage;
|
|
132
|
+
}
|
|
133
|
+
interface ChatErrorPayload {
|
|
134
|
+
message: string;
|
|
135
|
+
detail?: string;
|
|
136
|
+
kind?: string;
|
|
137
|
+
provider?: string;
|
|
138
|
+
retryable?: boolean;
|
|
139
|
+
status_code?: number;
|
|
140
|
+
}
|
|
141
|
+
interface Chat {
|
|
142
|
+
id: string;
|
|
143
|
+
organization_id: string;
|
|
144
|
+
owner_id: string;
|
|
145
|
+
owner_username?: string;
|
|
146
|
+
workspace_id?: string | null;
|
|
147
|
+
agent_id?: string | null;
|
|
148
|
+
parent_chat_id?: string | null;
|
|
149
|
+
root_chat_id?: string | null;
|
|
150
|
+
last_model_config_id?: string;
|
|
151
|
+
title: string;
|
|
152
|
+
status: ChatStatus;
|
|
153
|
+
plan_mode?: ChatPlanMode;
|
|
154
|
+
last_error?: ChatErrorPayload | null;
|
|
155
|
+
created_at: string;
|
|
156
|
+
updated_at: string;
|
|
157
|
+
archived: boolean;
|
|
158
|
+
mcp_server_ids?: string[];
|
|
159
|
+
client_type?: ChatClientType;
|
|
160
|
+
}
|
|
161
|
+
interface ChatQueuedMessage {
|
|
162
|
+
id: number;
|
|
163
|
+
chat_id: string;
|
|
164
|
+
content: ChatMessagePart[];
|
|
165
|
+
created_at: string;
|
|
166
|
+
}
|
|
167
|
+
interface CreateChatMessageResponse {
|
|
168
|
+
message?: ChatMessage;
|
|
169
|
+
queued_message?: ChatQueuedMessage;
|
|
170
|
+
queued: boolean;
|
|
171
|
+
warnings?: string[];
|
|
172
|
+
}
|
|
173
|
+
interface ChatMessagesResponse {
|
|
174
|
+
messages: ChatMessage[];
|
|
175
|
+
queued_messages: ChatQueuedMessage[];
|
|
176
|
+
has_more: boolean;
|
|
177
|
+
}
|
|
178
|
+
interface ChatModelConfig {
|
|
179
|
+
id: string;
|
|
180
|
+
provider: string;
|
|
181
|
+
ai_provider_id?: string;
|
|
182
|
+
model: string;
|
|
183
|
+
display_name: string;
|
|
184
|
+
enabled?: boolean;
|
|
185
|
+
is_default?: boolean;
|
|
186
|
+
context_limit?: number;
|
|
187
|
+
compression_threshold?: number;
|
|
188
|
+
}
|
|
189
|
+
type ChatStreamEventType = "message_part" | "message" | "status" | "error" | "queue_update" | "retry" | "action_required" | "preview_reset" | "history_reset";
|
|
190
|
+
interface ChatStreamMessagePart {
|
|
191
|
+
role?: ChatMessageRole;
|
|
192
|
+
part: ChatMessagePart;
|
|
193
|
+
history_version?: number;
|
|
194
|
+
generation_attempt?: number;
|
|
195
|
+
seq?: number;
|
|
196
|
+
}
|
|
197
|
+
interface ChatStreamStatus {
|
|
198
|
+
status: ChatStatus;
|
|
199
|
+
}
|
|
200
|
+
interface ChatStreamToolCall {
|
|
201
|
+
tool_call_id: string;
|
|
202
|
+
tool_name: string;
|
|
203
|
+
/** JSON string of the tool-call arguments. */
|
|
204
|
+
args: string;
|
|
205
|
+
}
|
|
206
|
+
interface ChatStreamActionRequired {
|
|
207
|
+
tool_calls: ChatStreamToolCall[];
|
|
208
|
+
}
|
|
209
|
+
interface ChatStreamRetry {
|
|
210
|
+
attempt: number;
|
|
211
|
+
delay_ms: number;
|
|
212
|
+
error: string;
|
|
213
|
+
kind?: string;
|
|
214
|
+
provider?: string;
|
|
215
|
+
status_code?: number;
|
|
216
|
+
retrying_at: string;
|
|
217
|
+
}
|
|
218
|
+
interface ChatStreamEvent {
|
|
219
|
+
type: ChatStreamEventType;
|
|
220
|
+
chat_id: string;
|
|
221
|
+
message?: ChatMessage;
|
|
222
|
+
message_part?: ChatStreamMessagePart;
|
|
223
|
+
status?: ChatStreamStatus;
|
|
224
|
+
error?: ChatErrorPayload;
|
|
225
|
+
retry?: ChatStreamRetry;
|
|
226
|
+
queued_messages?: ChatQueuedMessage[];
|
|
227
|
+
action_required?: ChatStreamActionRequired;
|
|
228
|
+
}
|
|
229
|
+
/** Terminal statuses: the chat has stopped generating for this turn. */
|
|
230
|
+
declare const TERMINAL_STATUSES: ReadonlySet<ChatStatus>;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* A minimal WebSocket factory abstraction so the stream reader can run on
|
|
234
|
+
* Node (via the `ws` package, with header auth) or in environments that
|
|
235
|
+
* provide a global `WebSocket` (browsers, where auth must go in the query
|
|
236
|
+
* string). Node is the default target.
|
|
237
|
+
*/
|
|
238
|
+
interface WebSocketLike {
|
|
239
|
+
send(data: string): void;
|
|
240
|
+
close(code?: number): void;
|
|
241
|
+
addEventListener(type: "open", cb: () => void): void;
|
|
242
|
+
addEventListener(type: "message", cb: (ev: {
|
|
243
|
+
data: unknown;
|
|
244
|
+
}) => void): void;
|
|
245
|
+
addEventListener(type: "error", cb: (ev: unknown) => void): void;
|
|
246
|
+
addEventListener(type: "close", cb: (ev: {
|
|
247
|
+
code?: number;
|
|
248
|
+
reason?: string;
|
|
249
|
+
}) => void): void;
|
|
250
|
+
removeEventListener(type: "open", cb: () => void): void;
|
|
251
|
+
removeEventListener(type: "message", cb: (ev: {
|
|
252
|
+
data: unknown;
|
|
253
|
+
}) => void): void;
|
|
254
|
+
removeEventListener(type: "error", cb: (ev: unknown) => void): void;
|
|
255
|
+
removeEventListener(type: "close", cb: (ev: {
|
|
256
|
+
code?: number;
|
|
257
|
+
reason?: string;
|
|
258
|
+
}) => void): void;
|
|
259
|
+
}
|
|
260
|
+
type WebSocketFactory = (url: string, protocols: {
|
|
261
|
+
headers: Record<string, string>;
|
|
262
|
+
}) => WebSocketLike;
|
|
263
|
+
interface StreamChatEventsOptions {
|
|
264
|
+
baseUrl: string;
|
|
265
|
+
token: string;
|
|
266
|
+
chatId: string;
|
|
267
|
+
/** Only stream events for messages with id greater than this. */
|
|
268
|
+
afterId?: number;
|
|
269
|
+
signal?: AbortSignal;
|
|
270
|
+
webSocketFactory?: WebSocketFactory;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Opens the chatd `/stream` WebSocket and yields decoded {@link ChatStreamEvent}s
|
|
274
|
+
* as an async iterable. Each text frame from chatd is a JSON array of events;
|
|
275
|
+
* we flatten them into a single stream.
|
|
276
|
+
*
|
|
277
|
+
* The chat stream is a live subscription that stays open after a turn settles,
|
|
278
|
+
* so callers should `break` out of the loop once they observe a terminal status
|
|
279
|
+
* — that triggers generator cleanup, which closes the socket.
|
|
280
|
+
*/
|
|
281
|
+
declare function streamChatEvents(options: StreamChatEventsOptions): AsyncGenerator<ChatStreamEvent, void, void>;
|
|
282
|
+
|
|
283
|
+
interface CoderChatClientOptions {
|
|
284
|
+
/** Base URL of the Coder deployment, e.g. `https://dev.coder.com`. */
|
|
285
|
+
baseUrl: string;
|
|
286
|
+
/** Coder API token or session token (sent as `Coder-Session-Token`). */
|
|
287
|
+
token: string;
|
|
288
|
+
/** Custom fetch implementation (defaults to global `fetch`). */
|
|
289
|
+
fetch?: typeof globalThis.fetch;
|
|
290
|
+
/** Custom WebSocket factory (defaults to the `ws` package on Node). */
|
|
291
|
+
webSocketFactory?: WebSocketFactory;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* A thin, typed client for Coder's experimental `chatd` API. This is a
|
|
295
|
+
* TypeScript port of the chat surface of `codersdk.ExperimentalClient`.
|
|
296
|
+
*/
|
|
297
|
+
declare class CoderChatClient {
|
|
298
|
+
#private;
|
|
299
|
+
readonly baseUrl: string;
|
|
300
|
+
constructor(options: CoderChatClientOptions);
|
|
301
|
+
listModelConfigs(signal?: AbortSignal): Promise<ChatModelConfig[]>;
|
|
302
|
+
createChat(req: CreateChatRequest, signal?: AbortSignal): Promise<Chat>;
|
|
303
|
+
getChat(chatId: string, signal?: AbortSignal): Promise<Chat>;
|
|
304
|
+
createChatMessage(chatId: string, req: CreateChatMessageRequest, signal?: AbortSignal): Promise<CreateChatMessageResponse>;
|
|
305
|
+
getMessages(chatId: string, opts?: {
|
|
306
|
+
before_id?: number;
|
|
307
|
+
after_id?: number;
|
|
308
|
+
limit?: number;
|
|
309
|
+
}, signal?: AbortSignal): Promise<ChatMessagesResponse>;
|
|
310
|
+
submitToolResults(chatId: string, req: SubmitToolResultsRequest, signal?: AbortSignal): Promise<void>;
|
|
311
|
+
interruptChat(chatId: string, signal?: AbortSignal): Promise<Chat>;
|
|
312
|
+
updateChat(chatId: string, req: UpdateChatRequest, signal?: AbortSignal): Promise<void>;
|
|
313
|
+
/** Convenience: archive a chat (soft-hide; safe for cleanup). */
|
|
314
|
+
archiveChat(chatId: string, signal?: AbortSignal): Promise<void>;
|
|
315
|
+
streamEvents(chatId: string, opts?: {
|
|
316
|
+
afterId?: number;
|
|
317
|
+
signal?: AbortSignal;
|
|
318
|
+
}): AsyncGenerator<ChatStreamEvent, void, void>;
|
|
319
|
+
/**
|
|
320
|
+
* Resolves a user-friendly model hint to a model-config UUID.
|
|
321
|
+
*
|
|
322
|
+
* Accepts: a config UUID (returned as-is), a `provider:model` id
|
|
323
|
+
* (e.g. `anthropic:claude-haiku-4-5-20251001`), a bare model id, or a
|
|
324
|
+
* display-name substring (case-insensitive). Returns `undefined` if no
|
|
325
|
+
* match is found, in which case the caller should let chatd pick the default.
|
|
326
|
+
*/
|
|
327
|
+
resolveModelConfigId(hint: string, signal?: AbortSignal): Promise<string | undefined>;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
type InnerAgent<TOOLS extends ToolSet> = ToolLoopAgent<never, TOOLS, never>;
|
|
331
|
+
interface CoderAgentSettings<TOOLS extends ToolSet = {}> {
|
|
332
|
+
/** A pre-built {@link CoderChatClient}. Mutually exclusive with baseUrl/token. */
|
|
333
|
+
client?: CoderChatClient;
|
|
334
|
+
/** Coder deployment base URL, e.g. `https://dev.coder.com`. */
|
|
335
|
+
baseUrl?: string;
|
|
336
|
+
/** Coder API/session token (sent as `Coder-Session-Token`). */
|
|
337
|
+
token?: string;
|
|
338
|
+
fetch?: CoderChatClientOptions["fetch"];
|
|
339
|
+
webSocketFactory?: CoderChatClientOptions["webSocketFactory"];
|
|
340
|
+
/** Organization UUID that owns the chat (required). */
|
|
341
|
+
organizationId: string;
|
|
342
|
+
/** Model hint: UUID, `provider:model`, model id, or display-name substring. */
|
|
343
|
+
model?: string;
|
|
344
|
+
/** Bind the chat to a Coder workspace (enables workspace-scoped tools). */
|
|
345
|
+
workspaceId?: string;
|
|
346
|
+
/** chatd-side MCP servers to enable for this chat. */
|
|
347
|
+
mcpServerIds?: string[];
|
|
348
|
+
/** chatd plan mode. */
|
|
349
|
+
planMode?: "" | "plan";
|
|
350
|
+
/** Resume an existing chat (session) instead of creating a new one. */
|
|
351
|
+
chatId?: string;
|
|
352
|
+
/** Stable agent id (exposed as {@link CoderAgent.id}). */
|
|
353
|
+
id?: string;
|
|
354
|
+
/** System instructions → chatd `system_prompt`. */
|
|
355
|
+
instructions?: string | SystemModelMessage | Array<SystemModelMessage>;
|
|
356
|
+
/** Custom (client-executed) tools. Each should have an `execute` for scripting. */
|
|
357
|
+
tools?: TOOLS;
|
|
358
|
+
toolChoice?: ToolChoice<NoInfer<TOOLS>>;
|
|
359
|
+
/** Stop condition(s) for the AI SDK loop. Default `stepCountIs(64)`. */
|
|
360
|
+
stopWhen?: StopCondition<NoInfer<TOOLS>> | Array<StopCondition<NoInfer<TOOLS>>>;
|
|
361
|
+
/**
|
|
362
|
+
* SDK-level retries. Default `0`: this agent owns server-side chat state, so
|
|
363
|
+
* SDK retries could duplicate a turn. Override with care.
|
|
364
|
+
*/
|
|
365
|
+
maxRetries?: number;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* An AI SDK-compliant agent backed by a remote Coder `chatd` agent runtime.
|
|
369
|
+
*
|
|
370
|
+
* `new CoderAgent({ ... })` returns an object that implements the AI SDK
|
|
371
|
+
* `Agent` interface (`generate()`/`stream()`), so it composes with the rest of
|
|
372
|
+
* the AI SDK ecosystem. Internally it wraps a {@link ToolLoopAgent} whose model
|
|
373
|
+
* is a {@link CoderLanguageModel}; chatd runs the actual agent loop server-side.
|
|
374
|
+
*
|
|
375
|
+
* One `CoderAgent` instance corresponds to one chatd chat ("session"): the chat
|
|
376
|
+
* is created on the first `generate()`/`stream()` and reused for subsequent
|
|
377
|
+
* turns. Use {@link CoderAgent.resetSession} to start a fresh chat.
|
|
378
|
+
*/
|
|
379
|
+
declare class CoderAgent<TOOLS extends ToolSet = {}> implements Agent<never, TOOLS, never> {
|
|
380
|
+
#private;
|
|
381
|
+
readonly version: "agent-v1";
|
|
382
|
+
constructor(settings: CoderAgentSettings<TOOLS>);
|
|
383
|
+
get id(): string | undefined;
|
|
384
|
+
get tools(): TOOLS;
|
|
385
|
+
/** The underlying chatd client. */
|
|
386
|
+
get client(): CoderChatClient;
|
|
387
|
+
/** The current chatd chat id, once a turn has started. */
|
|
388
|
+
get chatId(): string | undefined;
|
|
389
|
+
generate(options: Parameters<InnerAgent<TOOLS>["generate"]>[0]): ReturnType<InnerAgent<TOOLS>["generate"]>;
|
|
390
|
+
stream(options: Parameters<InnerAgent<TOOLS>["stream"]>[0]): ReturnType<InnerAgent<TOOLS>["stream"]>;
|
|
391
|
+
/** Start a fresh chatd chat on the next turn. */
|
|
392
|
+
resetSession(): void;
|
|
393
|
+
/** Interrupt the in-flight generation, if any. */
|
|
394
|
+
interrupt(): Promise<void>;
|
|
395
|
+
/** Archive the underlying chat (safe cleanup; hides it from listings). */
|
|
396
|
+
archive(): Promise<void>;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
interface CoderLanguageModelConfig {
|
|
400
|
+
client: CoderChatClient;
|
|
401
|
+
organizationId: string;
|
|
402
|
+
/** Model hint (UUID, `provider:model`, model id, or display-name substring). */
|
|
403
|
+
model?: string;
|
|
404
|
+
/** Bind the chat to a Coder workspace (enables workspace tools). */
|
|
405
|
+
workspaceId?: string;
|
|
406
|
+
/** chatd-side MCP servers to enable. */
|
|
407
|
+
mcpServerIds?: string[];
|
|
408
|
+
planMode?: "" | "plan";
|
|
409
|
+
/** Resume an existing chat instead of creating a new one. */
|
|
410
|
+
chatId?: string;
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* A {@link LanguageModelV3} that is backed by a remote Coder `chatd` agent
|
|
414
|
+
* runtime instead of a raw LLM. One model instance owns one chatd chat
|
|
415
|
+
* (a "session"): the chat is created lazily on the first turn and reused for
|
|
416
|
+
* subsequent turns and for client-tool resume steps.
|
|
417
|
+
*
|
|
418
|
+
* The chatd server runs the agent loop (model calls, server-side tools,
|
|
419
|
+
* compaction) itself. This model therefore represents *one chatd segment* per
|
|
420
|
+
* `doStream` call — it advances the chat until it settles (`waiting`/
|
|
421
|
+
* `completed`) or pauses for a client tool (`requires_action`). When the AI SDK
|
|
422
|
+
* executes a client tool and calls `doStream` again with the tool result, this
|
|
423
|
+
* model resumes the same chat. The two loops mesh at the client-tool boundary.
|
|
424
|
+
*
|
|
425
|
+
* NOTE: a single model instance is single-flight — do not run concurrent
|
|
426
|
+
* generations against the same instance/session.
|
|
427
|
+
*/
|
|
428
|
+
declare class CoderLanguageModel implements LanguageModelV3 {
|
|
429
|
+
#private;
|
|
430
|
+
readonly specificationVersion: "v3";
|
|
431
|
+
readonly provider = "coder.chatd";
|
|
432
|
+
readonly modelId: string;
|
|
433
|
+
readonly supportedUrls: Record<string, RegExp[]>;
|
|
434
|
+
constructor(config: CoderLanguageModelConfig);
|
|
435
|
+
get chatId(): string | undefined;
|
|
436
|
+
/** Drops the current session so the next turn creates a fresh chat. */
|
|
437
|
+
resetSession(): void;
|
|
438
|
+
doStream(options: LanguageModelV3CallOptions): Promise<LanguageModelV3StreamResult>;
|
|
439
|
+
doGenerate(options: LanguageModelV3CallOptions): Promise<LanguageModelV3GenerateResult>;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Translates one chatd turn's {@link ChatStreamEvent} stream into a sequence of
|
|
444
|
+
* `LanguageModelV3StreamPart`s for the AI SDK.
|
|
445
|
+
*
|
|
446
|
+
* Two text/reasoning modes, decided per turn from the wire behavior:
|
|
447
|
+
* - **delta mode** — chatd streamed `message_part` deltas; we emit those and
|
|
448
|
+
* treat the trailing full `message` snapshot as a no-op for text/reasoning.
|
|
449
|
+
* - **snapshot mode** — fast turns where only full `message` snapshots arrive;
|
|
450
|
+
* we diff each snapshot's full text against what we've already emitted.
|
|
451
|
+
* Both paths track an emitted-length cursor, so neither double-counts.
|
|
452
|
+
*
|
|
453
|
+
* Client (custom) tool calls are emitted from the reliable `action_required`
|
|
454
|
+
* event and left for the AI SDK to execute. chatd's own server-side tools are
|
|
455
|
+
* surfaced best-effort as `providerExecuted` tool calls/results.
|
|
456
|
+
*/
|
|
457
|
+
declare class TurnTranslator {
|
|
458
|
+
#private;
|
|
459
|
+
constructor(opts: {
|
|
460
|
+
dynamicToolNames: ReadonlySet<string>;
|
|
461
|
+
});
|
|
462
|
+
get terminalStatus(): ChatStatus | undefined;
|
|
463
|
+
/** Whether a client (custom) tool call has been emitted this turn. */
|
|
464
|
+
get clientToolCallSeen(): boolean;
|
|
465
|
+
get maxMessageId(): number;
|
|
466
|
+
get error(): ChatErrorPayload | undefined;
|
|
467
|
+
ingest(ev: ChatStreamEvent): LanguageModelV3StreamPart[];
|
|
468
|
+
finish(): LanguageModelV3StreamPart[];
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/** Concatenated system messages, mapped to chatd's `system_prompt`. */
|
|
472
|
+
declare function extractSystemPrompt(prompt: LanguageModelV3Prompt): string | undefined;
|
|
473
|
+
type TurnAction = {
|
|
474
|
+
kind: "new-turn";
|
|
475
|
+
content: ChatInputPart[];
|
|
476
|
+
} | {
|
|
477
|
+
kind: "resume";
|
|
478
|
+
toolResults: ToolResult[];
|
|
479
|
+
} | {
|
|
480
|
+
kind: "noop";
|
|
481
|
+
};
|
|
482
|
+
/**
|
|
483
|
+
* Decides what to do with a fresh `doStream`/`doGenerate` prompt:
|
|
484
|
+
* - trailing `tool` message(s) → resume the in-flight chatd turn by submitting
|
|
485
|
+
* those tool results (the AI SDK executed a client tool between steps);
|
|
486
|
+
* - otherwise the trailing `user` message → a new turn.
|
|
487
|
+
*/
|
|
488
|
+
declare function classifyTurnAction(prompt: LanguageModelV3Prompt): TurnAction;
|
|
489
|
+
/** Maps AI SDK function tools to chatd client-executed ("dynamic") tools. */
|
|
490
|
+
declare function toolsToDynamicTools(tools: LanguageModelV3CallOptions["tools"]): DynamicTool[];
|
|
491
|
+
/** The set of tool names the AI SDK side owns (i.e. client-executed). */
|
|
492
|
+
declare function dynamicToolNames(tools: LanguageModelV3CallOptions["tools"]): Set<string>;
|
|
493
|
+
|
|
494
|
+
/** Base error for all `@coder/ai-sdk-agent` failures. */
|
|
495
|
+
declare class CoderAgentError extends Error {
|
|
496
|
+
name: string;
|
|
497
|
+
constructor(message: string, options?: {
|
|
498
|
+
cause?: unknown;
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
/** An HTTP request to the Coder API failed. */
|
|
502
|
+
declare class CoderApiError extends CoderAgentError {
|
|
503
|
+
name: string;
|
|
504
|
+
readonly status: number;
|
|
505
|
+
readonly detail: string | undefined;
|
|
506
|
+
readonly method: string;
|
|
507
|
+
readonly path: string;
|
|
508
|
+
constructor(args: {
|
|
509
|
+
status: number;
|
|
510
|
+
method: string;
|
|
511
|
+
path: string;
|
|
512
|
+
message: string;
|
|
513
|
+
detail?: string;
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
/** A chat generation ended in an error status. */
|
|
517
|
+
declare class CoderChatError extends CoderAgentError {
|
|
518
|
+
name: string;
|
|
519
|
+
readonly kind: string | undefined;
|
|
520
|
+
readonly provider: string | undefined;
|
|
521
|
+
readonly retryable: boolean;
|
|
522
|
+
readonly statusCode: number | undefined;
|
|
523
|
+
constructor(payload: ChatErrorPayload);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
export { type Chat, type ChatBusyBehavior, type ChatClientType, type ChatErrorPayload, type ChatInputPart, type ChatInputPartType, type ChatMessage, type ChatMessagePart, type ChatMessagePartType, type ChatMessageRole, type ChatMessageUsage, type ChatMessagesResponse, type ChatModelConfig, type ChatPlanMode, type ChatQueuedMessage, type ChatStatus, type ChatStreamActionRequired, type ChatStreamEvent, type ChatStreamEventType, type ChatStreamMessagePart, type ChatStreamRetry, type ChatStreamStatus, type ChatStreamToolCall, CoderAgent, CoderAgentError, type CoderAgentSettings, CoderApiError, CoderChatClient, type CoderChatClientOptions, CoderChatError, CoderLanguageModel, type CoderLanguageModelConfig, type CreateChatMessageRequest, type CreateChatMessageResponse, type CreateChatRequest, type DynamicTool, type SubmitToolResultsRequest, TERMINAL_STATUSES, type ToolResult, type TurnAction, TurnTranslator, type UpdateChatRequest, type WebSocketFactory, type WebSocketLike, classifyTurnAction, dynamicToolNames, extractSystemPrompt, streamChatEvents, toolsToDynamicTools };
|