@coder/ai-sdk-agent 0.7.2 → 0.9.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 +73 -18
- package/dist/index.d.ts +172 -17
- package/dist/index.js +251 -89
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -196,6 +196,15 @@ Pass a Coder **API token** or **session token** as `token`; it is sent as the
|
|
|
196
196
|
`Coder-Session-Token` header (REST) and used to authenticate the streaming WebSocket. Create
|
|
197
197
|
a token with `coder tokens create`, or reuse your CLI session.
|
|
198
198
|
|
|
199
|
+
When `baseUrl`/`token` are not passed, they default from the `CODER_URL` and
|
|
200
|
+
`CODER_SESSION_TOKEN` environment variables (the same convention as
|
|
201
|
+
`@coder/ai-sdk-sandbox`'s transports); explicit settings win over the
|
|
202
|
+
environment. With the variables set, connection config disappears entirely:
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
const agent = new CoderAgent({ organizationId }); // uses CODER_URL + CODER_SESSION_TOKEN
|
|
206
|
+
```
|
|
207
|
+
|
|
199
208
|
You can also pass a pre‑built client:
|
|
200
209
|
|
|
201
210
|
```ts
|
|
@@ -312,7 +321,9 @@ await agent.generate({ prompt: "…" });
|
|
|
312
321
|
// e.g. attribute where the turn spent its time:
|
|
313
322
|
for (const ev of events) {
|
|
314
323
|
if (ev.type === "http:response")
|
|
315
|
-
console.log(
|
|
324
|
+
console.log(
|
|
325
|
+
`${ev.op}: ${ev.method} ${ev.path} → ${ev.status} in ${ev.durationMs.toFixed(0)}ms`,
|
|
326
|
+
);
|
|
316
327
|
if (ev.type === "ws:event" && ev.event.type === "action_required")
|
|
317
328
|
console.log(`tool calls arrived at +${ev.timestamp - events[0]!.timestamp}ms`);
|
|
318
329
|
if (ev.type === "segment:settle")
|
|
@@ -326,12 +337,12 @@ such as a message's `created_at`, for delivery‑lag measurements):
|
|
|
326
337
|
|
|
327
338
|
| event | when | payload (besides `timestamp`) |
|
|
328
339
|
| ---------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
329
|
-
| `http:request` | a REST request is sent | `id` (correlates the pair), `method`, `path`
|
|
330
|
-
| `http:response` | response headers arrive (incl. non‑2xx, `ok:false`) | `id`, `method`, `path`, `status`, `ok`, `durationMs`
|
|
331
|
-
| `http:error` | the fetch itself rejects (network failure, abort) | `id`, `method`, `path`, `message`, `durationMs`
|
|
340
|
+
| `http:request` | a REST request is sent | `id` (correlates the pair), `op` (the client operation, e.g. `"createChatMessage"`), `method`, `path` |
|
|
341
|
+
| `http:response` | response headers arrive (incl. non‑2xx, `ok:false`) | `id`, `op`, `method`, `path`, `status`, `ok`, `durationMs` |
|
|
342
|
+
| `http:error` | the fetch itself rejects (network failure, abort) | `id`, `op`, `method`, `path`, `message`, `durationMs` |
|
|
332
343
|
| `ws:dial` | a stream connection attempt starts | `chatId`, `reader` (identifies the `streamChatEvents` call), `attempt` (1‑based per reader, increments per redial), `url` |
|
|
333
344
|
| `ws:open` | the WebSocket handshake completes | `chatId`, `reader`, `attempt` |
|
|
334
|
-
| `ws:event` | a decoded stream event arrives | `chatId`, `reader`, `attempt`, `event` (the decoded `ChatStreamEvent`, by reference — don't mutate)
|
|
345
|
+
| `ws:event` | a decoded stream event arrives | `chatId`, `reader`, `attempt`, `event` (the decoded `ChatStreamEvent`, by reference — don't mutate), `forwarded` (the reader's replay verdict) |
|
|
335
346
|
| `ws:close` | the connection ends (exactly one per dial) | `chatId`, `reader`, `attempt`, `code`/`reason` when the server/network closed it; absent when the reader closed it (settle, teardown, redial) |
|
|
336
347
|
| `ws:error` | a socket error or unparseable frame | `chatId`, `reader`, `attempt`, `message` |
|
|
337
348
|
| `ws:redial` | a dropped connection is about to be redialed | `chatId`, `reader`, `attempt` (the ended connection), `consecutiveFailures`, `maxConsecutiveFailures`, `backoffMs` |
|
|
@@ -347,9 +358,24 @@ Semantics worth knowing:
|
|
|
347
358
|
- **No secrets** — events carry no headers and no tokens (auth travels in the
|
|
348
359
|
`Coder-Session-Token` header, which is deliberately excluded); `path`/`url`
|
|
349
360
|
never contain credentials.
|
|
350
|
-
- `
|
|
351
|
-
|
|
352
|
-
|
|
361
|
+
- `http:*` events name their operation: `op` is the public `CoderChatClient`
|
|
362
|
+
method performing the exchange (`"createChat"`, `"createChatMessage"`,
|
|
363
|
+
`"getMessages"`, `"submitToolResults"`, … — the `CoderClientOperation`
|
|
364
|
+
union), so per‑operation classification never has to reverse‑engineer
|
|
365
|
+
`path`. `method`/`path` stay for generic consumers; `archiveChat` stamps its
|
|
366
|
+
own `op` even though it issues the same `PATCH` as `updateChat`.
|
|
367
|
+
- `ws:event` fires at arrival: after a redial, chatd's replay of the
|
|
368
|
+
in‑progress episode is visible here (correlate with `reader`/`attempt`),
|
|
369
|
+
stamped with the reader's own replay verdict — `forwarded: false` exactly on
|
|
370
|
+
the duplicate deltas the reader suppresses from the turn, so subscribers
|
|
371
|
+
never re‑derive the episode filter.
|
|
372
|
+
- `forwarded` does **not** reflect snapshot dedup: repeated or revised
|
|
373
|
+
`message` snapshots are always `forwarded: true`, because reconciling them
|
|
374
|
+
is deliberately the consumer's job past the transport layer —
|
|
375
|
+
`TurnTranslator`'s per‑message ledger decides what a revision re‑emits, and
|
|
376
|
+
that disposition is not stamped on transport frames. Use `ws:event` for
|
|
377
|
+
span pairing and replay accounting; subscribers needing content fidelity
|
|
378
|
+
must consume model output (or `TurnTranslator`), not transport frames.
|
|
353
379
|
- Every `ws:*` event carries `reader` — a monotonic id for the
|
|
354
380
|
`streamChatEvents` call (reader) behind the connection, allocated from one
|
|
355
381
|
process‑wide counter so it stays unique across model and client instances.
|
|
@@ -427,6 +453,25 @@ for a few seconds, during which archiving 409s — `archive()` retries those 409
|
|
|
427
453
|
`settleRetryDelayMs`) and rethrows the last one if the chat never settles. Any
|
|
428
454
|
other failure, including your own abort, rethrows immediately.
|
|
429
455
|
|
|
456
|
+
`archive()` and `interrupt()` target the session's chat — or, after the session
|
|
457
|
+
was dropped (`resetSession()`, or the automatic discard after a fresh‑chat
|
|
458
|
+
stream failure — see [Handling errors](#handling-errors)), the **last‑known
|
|
459
|
+
chat id** (`agent.lastKnownChatId`), so a stranded chat is still cleaned up
|
|
460
|
+
instead of leaking. Generation never uses the last‑known id: a turn after a
|
|
461
|
+
drop creates a fresh chat as always. Every chat stranded by an _automatic_
|
|
462
|
+
discard is also recorded on a ledger (`agent.strandedChatIds`, oldest first) —
|
|
463
|
+
with `maxRetries` several failed attempts can strand one chat each while only
|
|
464
|
+
the final attempt's error surfaces — and one `archive()` retires them all,
|
|
465
|
+
oldest first, alongside its primary target. Both methods report what they
|
|
466
|
+
acted on instead of silently no‑oping: `archive()` resolves
|
|
467
|
+
`{ archived: true, chatId, archivedChatIds }` (each archived id is cleared as
|
|
468
|
+
a cleanup target) or `{ archived: false }` when no chat exists at all;
|
|
469
|
+
`interrupt()` resolves `{ interrupted: true, chatId }` /
|
|
470
|
+
`{ interrupted: false }` the same way. Deliberate abandonment is different:
|
|
471
|
+
`resetSession()` does **not** add to the ledger (you may want that chat kept),
|
|
472
|
+
so after a manual reset the old chat is targetable only until a new chat
|
|
473
|
+
supersedes `lastKnownChatId`.
|
|
474
|
+
|
|
430
475
|
To make cleanup ride scope exit instead of a `finally` you have to remember, the
|
|
431
476
|
agent is an **async disposable**:
|
|
432
477
|
|
|
@@ -460,7 +505,11 @@ carry structured detail you can branch on:
|
|
|
460
505
|
repeat (workspace/MCP tooling, fresh attachment uploads); otherwise it is
|
|
461
506
|
`false` — a retry would resubmit the prompt as a new user turn and could
|
|
462
507
|
duplicate those effects. A failure mid‑`stream()` surfaces on the stream,
|
|
463
|
-
outside the retry wrapper. The last transport failure is in `cause
|
|
508
|
+
outside the retry wrapper. The last transport failure is in `cause`, and
|
|
509
|
+
`chatId` names the chat the failed turn had created or attached to (absent
|
|
510
|
+
when it failed before a chat existed) — after the fresh‑chat discard the
|
|
511
|
+
chat still exists server‑side, and `archive()` keeps targeting it via
|
|
512
|
+
`agent.lastKnownChatId` ([Cleanup](#cleanup)).
|
|
464
513
|
|
|
465
514
|
```ts
|
|
466
515
|
import { CoderApiError, CoderChatError } from "@coder/ai-sdk-agent";
|
|
@@ -675,7 +724,8 @@ Coder servers — no experimental endpoints.
|
|
|
675
724
|
named "80" and never resolve; serve the preview on a higher port.
|
|
676
725
|
|
|
677
726
|
The preview helpers call non‑chat endpoints, so they need `baseUrl` + `token`
|
|
678
|
-
credentials — pass them alongside `client` if you construct one yourself
|
|
727
|
+
credentials — pass them alongside `client` if you construct one yourself (or
|
|
728
|
+
let them default from `CODER_URL`/`CODER_SESSION_TOKEN`).
|
|
679
729
|
|
|
680
730
|
## Workspaces & quota
|
|
681
731
|
|
|
@@ -835,7 +885,7 @@ sequence pinpoints _where_ a turn died:
|
|
|
835
885
|
|
|
836
886
|
| field | description |
|
|
837
887
|
| --------------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
838
|
-
| `client` \| (`baseUrl` + `token`) | connection (one or the other)
|
|
888
|
+
| `client` \| (`baseUrl` + `token`) | connection (one or the other; `baseUrl`/`token` default from `CODER_URL`/`CODER_SESSION_TOKEN`) |
|
|
839
889
|
| `organizationId` | org UUID that owns the chat (required) |
|
|
840
890
|
| `model` | model hint: UUID, `provider:model`, model id, or display‑name substring |
|
|
841
891
|
| `instructions` | system prompt |
|
|
@@ -936,7 +986,9 @@ export async function runTurn(workflowId: string, prompt: string): Promise<strin
|
|
|
936
986
|
// still persist the id, or the retried step orphans a live chat and its
|
|
937
987
|
// partial effects. Exception: after an exhausted stream failure on a
|
|
938
988
|
// chat this very call created, the SDK has already discarded the dead
|
|
939
|
-
// session (agent.chatId is undefined) and nothing is written —
|
|
989
|
+
// session (agent.chatId is undefined) and nothing is written — the thrown
|
|
990
|
+
// CoderStreamError's chatId still names the stranded chat, and
|
|
991
|
+
// agent.archive() retires it via agent.lastKnownChatId — see the
|
|
940
992
|
// CoderStreamError notes below for what retrying means then.
|
|
941
993
|
if (agent.chatId) await checkpoints.set(workflowId, agent.chatId);
|
|
942
994
|
}
|
|
@@ -1053,12 +1105,15 @@ try {
|
|
|
1053
1105
|
the dead session so a retry — `maxRetries` or a re‑run step — starts clean
|
|
1054
1106
|
on a fresh chat. The discard happens for _every_ chat the failed turn
|
|
1055
1107
|
itself created — **including the effectful, `isRetryable: false` case**:
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1108
|
+
`agent.chatId` is `undefined` and the `finally` checkpoint writes nothing —
|
|
1109
|
+
but the stranded chat is not nameless: the error's **`chatId`** field names
|
|
1110
|
+
it, and `interrupt()`/`archive()` keep targeting it via
|
|
1111
|
+
`agent.lastKnownChatId` ([Cleanup](#cleanup)), so the step's error path can
|
|
1112
|
+
retire the orphan directly — or checkpoint `err.chatId` for the
|
|
1113
|
+
reconciliation sweep (below) when its workspace/MCP effects need
|
|
1114
|
+
reconciling first. A retried step then starts a fresh chat that has _not_
|
|
1115
|
+
seen the orphan's effects: gate that retry on the same idempotency judgment
|
|
1116
|
+
as any re‑submission. **On a resumed chat it is always `isRetryable: false`:**
|
|
1062
1117
|
re‑running the step resubmits the same prompt as a _new user turn_, with the
|
|
1063
1118
|
failed attempt's partial output still in history (usually fine — the model
|
|
1064
1119
|
sees its own aborted attempt), and any workspace/MCP tool effects that ran
|
package/dist/index.d.ts
CHANGED
|
@@ -344,12 +344,27 @@ interface TransportEventBase {
|
|
|
344
344
|
/** Wall-clock observation time in ms since epoch (`Date.now()`). */
|
|
345
345
|
timestamp: number;
|
|
346
346
|
}
|
|
347
|
+
/**
|
|
348
|
+
* Names the `CoderChatClient` operation performing an HTTP exchange (issue
|
|
349
|
+
* #112). The public client method names are the stable vocabulary, so
|
|
350
|
+
* subscribers can classify per-operation timings without reverse-engineering
|
|
351
|
+
* `path` (whose API prefix is private and may change). New client methods
|
|
352
|
+
* extend this union; treat unrecognized values as "some other operation"
|
|
353
|
+
* rather than matching exhaustively.
|
|
354
|
+
*/
|
|
355
|
+
type CoderClientOperation = "listModelConfigs" | "resolveModelConfigId" | "createChat" | "getChat" | "createChatMessage" | "getMessages" | "submitToolResults" | "interruptChat" | "updateChat" | "archiveChat" | "uploadChatFile" | "getChatFile";
|
|
347
356
|
interface HttpTransportEventBase extends TransportEventBase {
|
|
348
357
|
/**
|
|
349
358
|
* Correlates a request with its response/error. Monotonically increasing
|
|
350
359
|
* per client instance.
|
|
351
360
|
*/
|
|
352
361
|
id: number;
|
|
362
|
+
/**
|
|
363
|
+
* The client operation performing this exchange — the public
|
|
364
|
+
* `CoderChatClient` method name. `archiveChat` stamps its own operation
|
|
365
|
+
* even though it issues the same `PATCH` as `updateChat`.
|
|
366
|
+
*/
|
|
367
|
+
op: CoderClientOperation;
|
|
353
368
|
/** HTTP method, e.g. `POST`. */
|
|
354
369
|
method: string;
|
|
355
370
|
/**
|
|
@@ -415,14 +430,31 @@ interface StreamOpenTransportEvent extends StreamTransportEventBase {
|
|
|
415
430
|
}
|
|
416
431
|
/**
|
|
417
432
|
* A decoded stream event arrived on the wire. Emitted at arrival time for
|
|
418
|
-
* every event in a frame batch
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
*
|
|
433
|
+
* every event in a frame batch — after a redial, chatd's replay of the
|
|
434
|
+
* in-progress episode is still visible here, stamped with the reader's own
|
|
435
|
+
* replay verdict (`forwarded`). `event` is the decoded object by reference
|
|
436
|
+
* (no copy): do not mutate it.
|
|
422
437
|
*/
|
|
423
438
|
interface StreamEventTransportEvent extends StreamTransportEventBase {
|
|
424
439
|
type: "ws:event";
|
|
425
440
|
event: ChatStreamEvent;
|
|
441
|
+
/**
|
|
442
|
+
* The reader's replay disposition for this frame (issue #111): `false`
|
|
443
|
+
* exactly when the episode filter suppresses it from the consumption path —
|
|
444
|
+
* a redial's replay of an in-progress delta at or below the last yielded
|
|
445
|
+
* `seq` of the same episode — and `true` when the reader forwards it to its
|
|
446
|
+
* consumer. It is a dedup verdict, not a delivery receipt: a consumer
|
|
447
|
+
* tearing down mid-queue can still discard a forwarded frame.
|
|
448
|
+
*
|
|
449
|
+
* Snapshot dedup is deliberately NOT reflected here: repeated or revised
|
|
450
|
+
* `message` snapshots are always `forwarded: true`, because reconciling
|
|
451
|
+
* them is the consumer's job past the transport layer — TurnTranslator's
|
|
452
|
+
* per-message emitted-content ledger decides what a revision re-emits.
|
|
453
|
+
* That disposition is not stamped on transport frames; subscribers needing
|
|
454
|
+
* content fidelity must consume model output (or TurnTranslator), not
|
|
455
|
+
* `ws:event`.
|
|
456
|
+
*/
|
|
457
|
+
forwarded: boolean;
|
|
426
458
|
}
|
|
427
459
|
/**
|
|
428
460
|
* The connection ended. Exactly one per dial: carries `code`/`reason` when
|
|
@@ -586,7 +618,10 @@ interface StreamChatEventsOptions {
|
|
|
586
618
|
* in-progress generation attempt's `message_part` deltas from `seq` 1, so
|
|
587
619
|
* parts of an episode
|
|
588
620
|
* (`history_version`, `generation_attempt`) at or below the last yielded `seq`
|
|
589
|
-
* are suppressed here rather than double-yielded.
|
|
621
|
+
* are suppressed here rather than double-yielded. That episode filter runs at
|
|
622
|
+
* frame arrival (not at consumption), so each frame's `ws:event` can carry
|
|
623
|
+
* the reader's own verdict as `forwarded` (issue #111) while `timestamp`
|
|
624
|
+
* keeps meaning arrival time. The iteration ends in five
|
|
590
625
|
* ways: `signal` aborting (clean return), a non-transient 4xx upgrade
|
|
591
626
|
* rejection (terminal {@link CoderApiError} — bad/expired token or a deleted
|
|
592
627
|
* chat cannot succeed on retry, while 408/425/429 consume the redial budget),
|
|
@@ -815,18 +850,49 @@ interface ChatAttachment extends UploadedChatFile {
|
|
|
815
850
|
*/
|
|
816
851
|
toFilePart(): FilePart;
|
|
817
852
|
}
|
|
853
|
+
/**
|
|
854
|
+
* Result of {@link CoderAgent.interrupt}: `interrupted: false` means there was
|
|
855
|
+
* no chat to interrupt (neither a live session nor a
|
|
856
|
+
* {@link CoderAgent.lastKnownChatId}) and no server call was made.
|
|
857
|
+
*/
|
|
858
|
+
type CoderInterruptResult = {
|
|
859
|
+
interrupted: true;
|
|
860
|
+
chatId: string;
|
|
861
|
+
} | {
|
|
862
|
+
interrupted: false;
|
|
863
|
+
chatId?: undefined;
|
|
864
|
+
};
|
|
865
|
+
/**
|
|
866
|
+
* Result of {@link CoderAgent.archive}: `archived: false` means there was no
|
|
867
|
+
* chat to archive (neither a live session nor a
|
|
868
|
+
* {@link CoderAgent.lastKnownChatId}) and no server call was made. Failures
|
|
869
|
+
* still throw — see {@link CoderAgent.archive}. `chatId` is the primary
|
|
870
|
+
* target (the session's or last-known chat); `archivedChatIds` additionally
|
|
871
|
+
* lists every chat archived by the call, oldest first — more than one when
|
|
872
|
+
* earlier stranded chats ({@link CoderAgent.strandedChatIds}) were retired
|
|
873
|
+
* alongside it.
|
|
874
|
+
*/
|
|
875
|
+
type CoderArchiveResult = {
|
|
876
|
+
archived: true;
|
|
877
|
+
chatId: string;
|
|
878
|
+
archivedChatIds: string[];
|
|
879
|
+
} | {
|
|
880
|
+
archived: false;
|
|
881
|
+
chatId?: undefined;
|
|
882
|
+
archivedChatIds?: undefined;
|
|
883
|
+
};
|
|
818
884
|
interface CoderAgentSettings<TOOLS extends ToolSet = {}> {
|
|
819
885
|
/**
|
|
820
886
|
* A pre-built {@link CoderChatClient}, used instead of constructing one from
|
|
821
887
|
* `baseUrl`/`token`. The preview helpers ({@link CoderAgent.getPreview},
|
|
822
888
|
* {@link CoderAgent.sharePreview}) call non-chat endpoints and therefore
|
|
823
|
-
* still need credentials — pass `baseUrl` + `token` alongside `client`
|
|
824
|
-
* enable them.
|
|
889
|
+
* still need credentials — pass `baseUrl` + `token` alongside `client` (or
|
|
890
|
+
* set `CODER_URL` + `CODER_SESSION_TOKEN`) to enable them.
|
|
825
891
|
*/
|
|
826
892
|
client?: CoderChatClient;
|
|
827
|
-
/** Coder deployment base URL, e.g. `https://dev.coder.com`. */
|
|
893
|
+
/** Coder deployment base URL, e.g. `https://dev.coder.com`. Defaults to `CODER_URL`. */
|
|
828
894
|
baseUrl?: string;
|
|
829
|
-
/** Coder API/session token (sent as `Coder-Session-Token`). */
|
|
895
|
+
/** Coder API/session token (sent as `Coder-Session-Token`). Defaults to `CODER_SESSION_TOKEN`. */
|
|
830
896
|
token?: string;
|
|
831
897
|
fetch?: CoderChatClientOptions["fetch"];
|
|
832
898
|
webSocketFactory?: CoderChatClientOptions["webSocketFactory"];
|
|
@@ -964,6 +1030,25 @@ declare class CoderAgent<TOOLS extends ToolSet = {}> implements Agent<never, TOO
|
|
|
964
1030
|
get client(): CoderChatClient;
|
|
965
1031
|
/** The current chatd chat id, once a turn has started. */
|
|
966
1032
|
get chatId(): string | undefined;
|
|
1033
|
+
/**
|
|
1034
|
+
* The last chat id this agent created or attached to, retained for CLEANUP
|
|
1035
|
+
* even after the session was dropped — a fresh-chat stream failure discards
|
|
1036
|
+
* the session ({@link CoderAgent.chatId} becomes `undefined`, so a retry
|
|
1037
|
+
* starts fresh), but the failed chat still exists server-side.
|
|
1038
|
+
* {@link CoderAgent.archive} and {@link CoderAgent.interrupt} fall back to
|
|
1039
|
+
* this id; generation never does. Superseded when a later turn creates or
|
|
1040
|
+
* attaches to another chat; cleared once {@link CoderAgent.archive}
|
|
1041
|
+
* succeeds against it.
|
|
1042
|
+
*/
|
|
1043
|
+
get lastKnownChatId(): string | undefined;
|
|
1044
|
+
/**
|
|
1045
|
+
* Chat ids stranded by automatic session discards and not yet cleaned up,
|
|
1046
|
+
* oldest first. Each retryable fresh-chat stream failure strands one chat,
|
|
1047
|
+
* so with `maxRetries` > 0 several can accumulate while only the final
|
|
1048
|
+
* attempt's error (and {@link CoderAgent.lastKnownChatId}) names the
|
|
1049
|
+
* newest. {@link CoderAgent.archive} retires all of them.
|
|
1050
|
+
*/
|
|
1051
|
+
get strandedChatIds(): string[];
|
|
967
1052
|
generate(options: Parameters<InnerAgent<TOOLS>["generate"]>[0]): ReturnType<InnerAgent<TOOLS>["generate"]>;
|
|
968
1053
|
stream(options: Parameters<InnerAgent<TOOLS>["stream"]>[0]): ReturnType<InnerAgent<TOOLS>["stream"]>;
|
|
969
1054
|
/**
|
|
@@ -972,33 +1057,61 @@ declare class CoderAgent<TOOLS extends ToolSet = {}> implements Agent<never, TOO
|
|
|
972
1057
|
* `id`, `provider`/`model`, or `display_name`.
|
|
973
1058
|
*/
|
|
974
1059
|
listModels(signal?: AbortSignal): Promise<ChatModelConfig[]>;
|
|
975
|
-
/**
|
|
1060
|
+
/**
|
|
1061
|
+
* Start a fresh chatd chat on the next turn. The dropped chat still exists
|
|
1062
|
+
* server-side: {@link CoderAgent.archive} / {@link CoderAgent.interrupt}
|
|
1063
|
+
* keep targeting it (via {@link CoderAgent.lastKnownChatId}) until a new
|
|
1064
|
+
* chat supersedes it or an archive succeeds against it.
|
|
1065
|
+
*/
|
|
976
1066
|
resetSession(): void;
|
|
977
1067
|
/**
|
|
978
1068
|
* Interrupt the in-flight generation, if any. Resolves as soon as the server
|
|
979
1069
|
* acknowledges the interrupt — the run keeps winding down asynchronously for
|
|
980
1070
|
* a few seconds afterwards (see {@link CoderAgent.archive}).
|
|
1071
|
+
*
|
|
1072
|
+
* Targets the session's chat, or — after the session was dropped (a
|
|
1073
|
+
* fresh-chat stream failure, or {@link CoderAgent.resetSession}) — the
|
|
1074
|
+
* {@link CoderAgent.lastKnownChatId}, whose run may still be winding down
|
|
1075
|
+
* server-side. With neither, there is nothing to interrupt and it resolves
|
|
1076
|
+
* `{ interrupted: false }` without a server call (inspect the result rather
|
|
1077
|
+
* than relying on a silent no-op).
|
|
981
1078
|
*/
|
|
982
1079
|
interrupt(opts?: {
|
|
983
1080
|
signal?: AbortSignal;
|
|
984
|
-
}): Promise<
|
|
1081
|
+
}): Promise<CoderInterruptResult>;
|
|
985
1082
|
/**
|
|
986
1083
|
* Archive the underlying chat (safe cleanup; hides it from listings).
|
|
987
1084
|
*
|
|
1085
|
+
* Targets the session's chat, or — after the session was dropped (a
|
|
1086
|
+
* fresh-chat stream failure, or {@link CoderAgent.resetSession}) — the
|
|
1087
|
+
* {@link CoderAgent.lastKnownChatId}, so the stranded chat is still cleaned
|
|
1088
|
+
* up; chats stranded by EARLIER automatic discards
|
|
1089
|
+
* ({@link CoderAgent.strandedChatIds} — `maxRetries` can accumulate several)
|
|
1090
|
+
* are retired in the same call. On success each archived id is cleared as a
|
|
1091
|
+
* cleanup target; with no id at all, there is nothing to archive and it
|
|
1092
|
+
* resolves `{ archived: false }` without a server call (inspect the result
|
|
1093
|
+
* rather than relying on a silent no-op).
|
|
1094
|
+
*
|
|
988
1095
|
* A freshly interrupted/settled chat can keep winding down server-side for a
|
|
989
1096
|
* few seconds, during which the server rejects archiving with a 409. Those
|
|
990
|
-
* 409s are retried (~1s apart
|
|
991
|
-
* `
|
|
992
|
-
*
|
|
1097
|
+
* 409s are retried (~1s apart — see `settleRetryDelayMs`) inside ONE
|
|
1098
|
+
* `settleDeadlineMs` window (~15s) shared by the whole call — however many
|
|
1099
|
+
* chats it archives — and the last 409 is rethrown if the window closes
|
|
1100
|
+
* first; any other failure, including a caller abort, rethrows immediately.
|
|
1101
|
+
* Chats are archived oldest first, each id cleared as its archive succeeds —
|
|
1102
|
+
* a mid-list failure rethrows and leaves the remaining ids targetable by a
|
|
1103
|
+
* later retry.
|
|
993
1104
|
*/
|
|
994
1105
|
archive(opts?: {
|
|
995
1106
|
signal?: AbortSignal;
|
|
996
|
-
}): Promise<
|
|
1107
|
+
}): Promise<CoderArchiveResult>;
|
|
997
1108
|
/**
|
|
998
1109
|
* Clean up the chat when the agent leaves an `await using` scope, so cleanup
|
|
999
1110
|
* rides scope exit instead of a separate call you have to remember in a
|
|
1000
1111
|
* `finally`. Interrupts any in-flight server run, then archives the chat
|
|
1001
|
-
* (retrying while the interrupted run settles)
|
|
1112
|
+
* (retrying while the interrupted run settles) — including a chat stranded
|
|
1113
|
+
* by a session discard (see {@link CoderAgent.lastKnownChatId}), which a
|
|
1114
|
+
* failed `generate()` would otherwise leak. Best-effort and bounded
|
|
1002
1115
|
* (~15s overall): disposal errors are swallowed after the bounded attempts
|
|
1003
1116
|
* so they can't mask the scope's own error — call {@link CoderAgent.archive}
|
|
1004
1117
|
* directly when you need guaranteed cleanup.
|
|
@@ -1128,10 +1241,42 @@ declare class CoderLanguageModel implements LanguageModelV4 {
|
|
|
1128
1241
|
readonly supportedUrls: Record<string, RegExp[]>;
|
|
1129
1242
|
constructor(config: CoderLanguageModelConfig);
|
|
1130
1243
|
get chatId(): string | undefined;
|
|
1244
|
+
/**
|
|
1245
|
+
* The last chat id this model created or attached to, for CLEANUP targeting
|
|
1246
|
+
* only — generation always targets {@link chatId}. It survives
|
|
1247
|
+
* {@link resetSession} (including the automatic session discard after a
|
|
1248
|
+
* fresh-chat stream failure, which clears {@link chatId} so a retry starts
|
|
1249
|
+
* fresh while the failed chat still exists server-side), is superseded when
|
|
1250
|
+
* a later turn creates or attaches to another chat, and is cleared via
|
|
1251
|
+
* {@link noteChatCleanedUp} once cleanup actually succeeded against it.
|
|
1252
|
+
*/
|
|
1253
|
+
get lastKnownChatId(): string | undefined;
|
|
1254
|
+
/**
|
|
1255
|
+
* Chat ids stranded by automatic session discards and not yet cleaned up,
|
|
1256
|
+
* oldest first. Each retryable fresh-chat stream failure strands one chat;
|
|
1257
|
+
* under AI-SDK `maxRetries` several can accumulate while only the final
|
|
1258
|
+
* attempt's error (and {@link lastKnownChatId}) names the newest —
|
|
1259
|
+
* `CoderAgent.archive()` retires all of them. Ids leave the list only via
|
|
1260
|
+
* {@link noteChatCleanedUp}.
|
|
1261
|
+
*/
|
|
1262
|
+
get strandedChatIds(): string[];
|
|
1263
|
+
/**
|
|
1264
|
+
* Forgets `chatId` as a cleanup target — call it only after cleanup
|
|
1265
|
+
* actually succeeded against that chat (e.g. `CoderAgent.archive()`
|
|
1266
|
+
* archived it), so later cleanup calls don't re-target an already-archived
|
|
1267
|
+
* chat: removes it from {@link strandedChatIds} and, when it is the
|
|
1268
|
+
* last-known id, clears {@link lastKnownChatId} (match-guarded: a stale
|
|
1269
|
+
* completion must not erase a newer chat's id). The session field
|
|
1270
|
+
* ({@link chatId}) is deliberately untouched — archiving does not reset the
|
|
1271
|
+
* session.
|
|
1272
|
+
*/
|
|
1273
|
+
noteChatCleanedUp(chatId: string): void;
|
|
1131
1274
|
/**
|
|
1132
1275
|
* Drops the current session so the next turn creates a fresh chat. Also
|
|
1133
1276
|
* closes the retained event stream, if any (fire-and-forget — a sync reset
|
|
1134
1277
|
* must not wait on socket teardown, and `close()` never rejects).
|
|
1278
|
+
* {@link lastKnownChatId} deliberately survives the reset: the dropped chat
|
|
1279
|
+
* still exists server-side and cleanup must still be able to target it.
|
|
1135
1280
|
*/
|
|
1136
1281
|
resetSession(): void;
|
|
1137
1282
|
/**
|
|
@@ -1340,11 +1485,21 @@ declare class CoderApiError extends CoderAgentError {
|
|
|
1340
1485
|
*/
|
|
1341
1486
|
declare class CoderStreamError extends APICallError {
|
|
1342
1487
|
name: string;
|
|
1488
|
+
/**
|
|
1489
|
+
* The chatd chat id the failed turn had created or attached to, when known.
|
|
1490
|
+
* A fresh-chat stream failure discards the session so a retry starts on a
|
|
1491
|
+
* fresh chat (`CoderAgent.chatId` becomes `undefined`), but the failed chat
|
|
1492
|
+
* still exists server-side — this field names it so callers can clean it up
|
|
1493
|
+
* (`CoderAgent.archive()` also retains it as the last-known cleanup target).
|
|
1494
|
+
* `undefined` when the failure happened before any chat existed.
|
|
1495
|
+
*/
|
|
1496
|
+
readonly chatId: string | undefined;
|
|
1343
1497
|
constructor(args: {
|
|
1344
1498
|
message: string;
|
|
1345
1499
|
url: string;
|
|
1346
1500
|
cause?: unknown;
|
|
1347
1501
|
isRetryable?: boolean;
|
|
1502
|
+
chatId?: string;
|
|
1348
1503
|
});
|
|
1349
1504
|
}
|
|
1350
1505
|
/** A chat generation ended in an error status. */
|
|
@@ -1357,4 +1512,4 @@ declare class CoderChatError extends CoderAgentError {
|
|
|
1357
1512
|
constructor(payload: ChatErrorPayload);
|
|
1358
1513
|
}
|
|
1359
1514
|
|
|
1360
|
-
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, CoderStreamError, type CoderTransportEvent, type CreateChatMessageRequest, type CreateChatMessageResponse, type CreateChatRequest, type DynamicTool, type FileContent, type FilePartUploader, type HttpErrorTransportEvent, type HttpRequestTransportEvent, type HttpResponseTransportEvent, MAX_CHAT_FILE_SIZE_BYTES, type PreviewShareLevel, type ResolvedFile, type SegmentSettleTransportEvent, type SegmentStartTransportEvent, type SharePreviewOptions, type SharedWorkspacePreview, type StreamCloseTransportEvent, type StreamDialTransportEvent, type StreamErrorTransportEvent, type StreamEventTransportEvent, type StreamOpenTransportEvent, type StreamRedialTransportEvent, type SubmitToolResultsRequest, TERMINAL_STATUSES, type ToolResult, type TransportEventHandler, 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 };
|
|
1515
|
+
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, type CoderArchiveResult, CoderChatClient, type CoderChatClientOptions, CoderChatError, type CoderClientOperation, type CoderFileProviderOptions, type CoderInterruptResult, CoderLanguageModel, type CoderLanguageModelConfig, CoderStreamError, type CoderTransportEvent, type CreateChatMessageRequest, type CreateChatMessageResponse, type CreateChatRequest, type DynamicTool, type FileContent, type FilePartUploader, type HttpErrorTransportEvent, type HttpRequestTransportEvent, type HttpResponseTransportEvent, MAX_CHAT_FILE_SIZE_BYTES, type PreviewShareLevel, type ResolvedFile, type SegmentSettleTransportEvent, type SegmentStartTransportEvent, type SharePreviewOptions, type SharedWorkspacePreview, type StreamCloseTransportEvent, type StreamDialTransportEvent, type StreamErrorTransportEvent, type StreamEventTransportEvent, type StreamOpenTransportEvent, type StreamRedialTransportEvent, type SubmitToolResultsRequest, TERMINAL_STATUSES, type ToolResult, type TransportEventHandler, 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 };
|