@coder/ai-sdk-agent 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +210 -21
- package/dist/index.d.ts +280 -39
- package/dist/index.js +672 -31
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { FilePart, ToolSet, Agent, SystemModelMessage, ToolChoice, StopCondition, ToolLoopAgent } from 'ai';
|
|
2
|
-
import {
|
|
1
|
+
import { FilePart, ToolSet, Agent, SystemModelMessage, ToolLoopAgentSettings, ToolChoice, StopCondition, ToolLoopAgent, UIMessage } from 'ai';
|
|
2
|
+
import { SharedV4FileData, LanguageModelV4, LanguageModelV4CallOptions, LanguageModelV4StreamResult, LanguageModelV4GenerateResult, LanguageModelV4StreamPart, LanguageModelV4Message, LanguageModelV4Prompt } from '@ai-sdk/provider';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Bytes to upload, in any convenient shape.
|
|
@@ -38,12 +38,14 @@ declare function resolveFileContent(content: FileContent, opts?: {
|
|
|
38
38
|
name?: string;
|
|
39
39
|
}): ResolvedFile;
|
|
40
40
|
/**
|
|
41
|
-
* Convert an AI SDK file-part `data` value
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
41
|
+
* Convert an AI SDK file-part `data` value (a tagged {@link SharedV4FileData}
|
|
42
|
+
* union) into {@link FileContent} for upload. The provider receives inline
|
|
43
|
+
* bytes, a base64 string, or inline text. URLs are not expected: this model
|
|
44
|
+
* declares no `supportedUrls`, so the SDK downloads them to bytes before
|
|
45
|
+
* calling us — a URL (or an opaque provider reference) here is therefore an
|
|
46
|
+
* error.
|
|
45
47
|
*/
|
|
46
|
-
declare function dataContentToFileContent(data:
|
|
48
|
+
declare function dataContentToFileContent(data: SharedV4FileData): FileContent;
|
|
47
49
|
|
|
48
50
|
/**
|
|
49
51
|
* Wire types for Coder's experimental `chatd` chat API
|
|
@@ -175,6 +177,13 @@ interface ChatMessageUsage {
|
|
|
175
177
|
cache_creation_tokens?: number;
|
|
176
178
|
cache_read_tokens?: number;
|
|
177
179
|
context_limit?: number;
|
|
180
|
+
/**
|
|
181
|
+
* Cost in micro-USD, when the server prices usage. Optional: servers that
|
|
182
|
+
* don't price usage (or predate cost reporting) omit it.
|
|
183
|
+
*/
|
|
184
|
+
total_cost_micros?: number;
|
|
185
|
+
/** Model runtime in milliseconds, when the server reports it. */
|
|
186
|
+
total_runtime_ms?: number;
|
|
178
187
|
}
|
|
179
188
|
interface ChatMessage {
|
|
180
189
|
id: number;
|
|
@@ -235,12 +244,18 @@ interface ChatMessagesResponse {
|
|
|
235
244
|
interface UploadChatFileResponse {
|
|
236
245
|
id: string;
|
|
237
246
|
}
|
|
247
|
+
/**
|
|
248
|
+
* A configured model (`GET /api/experimental/chats/model-configs`). Depending
|
|
249
|
+
* on the server version and how a config was created, `provider`, `model`, and
|
|
250
|
+
* `display_name` may be absent on individual entries, so treat them as
|
|
251
|
+
* optional and guard reads.
|
|
252
|
+
*/
|
|
238
253
|
interface ChatModelConfig {
|
|
239
254
|
id: string;
|
|
240
|
-
provider
|
|
255
|
+
provider?: string;
|
|
241
256
|
ai_provider_id?: string;
|
|
242
|
-
model
|
|
243
|
-
display_name
|
|
257
|
+
model?: string;
|
|
258
|
+
display_name?: string;
|
|
244
259
|
enabled?: boolean;
|
|
245
260
|
is_default?: boolean;
|
|
246
261
|
context_limit?: number;
|
|
@@ -288,6 +303,19 @@ interface ChatStreamEvent {
|
|
|
288
303
|
}
|
|
289
304
|
/** Terminal statuses: the chat has stopped generating for this turn. */
|
|
290
305
|
declare const TERMINAL_STATUSES: ReadonlySet<ChatStatus>;
|
|
306
|
+
/** Kinds of chat lifecycle events emitted on the per-user watch socket. */
|
|
307
|
+
type ChatWatchEventKind = "status_change" | "summary_change" | "title_change" | "created" | "deleted" | "diff_status_change" | "action_required" | "context_dirty";
|
|
308
|
+
/**
|
|
309
|
+
* An event from `GET /api/experimental/chats/watch`, which covers every chat
|
|
310
|
+
* visible to the authenticated user (not a single chat). Mirrors
|
|
311
|
+
* `codersdk.ChatWatchEvent`.
|
|
312
|
+
*/
|
|
313
|
+
interface ChatWatchEvent {
|
|
314
|
+
kind: ChatWatchEventKind;
|
|
315
|
+
chat: Chat;
|
|
316
|
+
/** Pending client-executed tool calls; sent with `action_required` events. */
|
|
317
|
+
tool_calls?: ChatStreamToolCall[];
|
|
318
|
+
}
|
|
291
319
|
|
|
292
320
|
/**
|
|
293
321
|
* A minimal WebSocket factory abstraction so the stream reader can run on
|
|
@@ -339,6 +367,27 @@ interface StreamChatEventsOptions {
|
|
|
339
367
|
* — that triggers generator cleanup, which closes the socket.
|
|
340
368
|
*/
|
|
341
369
|
declare function streamChatEvents(options: StreamChatEventsOptions): AsyncGenerator<ChatStreamEvent, void, void>;
|
|
370
|
+
interface WatchChatEventsOptions {
|
|
371
|
+
baseUrl: string;
|
|
372
|
+
token: string;
|
|
373
|
+
signal?: AbortSignal;
|
|
374
|
+
webSocketFactory?: WebSocketFactory;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Opens the chatd `/watch` WebSocket — lifecycle events for every chat visible
|
|
378
|
+
* to the authenticated user — and yields decoded {@link ChatWatchEvent}s as an
|
|
379
|
+
* async iterable.
|
|
380
|
+
*
|
|
381
|
+
* Unlike the per-chat `/stream`, this is a long-lived subscription, so dropped
|
|
382
|
+
* connections are redialed automatically with exponential backoff (1s doubling
|
|
383
|
+
* to a 30s cap, reset once an event arrives). It ends in exactly three ways:
|
|
384
|
+
* `signal` aborting, the consumer ending iteration (`break` from `for await`,
|
|
385
|
+
* `iterator.return()`) — both tear the socket down promptly even while a read
|
|
386
|
+
* is pending — or the server rejecting the upgrade with a 4xx — bad/expired
|
|
387
|
+
* token, or an older Coder server without the endpoint (404) — which throws a
|
|
388
|
+
* terminal {@link CoderApiError} instead of retrying forever.
|
|
389
|
+
*/
|
|
390
|
+
declare function watchChatEvents(options: WatchChatEventsOptions): AsyncGenerator<ChatWatchEvent, void, void>;
|
|
342
391
|
|
|
343
392
|
/** A file to upload as a chat attachment. */
|
|
344
393
|
interface ChatFileInput {
|
|
@@ -386,7 +435,23 @@ declare class CoderChatClient {
|
|
|
386
435
|
limit?: number;
|
|
387
436
|
}, signal?: AbortSignal): Promise<ChatMessagesResponse>;
|
|
388
437
|
submitToolResults(chatId: string, req: SubmitToolResultsRequest, signal?: AbortSignal): Promise<void>;
|
|
389
|
-
|
|
438
|
+
/**
|
|
439
|
+
* Interrupt the chat's in-flight run (`POST /interrupt`). The server flips
|
|
440
|
+
* an active run to `interrupting` and responds immediately with the updated
|
|
441
|
+
* chat — it does not wait for the run to actually stop.
|
|
442
|
+
*
|
|
443
|
+
* Pass `{ wait: true }` to send `?wait=true`, asking the server to hold the
|
|
444
|
+
* response until the run has stopped. Coder servers without that param
|
|
445
|
+
* ignore the unknown query harmlessly and still return immediately, so
|
|
446
|
+
* callers should be prepared to confirm completion via the event stream.
|
|
447
|
+
*
|
|
448
|
+
* The second parameter also accepts a bare `AbortSignal` (the historical
|
|
449
|
+
* signature).
|
|
450
|
+
*/
|
|
451
|
+
interruptChat(chatId: string, optsOrSignal?: AbortSignal | {
|
|
452
|
+
wait?: boolean;
|
|
453
|
+
signal?: AbortSignal;
|
|
454
|
+
}): Promise<Chat>;
|
|
390
455
|
updateChat(chatId: string, req: UpdateChatRequest, signal?: AbortSignal): Promise<void>;
|
|
391
456
|
/** Convenience: archive a chat (soft-hide; safe for cleanup). */
|
|
392
457
|
archiveChat(chatId: string, signal?: AbortSignal): Promise<void>;
|
|
@@ -409,6 +474,17 @@ declare class CoderChatClient {
|
|
|
409
474
|
afterId?: number;
|
|
410
475
|
signal?: AbortSignal;
|
|
411
476
|
}): AsyncGenerator<ChatStreamEvent, void, void>;
|
|
477
|
+
/**
|
|
478
|
+
* Watch lifecycle events (status/title changes, creation, deletion, …) for
|
|
479
|
+
* every chat visible to the authenticated user via the `/chats/watch`
|
|
480
|
+
* WebSocket. Dropped connections are redialed with exponential backoff; the
|
|
481
|
+
* iteration ends only when `opts.signal` aborts, or with a terminal
|
|
482
|
+
* {@link CoderApiError} when the server rejects the upgrade with a 4xx
|
|
483
|
+
* (bad/expired token, or an older Coder server without the endpoint → 404).
|
|
484
|
+
*/
|
|
485
|
+
watchChats(opts?: {
|
|
486
|
+
signal?: AbortSignal;
|
|
487
|
+
}): AsyncGenerator<ChatWatchEvent, void, void>;
|
|
412
488
|
/**
|
|
413
489
|
* Resolves a user-friendly model hint to a model-config UUID.
|
|
414
490
|
*
|
|
@@ -416,10 +492,24 @@ declare class CoderChatClient {
|
|
|
416
492
|
* (e.g. `anthropic:claude-haiku-4-5-20251001`), a bare model id, or a
|
|
417
493
|
* display-name substring (case-insensitive). Returns `undefined` if no
|
|
418
494
|
* match is found, in which case the caller should let chatd pick the default.
|
|
495
|
+
*
|
|
496
|
+
* Tolerates partial payloads from older/newer servers: a malformed listing
|
|
497
|
+
* (empty body, non-array JSON, null entries) resolves as no match, and
|
|
498
|
+
* entries missing `provider`, `model`, or `display_name` are matched on the
|
|
499
|
+
* fields they do carry — an entry without `provider` still matches by its
|
|
500
|
+
* model id, one without `model` only by display name.
|
|
419
501
|
*/
|
|
420
502
|
resolveModelConfigId(hint: string, signal?: AbortSignal): Promise<string | undefined>;
|
|
421
503
|
}
|
|
422
504
|
|
|
505
|
+
/** Share levels a port can be in; `owner` is the implicit default when no share exists. */
|
|
506
|
+
type PortShareLevel = "owner" | "authenticated" | "organization" | "public";
|
|
507
|
+
/**
|
|
508
|
+
* Share levels the upsert endpoint accepts. `owner` is rejected server-side —
|
|
509
|
+
* reverting to owner-only is done by deleting the share, not setting it.
|
|
510
|
+
*/
|
|
511
|
+
type PreviewShareLevel = Exclude<PortShareLevel, "owner">;
|
|
512
|
+
|
|
423
513
|
/**
|
|
424
514
|
* Adapter that writes bytes onto a Coder workspace's filesystem, injected into
|
|
425
515
|
* a {@link CoderAgent} to enable {@link CoderAgent.uploadToWorkspace}.
|
|
@@ -467,7 +557,7 @@ interface WorkspacePlacement {
|
|
|
467
557
|
path: string;
|
|
468
558
|
}
|
|
469
559
|
|
|
470
|
-
type InnerAgent<TOOLS extends ToolSet> = ToolLoopAgent<never, TOOLS
|
|
560
|
+
type InnerAgent<TOOLS extends ToolSet> = ToolLoopAgent<never, TOOLS>;
|
|
471
561
|
/** A handle to a file uploaded as a chat attachment (see {@link CoderAgent.attach}). */
|
|
472
562
|
interface ChatAttachment extends UploadedChatFile {
|
|
473
563
|
/**
|
|
@@ -482,7 +572,13 @@ interface ChatAttachment extends UploadedChatFile {
|
|
|
482
572
|
toFilePart(): FilePart;
|
|
483
573
|
}
|
|
484
574
|
interface CoderAgentSettings<TOOLS extends ToolSet = {}> {
|
|
485
|
-
/**
|
|
575
|
+
/**
|
|
576
|
+
* A pre-built {@link CoderChatClient}, used instead of constructing one from
|
|
577
|
+
* `baseUrl`/`token`. The preview helpers ({@link CoderAgent.getPreview},
|
|
578
|
+
* {@link CoderAgent.sharePreview}) call non-chat endpoints and therefore
|
|
579
|
+
* still need credentials — pass `baseUrl` + `token` alongside `client` to
|
|
580
|
+
* enable them.
|
|
581
|
+
*/
|
|
486
582
|
client?: CoderChatClient;
|
|
487
583
|
/** Coder deployment base URL, e.g. `https://dev.coder.com`. */
|
|
488
584
|
baseUrl?: string;
|
|
@@ -514,8 +610,14 @@ interface CoderAgentSettings<TOOLS extends ToolSet = {}> {
|
|
|
514
610
|
instructions?: string | SystemModelMessage | Array<SystemModelMessage>;
|
|
515
611
|
/** Custom (client-executed) tools. Each should have an `execute` for scripting. */
|
|
516
612
|
tools?: TOOLS;
|
|
613
|
+
/**
|
|
614
|
+
* Per-tool context values for tools that declare a `contextSchema`, keyed by
|
|
615
|
+
* tool name (forwarded to the AI SDK loop). Required by the SDK at runtime
|
|
616
|
+
* whenever a supplied tool declares contextual data.
|
|
617
|
+
*/
|
|
618
|
+
toolsContext?: ToolLoopAgentSettings<never, TOOLS>["toolsContext"];
|
|
517
619
|
toolChoice?: ToolChoice<NoInfer<TOOLS>>;
|
|
518
|
-
/** Stop condition(s) for the AI SDK loop. Default `
|
|
620
|
+
/** Stop condition(s) for the AI SDK loop. Default `isStepCount(64)`. */
|
|
519
621
|
stopWhen?: StopCondition<NoInfer<TOOLS>> | Array<StopCondition<NoInfer<TOOLS>>>;
|
|
520
622
|
/**
|
|
521
623
|
* SDK-level retries. Default `0`: this agent owns server-side chat state, so
|
|
@@ -534,6 +636,56 @@ interface CoderAgentSettings<TOOLS extends ToolSet = {}> {
|
|
|
534
636
|
* non-positive means no limit.
|
|
535
637
|
*/
|
|
536
638
|
requestTimeoutMs?: number;
|
|
639
|
+
/**
|
|
640
|
+
* Overall deadline in milliseconds for bounded cleanup: how long
|
|
641
|
+
* {@link CoderAgent.archive} keeps retrying while a freshly interrupted chat
|
|
642
|
+
* settles server-side, and how long `[Symbol.asyncDispose]` may take in
|
|
643
|
+
* total. Default 15 000. Primarily a test/tuning knob.
|
|
644
|
+
*/
|
|
645
|
+
settleDeadlineMs?: number;
|
|
646
|
+
/**
|
|
647
|
+
* Pause in milliseconds between {@link CoderAgent.archive} retries while the
|
|
648
|
+
* chat settles. Default 1000. Primarily a test/tuning knob.
|
|
649
|
+
*/
|
|
650
|
+
settleRetryDelayMs?: number;
|
|
651
|
+
}
|
|
652
|
+
/** Options for {@link CoderAgent.getPreview}. */
|
|
653
|
+
interface WorkspacePreviewOptions {
|
|
654
|
+
/** Workspace port the app listens on (4–5 digit ports parse most reliably). */
|
|
655
|
+
port: number;
|
|
656
|
+
/**
|
|
657
|
+
* Agent that serves the port. Optional when the workspace has exactly one
|
|
658
|
+
* agent; required when it has several (the error lists the candidates).
|
|
659
|
+
*/
|
|
660
|
+
agentName?: string;
|
|
661
|
+
/**
|
|
662
|
+
* Protocol the app speaks *inside the workspace* on that port — `https` adds
|
|
663
|
+
* the `s` suffix (`3000s--…`) so the proxy connects over TLS. This is not
|
|
664
|
+
* the browser scheme, which follows the deployment's access URL.
|
|
665
|
+
* Default `"http"`.
|
|
666
|
+
*/
|
|
667
|
+
protocol?: "http" | "https";
|
|
668
|
+
signal?: AbortSignal;
|
|
669
|
+
}
|
|
670
|
+
/** A resolved workspace preview URL (see {@link CoderAgent.getPreview}). */
|
|
671
|
+
interface WorkspacePreview {
|
|
672
|
+
/** Browser-openable subdomain app URL, e.g. `https://3000--main--dev--alice.apps.example.com`. */
|
|
673
|
+
url: string;
|
|
674
|
+
}
|
|
675
|
+
/** Options for {@link CoderAgent.sharePreview}. */
|
|
676
|
+
interface SharePreviewOptions extends WorkspacePreviewOptions {
|
|
677
|
+
/**
|
|
678
|
+
* Who may open the preview: `authenticated` (any logged-in user; the
|
|
679
|
+
* default), `organization` (members of the workspace's organization;
|
|
680
|
+
* requires a newer Coder server), or `public` (no auth at all — mind what
|
|
681
|
+
* the port serves).
|
|
682
|
+
*/
|
|
683
|
+
shareLevel?: PreviewShareLevel;
|
|
684
|
+
}
|
|
685
|
+
/** A shared workspace preview (see {@link CoderAgent.sharePreview}). */
|
|
686
|
+
interface SharedWorkspacePreview extends WorkspacePreview {
|
|
687
|
+
/** The share level now in effect for the port. */
|
|
688
|
+
shareLevel: PreviewShareLevel;
|
|
537
689
|
}
|
|
538
690
|
/**
|
|
539
691
|
* An AI SDK-compliant agent backed by a remote Coder `chatd` agent runtime.
|
|
@@ -547,7 +699,7 @@ interface CoderAgentSettings<TOOLS extends ToolSet = {}> {
|
|
|
547
699
|
* is created on the first `generate()`/`stream()` and reused for subsequent
|
|
548
700
|
* turns. Use {@link CoderAgent.resetSession} to start a fresh chat.
|
|
549
701
|
*/
|
|
550
|
-
declare class CoderAgent<TOOLS extends ToolSet = {}> implements Agent<never, TOOLS
|
|
702
|
+
declare class CoderAgent<TOOLS extends ToolSet = {}> implements Agent<never, TOOLS> {
|
|
551
703
|
#private;
|
|
552
704
|
readonly version: "agent-v1";
|
|
553
705
|
constructor(settings: CoderAgentSettings<TOOLS>);
|
|
@@ -567,16 +719,34 @@ declare class CoderAgent<TOOLS extends ToolSet = {}> implements Agent<never, TOO
|
|
|
567
719
|
listModels(signal?: AbortSignal): Promise<ChatModelConfig[]>;
|
|
568
720
|
/** Start a fresh chatd chat on the next turn. */
|
|
569
721
|
resetSession(): void;
|
|
570
|
-
/**
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
722
|
+
/**
|
|
723
|
+
* Interrupt the in-flight generation, if any. Resolves as soon as the server
|
|
724
|
+
* acknowledges the interrupt — the run keeps winding down asynchronously for
|
|
725
|
+
* a few seconds afterwards (see {@link CoderAgent.archive}).
|
|
726
|
+
*/
|
|
727
|
+
interrupt(opts?: {
|
|
728
|
+
signal?: AbortSignal;
|
|
729
|
+
}): Promise<void>;
|
|
730
|
+
/**
|
|
731
|
+
* Archive the underlying chat (safe cleanup; hides it from listings).
|
|
732
|
+
*
|
|
733
|
+
* A freshly interrupted/settled chat can keep winding down server-side for a
|
|
734
|
+
* few seconds, during which the server rejects archiving with a 409. Those
|
|
735
|
+
* 409s are retried (~1s apart, ~15s overall — see `settleDeadlineMs` /
|
|
736
|
+
* `settleRetryDelayMs`) and the last one is rethrown if the chat never
|
|
737
|
+
* settles; any other failure, including a caller abort, rethrows immediately.
|
|
738
|
+
*/
|
|
739
|
+
archive(opts?: {
|
|
740
|
+
signal?: AbortSignal;
|
|
741
|
+
}): Promise<void>;
|
|
574
742
|
/**
|
|
575
743
|
* Clean up the chat when the agent leaves an `await using` scope, so cleanup
|
|
576
744
|
* rides scope exit instead of a separate call you have to remember in a
|
|
577
|
-
* `finally`. Interrupts any in-flight server run, then archives the chat
|
|
578
|
-
*
|
|
579
|
-
*
|
|
745
|
+
* `finally`. Interrupts any in-flight server run, then archives the chat
|
|
746
|
+
* (retrying while the interrupted run settles). Best-effort and bounded
|
|
747
|
+
* (~15s overall): disposal errors are swallowed after the bounded attempts
|
|
748
|
+
* so they can't mask the scope's own error — call {@link CoderAgent.archive}
|
|
749
|
+
* directly when you need guaranteed cleanup.
|
|
580
750
|
*
|
|
581
751
|
* @example
|
|
582
752
|
* ```ts
|
|
@@ -615,6 +785,26 @@ declare class CoderAgent<TOOLS extends ToolSet = {}> implements Agent<never, TOO
|
|
|
615
785
|
path: string;
|
|
616
786
|
signal?: AbortSignal;
|
|
617
787
|
}): Promise<WorkspacePlacement>;
|
|
788
|
+
/**
|
|
789
|
+
* Resolve the browser URL where a port on the bound workspace can be
|
|
790
|
+
* previewed, e.g. `https://3000--main--dev--alice.apps.example.com`.
|
|
791
|
+
* Composed from stable v2 endpoints (workspace lookup + wildcard app host),
|
|
792
|
+
* so it works against old Coder servers. Requires the `workspaceId` setting,
|
|
793
|
+
* `baseUrl`/`token` credentials, and a deployment with a wildcard access URL
|
|
794
|
+
* configured.
|
|
795
|
+
*
|
|
796
|
+
* The URL honors the port's current share level — private to the workspace
|
|
797
|
+
* owner unless shared (see {@link CoderAgent.sharePreview}).
|
|
798
|
+
*/
|
|
799
|
+
getPreview(opts: WorkspacePreviewOptions): Promise<WorkspacePreview>;
|
|
800
|
+
/**
|
|
801
|
+
* Share a port on the bound workspace and return its preview URL. Upserts
|
|
802
|
+
* the port's share level — `authenticated` by default — so teammates (or,
|
|
803
|
+
* with `public`, anyone) can open what the agent is serving; re-invoking
|
|
804
|
+
* updates the level in place. On Coder servers that predate port sharing
|
|
805
|
+
* (< v2.9) this fails with a 404 {@link CoderApiError} saying so.
|
|
806
|
+
*/
|
|
807
|
+
sharePreview(opts: SharePreviewOptions): Promise<SharedWorkspacePreview>;
|
|
618
808
|
}
|
|
619
809
|
|
|
620
810
|
interface CoderLanguageModelConfig {
|
|
@@ -642,7 +832,7 @@ interface CoderLanguageModelConfig {
|
|
|
642
832
|
requestTimeoutMs?: number;
|
|
643
833
|
}
|
|
644
834
|
/**
|
|
645
|
-
* A {@link
|
|
835
|
+
* A {@link LanguageModelV4} that is backed by a remote Coder `chatd` agent
|
|
646
836
|
* runtime instead of a raw LLM. One model instance owns one chatd chat
|
|
647
837
|
* (a "session"): the chat is created lazily on the first turn and reused for
|
|
648
838
|
* subsequent turns and for client-tool resume steps.
|
|
@@ -657,9 +847,9 @@ interface CoderLanguageModelConfig {
|
|
|
657
847
|
* NOTE: a single model instance is single-flight — do not run concurrent
|
|
658
848
|
* generations against the same instance/session.
|
|
659
849
|
*/
|
|
660
|
-
declare class CoderLanguageModel implements
|
|
850
|
+
declare class CoderLanguageModel implements LanguageModelV4 {
|
|
661
851
|
#private;
|
|
662
|
-
readonly specificationVersion: "
|
|
852
|
+
readonly specificationVersion: "v4";
|
|
663
853
|
readonly provider = "coder.chatd";
|
|
664
854
|
readonly modelId: string;
|
|
665
855
|
readonly supportedUrls: Record<string, RegExp[]>;
|
|
@@ -667,17 +857,20 @@ declare class CoderLanguageModel implements LanguageModelV3 {
|
|
|
667
857
|
get chatId(): string | undefined;
|
|
668
858
|
/** Drops the current session so the next turn creates a fresh chat. */
|
|
669
859
|
resetSession(): void;
|
|
670
|
-
doStream(options:
|
|
671
|
-
doGenerate(options:
|
|
860
|
+
doStream(options: LanguageModelV4CallOptions): Promise<LanguageModelV4StreamResult>;
|
|
861
|
+
doGenerate(options: LanguageModelV4CallOptions): Promise<LanguageModelV4GenerateResult>;
|
|
672
862
|
}
|
|
673
863
|
|
|
674
864
|
/**
|
|
675
865
|
* Translates one chatd turn's {@link ChatStreamEvent} stream into a sequence of
|
|
676
|
-
* `
|
|
866
|
+
* `LanguageModelV4StreamPart`s for the AI SDK.
|
|
677
867
|
*
|
|
678
|
-
* Two text/reasoning modes, decided per
|
|
868
|
+
* Two text/reasoning modes, decided per assistant message from the wire
|
|
869
|
+
* behavior:
|
|
679
870
|
* - **delta mode** — chatd streamed `message_part` deltas; we emit those and
|
|
680
|
-
* treat the trailing full `message` snapshot as a no-op for
|
|
871
|
+
* treat the message's trailing full `message` snapshot as a no-op for
|
|
872
|
+
* text/reasoning. Deltas carry no message id, so "deltas arrived since the
|
|
873
|
+
* last assistant snapshot" is what marks a snapshot as trailing.
|
|
681
874
|
* - **snapshot mode** — fast turns where only full `message` snapshots arrive;
|
|
682
875
|
* we diff each snapshot's full text against what we've already emitted.
|
|
683
876
|
* Both paths track an emitted-length cursor, so neither double-counts.
|
|
@@ -696,9 +889,57 @@ declare class TurnTranslator {
|
|
|
696
889
|
get clientToolCallSeen(): boolean;
|
|
697
890
|
get maxMessageId(): number;
|
|
698
891
|
get error(): ChatErrorPayload | undefined;
|
|
699
|
-
ingest(ev: ChatStreamEvent):
|
|
700
|
-
finish():
|
|
892
|
+
ingest(ev: ChatStreamEvent): LanguageModelV4StreamPart[];
|
|
893
|
+
finish(): LanguageModelV4StreamPart[];
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
/** Options for {@link chatMessagesToUIMessages}. */
|
|
897
|
+
interface ChatMessagesToUIMessagesOptions {
|
|
898
|
+
/**
|
|
899
|
+
* Resolves a persisted `file` part to a URL for its `FileUIPart`. Persisted
|
|
900
|
+
* file parts carry only a `file_id` (no bytes, and usually no `url`), so
|
|
901
|
+
* without a URL there is nothing for the UI to render and the part is
|
|
902
|
+
* skipped. Download the bytes with `CoderChatClient.getChatFile(fileId)`
|
|
903
|
+
* and return a data:/object/proxy URL here to keep attachments visible.
|
|
904
|
+
* Returning `undefined` falls back to the part's own `url`, if any.
|
|
905
|
+
*/
|
|
906
|
+
fileUrl?: (part: ChatMessagePart) => string | undefined;
|
|
701
907
|
}
|
|
908
|
+
/**
|
|
909
|
+
* Converts persisted chat history (`CoderChatClient.getMessages`) into AI SDK
|
|
910
|
+
* v6 `UIMessage`s, e.g. to rehydrate `useChat({ messages })` for an existing
|
|
911
|
+
* chat. Pure and side-effect free.
|
|
912
|
+
*
|
|
913
|
+
* The mapping mirrors what a live-streamed transcript of the same turn looks
|
|
914
|
+
* like, with one caveat around client-tool typing (below):
|
|
915
|
+
* - One `ChatMessage` becomes one `UIMessage` (ids stringified), sorted
|
|
916
|
+
* chronologically by id regardless of input order — the messages endpoint
|
|
917
|
+
* pages newest-first by default, while `useChat` needs oldest-first. The
|
|
918
|
+
* exception is `role: "tool"` messages: their `tool-result` parts are
|
|
919
|
+
* folded into the originating assistant `dynamic-tool` part and the message
|
|
920
|
+
* itself is dropped.
|
|
921
|
+
* - `text`/`reasoning` parts map to their UI counterparts with
|
|
922
|
+
* `state: "done"` (history is complete, never streaming).
|
|
923
|
+
* - Every `tool-call` part becomes a `dynamic-tool` part, in state
|
|
924
|
+
* `"output-available"` once a result exists (`"output-error"` when it is
|
|
925
|
+
* marked `is_error`), or `"input-available"` while no result has been
|
|
926
|
+
* persisted yet. For server-executed tools this matches the live stream
|
|
927
|
+
* (they stream with `dynamic: true`); client (`ToolSet`) tools stream live
|
|
928
|
+
* as statically-typed `tool-{name}` parts, but persisted history does not
|
|
929
|
+
* record which names were client tools, so they rehydrate as `dynamic-tool`
|
|
930
|
+
* too. Render tools by name — ai's `isToolOrDynamicToolUIPart` +
|
|
931
|
+
* `getToolOrDynamicToolName` — rather than exact `part.type` matches and
|
|
932
|
+
* both shapes look identical.
|
|
933
|
+
* - `source` parts become `source-url` parts; skipped when the wire part has
|
|
934
|
+
* no `url`.
|
|
935
|
+
* - `file` parts become `file` UI parts only when a URL is available (see
|
|
936
|
+
* {@link ChatMessagesToUIMessagesOptions.fileUrl}): persisted file parts
|
|
937
|
+
* carry only a `file_id`, and `FileUIPart` requires a `url`. Parts without
|
|
938
|
+
* one are skipped.
|
|
939
|
+
* - `file-reference` / `context-file` / `skill` / unknown part kinds have no
|
|
940
|
+
* UI equivalent and are skipped silently (forward compatible).
|
|
941
|
+
*/
|
|
942
|
+
declare function chatMessagesToUIMessages(messages: ChatMessage[], opts?: ChatMessagesToUIMessagesOptions): UIMessage[];
|
|
702
943
|
|
|
703
944
|
/** Namespace key for this package's options on AI SDK message-part `providerOptions`. */
|
|
704
945
|
declare const CODER_PROVIDER_OPTIONS = "coder";
|
|
@@ -708,9 +949,9 @@ interface CoderFileProviderOptions {
|
|
|
708
949
|
fileId?: string;
|
|
709
950
|
}
|
|
710
951
|
/** Concatenated system messages, mapped to chatd's `system_prompt`. */
|
|
711
|
-
declare function extractSystemPrompt(prompt:
|
|
952
|
+
declare function extractSystemPrompt(prompt: LanguageModelV4Prompt): string | undefined;
|
|
712
953
|
/** The content array of a user message (text and file parts). */
|
|
713
|
-
type UserContent = Extract<
|
|
954
|
+
type UserContent = Extract<LanguageModelV4Message, {
|
|
714
955
|
role: "user";
|
|
715
956
|
}>["content"];
|
|
716
957
|
/**
|
|
@@ -719,7 +960,7 @@ type UserContent = Extract<LanguageModelV3Message, {
|
|
|
719
960
|
* here so {@link userContentToInputParts} stays pure and testable.
|
|
720
961
|
*/
|
|
721
962
|
type FilePartUploader = (file: {
|
|
722
|
-
data:
|
|
963
|
+
data: SharedV4FileData;
|
|
723
964
|
mediaType: string;
|
|
724
965
|
filename?: string;
|
|
725
966
|
}) => Promise<string>;
|
|
@@ -745,11 +986,11 @@ type TurnAction = {
|
|
|
745
986
|
* those tool results (the AI SDK executed a client tool between steps);
|
|
746
987
|
* - otherwise the trailing `user` message → a new turn.
|
|
747
988
|
*/
|
|
748
|
-
declare function classifyTurnAction(prompt:
|
|
989
|
+
declare function classifyTurnAction(prompt: LanguageModelV4Prompt): TurnAction;
|
|
749
990
|
/** Maps AI SDK function tools to chatd client-executed ("dynamic") tools. */
|
|
750
|
-
declare function toolsToDynamicTools(tools:
|
|
991
|
+
declare function toolsToDynamicTools(tools: LanguageModelV4CallOptions["tools"]): DynamicTool[];
|
|
751
992
|
/** The set of tool names the AI SDK side owns (i.e. client-executed). */
|
|
752
|
-
declare function dynamicToolNames(tools:
|
|
993
|
+
declare function dynamicToolNames(tools: LanguageModelV4CallOptions["tools"]): Set<string>;
|
|
753
994
|
|
|
754
995
|
/** Base error for all `@coder/ai-sdk-agent` failures. */
|
|
755
996
|
declare class CoderAgentError extends Error {
|
|
@@ -783,4 +1024,4 @@ declare class CoderChatError extends CoderAgentError {
|
|
|
783
1024
|
constructor(payload: ChatErrorPayload);
|
|
784
1025
|
}
|
|
785
1026
|
|
|
786
|
-
export { CHAT_ATTACHMENT_MEDIA_TYPES, CODER_PROVIDER_OPTIONS, type Chat, type ChatAttachment, type ChatAttachmentMediaType, type ChatBusyBehavior, type ChatClientType, type ChatErrorPayload, type ChatFileInput, 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, type CoderFileProviderOptions, CoderLanguageModel, type CoderLanguageModelConfig, type CreateChatMessageRequest, type CreateChatMessageResponse, type CreateChatRequest, type DynamicTool, type FileContent, type FilePartUploader, MAX_CHAT_FILE_SIZE_BYTES, type ResolvedFile, type SubmitToolResultsRequest, TERMINAL_STATUSES, type ToolResult, type TurnAction, TurnTranslator, type UpdateChatRequest, type UploadChatFileResponse, type UploadedChatFile, type UserContent, type WebSocketFactory, type WebSocketLike, type WorkspaceFileStore, type WorkspacePlacement, classifyTurnAction, dataContentToFileContent, dynamicToolNames, extractSystemPrompt, resolveFileContent, streamChatEvents, toolsToDynamicTools, userContentToInputParts };
|
|
1027
|
+
export { CHAT_ATTACHMENT_MEDIA_TYPES, CODER_PROVIDER_OPTIONS, type Chat, type ChatAttachment, type ChatAttachmentMediaType, type ChatBusyBehavior, type ChatClientType, type ChatErrorPayload, type ChatFileInput, type ChatInputPart, type ChatInputPartType, type ChatMessage, type ChatMessagePart, type ChatMessagePartType, type ChatMessageRole, type ChatMessageUsage, type ChatMessagesResponse, type ChatMessagesToUIMessagesOptions, type ChatModelConfig, type ChatPlanMode, type ChatQueuedMessage, type ChatStatus, type ChatStreamActionRequired, type ChatStreamEvent, type ChatStreamEventType, type ChatStreamMessagePart, type ChatStreamRetry, type ChatStreamStatus, type ChatStreamToolCall, type ChatWatchEvent, type ChatWatchEventKind, CoderAgent, CoderAgentError, type CoderAgentSettings, CoderApiError, CoderChatClient, type CoderChatClientOptions, CoderChatError, type CoderFileProviderOptions, CoderLanguageModel, type CoderLanguageModelConfig, type CreateChatMessageRequest, type CreateChatMessageResponse, type CreateChatRequest, type DynamicTool, type FileContent, type FilePartUploader, MAX_CHAT_FILE_SIZE_BYTES, type PreviewShareLevel, type ResolvedFile, type SharePreviewOptions, type SharedWorkspacePreview, type SubmitToolResultsRequest, TERMINAL_STATUSES, type ToolResult, type TurnAction, TurnTranslator, type UpdateChatRequest, type UploadChatFileResponse, type UploadedChatFile, type UserContent, type WatchChatEventsOptions, type WebSocketFactory, type WebSocketLike, type WorkspaceFileStore, type WorkspacePlacement, type WorkspacePreview, type WorkspacePreviewOptions, chatMessagesToUIMessages, classifyTurnAction, dataContentToFileContent, dynamicToolNames, extractSystemPrompt, resolveFileContent, streamChatEvents, toolsToDynamicTools, userContentToInputParts, watchChatEvents };
|