basalt-ui 1.9.0 → 1.11.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/AGENTS.md +2 -1
- package/CHANGELOG.md +18 -0
- package/README.md +64 -34
- package/agent/rules/basalt-agent.md +49 -6
- package/configs/oxlint-plugin.js +279 -0
- package/configs/oxlint-plugin.test.ts +216 -1
- package/configs/oxlint.json +5 -2
- package/dist/agent/ai-sdk-transport.d.ts +3 -52
- package/dist/agent/ai-sdk-transport.d.ts.map +1 -1
- package/dist/agent/ai-sdk-transport.js +108 -24
- package/dist/agent/coalesce.d.ts +26 -0
- package/dist/agent/coalesce.d.ts.map +1 -0
- package/dist/agent/coalesce.js +69 -0
- package/dist/agent/foreign.d.ts +97 -0
- package/dist/agent/foreign.d.ts.map +1 -0
- package/dist/agent/foreign.js +18 -0
- package/dist/agent/history.d.ts +2 -0
- package/dist/agent/history.d.ts.map +1 -1
- package/dist/agent/id.d.ts +35 -0
- package/dist/agent/id.d.ts.map +1 -0
- package/dist/agent/id.js +14 -0
- package/dist/agent/index.d.ts +9 -4
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +15 -3
- package/dist/agent/merge.d.ts +8 -0
- package/dist/agent/merge.d.ts.map +1 -0
- package/dist/agent/merge.js +23 -0
- package/dist/agent/part-list.d.ts.map +1 -1
- package/dist/agent/part-list.js +16 -6
- package/dist/agent/parts.d.ts +100 -21
- package/dist/agent/parts.d.ts.map +1 -1
- package/dist/agent/parts.js +128 -11
- package/dist/agent/transport.d.ts +39 -3
- package/dist/agent/transport.d.ts.map +1 -1
- package/dist/agent/transport.js +20 -17
- package/dist/agent/use-agent-stream.d.ts +2 -1
- package/dist/agent/use-agent-stream.d.ts.map +1 -1
- package/dist/agent/use-agent-stream.js +5 -2
- package/dist/agent/use-agent-thread-runs.d.ts +9 -3
- package/dist/agent/use-agent-thread-runs.d.ts.map +1 -1
- package/dist/agent/use-agent-thread-runs.js +76 -23
- package/dist/agent-chat/index.d.ts +6 -3
- package/dist/agent-chat/index.d.ts.map +1 -1
- package/dist/agent-chat/index.js +2 -0
- package/dist/agent-chat/thread-message.d.ts +24 -7
- package/dist/agent-chat/thread-message.d.ts.map +1 -1
- package/dist/agent-chat/thread-message.js +102 -43
- package/dist/agent-chat/tool-chip.d.ts +21 -0
- package/dist/agent-chat/tool-chip.d.ts.map +1 -0
- package/dist/agent-chat/tool-chip.js +120 -0
- package/dist/cli/index.d.ts +33 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +131 -0
- package/dist/guard/index.d.ts.map +1 -1
- package/dist/guard/index.js +1 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/surfaces.d.ts +11 -1
- package/dist/surfaces.d.ts.map +1 -1
- package/dist/surfaces.js +22 -1
- package/llms.txt +10 -3
- package/package.json +6 -1
- package/src/agent/ai-sdk-transport.test.ts +567 -0
- package/src/agent/ai-sdk-transport.ts +206 -53
- package/src/agent/coalesce.test.ts +194 -0
- package/src/agent/coalesce.ts +118 -0
- package/src/agent/foreign.test.ts +47 -0
- package/src/agent/foreign.ts +140 -0
- package/src/agent/history.ts +2 -0
- package/src/agent/id.test.ts +71 -0
- package/src/agent/id.ts +43 -0
- package/src/agent/index.ts +26 -3
- package/src/agent/merge.test.ts +119 -0
- package/src/agent/merge.ts +67 -0
- package/src/agent/part-list.test.tsx +82 -0
- package/src/agent/part-list.tsx +31 -6
- package/src/agent/parts.test.ts +603 -0
- package/src/agent/parts.ts +262 -32
- package/src/agent/thread.test.ts +147 -0
- package/src/agent/transport.test.ts +70 -0
- package/src/agent/transport.ts +72 -20
- package/src/agent/use-agent-stream.test.tsx +261 -0
- package/src/agent/use-agent-stream.ts +13 -3
- package/src/agent/use-agent-thread-runs.foreign.test.tsx +133 -0
- package/src/agent/use-agent-thread-runs.resume.test.tsx +289 -0
- package/src/agent/use-agent-thread-runs.test.tsx +781 -0
- package/src/agent/use-agent-thread-runs.ts +177 -27
- package/src/agent/use-agent-thread-runs.wedge.test.tsx +301 -0
- package/src/agent-chat/index.ts +8 -3
- package/src/agent-chat/thread-message.test.tsx +211 -0
- package/src/agent-chat/thread-message.tsx +235 -62
- package/src/agent-chat/tool-chip.test.tsx +139 -0
- package/src/agent-chat/tool-chip.tsx +219 -0
- package/src/charts/primitives/ChartFrame.test.tsx +8 -5
- package/src/cli/index.ts +285 -0
- package/src/dashboard/stat-card.test.tsx +5 -3
- package/src/guard/check-source.test.ts +8 -4
- package/src/guard/index.ts +1 -3
- package/src/index.ts +2 -0
- package/src/provider/index.test.tsx +6 -5
- package/src/surfaces.ts +23 -1
- package/src/theme/use-basalt-spacing.test.tsx +7 -4
- package/src/tokens/build-fonts-css.test.ts +3 -2
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* foreign.ts — the open half of the transcript's part-rendering registry.
|
|
3
|
+
*
|
|
4
|
+
* `AgentPart` (`./parts`) is a closed, exhaustively-switched union — adding a variant without
|
|
5
|
+
* updating every consuming switch is a tsc error (`PartList`'s `assertNever` gate). A transport
|
|
6
|
+
* that streams app-specific structured data (a chart spec, a progress ping) needs a part type
|
|
7
|
+
* `AgentPart` will never carry — closing the union around it would defeat the whole point of the
|
|
8
|
+
* gate. This file is the seam: `ForeignPart` describes what basalt does NOT know, `ConsumerPart`
|
|
9
|
+
* resolves the augmented union a consumer registers via `declare module 'basalt-ui'`, and
|
|
10
|
+
* `definePartRenderers` types an exhaustive renderer map against it. See
|
|
11
|
+
* `agent-chat/thread-message.tsx`'s three-step resolution order for how this plugs into
|
|
12
|
+
* `ThreadTranscript`: a consumer renderer wins first, `narrowAgentPart` routes the built-in six to
|
|
13
|
+
* `PartList`'s own exhaustive switch second, and `fallbackRenderer` catches anything left.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // app-side: src/features/chat/parts.ts
|
|
17
|
+
* type ChartPart = { type: 'data-chart'; id: string; spec: ChartSpec }
|
|
18
|
+
* declare module 'basalt-ui' {
|
|
19
|
+
* interface BasaltRegister { parts: ChartPart }
|
|
20
|
+
* }
|
|
21
|
+
* export const chatRenderers = definePartRenderers({
|
|
22
|
+
* 'data-chart': ({ part, settled }) => (settled ? <Chart spec={part.spec} /> : <ChartSkeleton />),
|
|
23
|
+
* })
|
|
24
|
+
*/
|
|
25
|
+
import type { ReactNode } from 'react';
|
|
26
|
+
import type { BasaltRegister } from '../register.js';
|
|
27
|
+
import type { ChatMessage } from './history.js';
|
|
28
|
+
import type { AgentPart } from './parts.js';
|
|
29
|
+
/** A part basalt does not know. NOT a member of AgentPart — the built-in union stays closed. */
|
|
30
|
+
export type ForeignPart = {
|
|
31
|
+
readonly type: string;
|
|
32
|
+
readonly id: string;
|
|
33
|
+
readonly [k: string]: unknown;
|
|
34
|
+
};
|
|
35
|
+
/** What a transcript actually holds — basalt's own six variants plus anything a consumer registers. */
|
|
36
|
+
export type TranscriptPart = AgentPart | ForeignPart;
|
|
37
|
+
/** The consumer's registered foreign-part union, or `never` when un-augmented. */
|
|
38
|
+
export type ConsumerPart = BasaltRegister extends {
|
|
39
|
+
parts: infer P extends ForeignPart;
|
|
40
|
+
} ? P : never;
|
|
41
|
+
/**
|
|
42
|
+
* Un-augmented: a loose string-keyed map (any renderer, any key — there is nothing to check
|
|
43
|
+
* against). Augmented: a MISSING key is a tsc error (`definePartRenderers` requires the full
|
|
44
|
+
* registered union), and each renderer's `part` is narrowed to exactly its variant. Same
|
|
45
|
+
* bound-check mechanism as `SeriesKey` (`register.ts:26-58`), applied to a union instead of a map.
|
|
46
|
+
*
|
|
47
|
+
* NOT caught: a STALE (extra, unregistered) key. `<const T extends Constraint>` inference does
|
|
48
|
+
* not excess-property-check an object-literal argument the way a direct assignment to a fixed
|
|
49
|
+
* target type would (verified against this repo's tsc — see
|
|
50
|
+
* `apps/playground/src/demo/agent-part-registry.type-guard.ts`'s Fixture 3) — an extra key
|
|
51
|
+
* compiles as dead code rather than erroring. Catching it would need an `Exact<T, Shape>`-style
|
|
52
|
+
* wrapper that departs from the `spec: T` "canonical token-factory contract" every other `defineX`
|
|
53
|
+
* in this codebase follows verbatim; that trade was left as a documented gap rather than a one-off
|
|
54
|
+
* factory shape.
|
|
55
|
+
*/
|
|
56
|
+
export type PartRenderers = [ConsumerPart] extends [never] ? Readonly<Record<string, PartRenderer<ForeignPart>>> : {
|
|
57
|
+
readonly [K in ConsumerPart['type']]: PartRenderer<Extract<ConsumerPart, {
|
|
58
|
+
type: K;
|
|
59
|
+
}>>;
|
|
60
|
+
};
|
|
61
|
+
/** Everything a foreign-part renderer needs beyond the part itself. */
|
|
62
|
+
export type PartRenderContext<TPart = ForeignPart> = {
|
|
63
|
+
readonly part: TPart;
|
|
64
|
+
readonly messageId: string;
|
|
65
|
+
readonly partId: string;
|
|
66
|
+
/** false while this part belongs to the in-flight tail of a streaming turn. */
|
|
67
|
+
readonly settled: boolean;
|
|
68
|
+
readonly role: ChatMessage['role'];
|
|
69
|
+
};
|
|
70
|
+
export type PartRenderer<TPart = ForeignPart> = (ctx: PartRenderContext<TPart>) => ReactNode;
|
|
71
|
+
/**
|
|
72
|
+
* Canonical const-generic factory (`packages/basalt-ui/CLAUDE.md`, "Canonical token-factory
|
|
73
|
+
* contract") — identity passthrough, exact-keyed return, no builder, no config bag. Mirrors
|
|
74
|
+
* `defineSeries` (`tokens/index.ts:648-650`) and `defineNotifications`
|
|
75
|
+
* (`notifications/define-notifications.ts:112-115`).
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* const chatRenderers = definePartRenderers({
|
|
79
|
+
* 'data-chart': ({ part }) => <Chart spec={part.spec} />,
|
|
80
|
+
* })
|
|
81
|
+
*/
|
|
82
|
+
export declare function definePartRenderers<const T extends PartRenderers>(map: T): T;
|
|
83
|
+
/**
|
|
84
|
+
* Returns `part` as an `AgentPart` when its `type` is one of the six built-in variants, else
|
|
85
|
+
* `null`. Deliberately NOT routed through `parseAgentPart`: that function is a VALIDATING parser
|
|
86
|
+
* for untrusted wire data — it checks every field a variant requires (`runId`, `toolCallId`,
|
|
87
|
+
* `approval`, ...) and would reject an already-well-typed in-memory `AgentPart` on shape grounds
|
|
88
|
+
* if it doesn't happen to match the wire representation byte-for-byte. `narrowAgentPart` is the
|
|
89
|
+
* cheap complement: a plain discriminator check on a value already known to be a `TranscriptPart`,
|
|
90
|
+
* used purely to route rendering — it trusts the caller's typing rather than re-validating it.
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* const agentPart = narrowAgentPart(part)
|
|
94
|
+
* if (agentPart !== null) return <PartList parts={[agentPart]} />
|
|
95
|
+
*/
|
|
96
|
+
export declare function narrowAgentPart(part: TranscriptPart): AgentPart | null;
|
|
97
|
+
//# sourceMappingURL=foreign.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foreign.d.ts","sourceRoot":"","sources":["../../src/agent/foreign.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAIxC,gGAAgG;AAChG,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CAC9B,CAAA;AAED,uGAAuG;AACvG,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,WAAW,CAAA;AAuBpD,kFAAkF;AAClF,MAAM,MAAM,YAAY,GAAG,cAAc,SAAS;IAAE,KAAK,EAAE,MAAM,CAAC,SAAS,WAAW,CAAA;CAAE,GAAG,CAAC,GAAG,KAAK,CAAA;AAIpG;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,GACtD,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC,CAAC,GACnD;IAAE,QAAQ,EAAE,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,YAAY,EAAE;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;CAAE,CAAA;AAE9F,uEAAuE;AACvE,MAAM,MAAM,iBAAiB,CAAC,KAAK,GAAG,WAAW,IAAI;IACnD,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;IACpB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CACnC,CAAA;AAED,MAAM,MAAM,YAAY,CAAC,KAAK,GAAG,WAAW,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,KAAK,CAAC,KAAK,SAAS,CAAA;AAE5F;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,CAAC,SAAS,aAAa,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAE5E;AAaD;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,SAAS,GAAG,IAAI,CAEtE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
function definePartRenderers(map) {
|
|
2
|
+
return map;
|
|
3
|
+
}
|
|
4
|
+
const AGENT_PART_TYPES = /* @__PURE__ */ new Set([
|
|
5
|
+
"start",
|
|
6
|
+
"text",
|
|
7
|
+
"reasoning",
|
|
8
|
+
"tool",
|
|
9
|
+
"source",
|
|
10
|
+
"error"
|
|
11
|
+
]);
|
|
12
|
+
function narrowAgentPart(part) {
|
|
13
|
+
return AGENT_PART_TYPES.has(part.type) ? part : null;
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
definePartRenderers,
|
|
17
|
+
narrowAgentPart
|
|
18
|
+
};
|
package/dist/agent/history.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ export type ChatMessage<TPart = AgentPart> = {
|
|
|
16
16
|
readonly role: 'user' | 'assistant';
|
|
17
17
|
readonly parts: TPart[];
|
|
18
18
|
readonly createdAt: number;
|
|
19
|
+
/** How the turn ended. Absent on user messages and on pre-1.11 persisted assistant messages. */
|
|
20
|
+
readonly finish?: 'complete' | 'stopped' | 'error';
|
|
19
21
|
};
|
|
20
22
|
export type ChatHistoryStoreOptions = {
|
|
21
23
|
/** localStorage key (namespaced as `basalt:<key>`). Stable — changes key lose history. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/agent/history.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAIxC;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,WAAW,CAAC,KAAK,GAAG,SAAS,IAAI;IAC3C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;IACnC,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,CAAA;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/agent/history.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAIxC;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,WAAW,CAAC,KAAK,GAAG,SAAS,IAAI;IAC3C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;IACnC,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,CAAA;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,gGAAgG;IAChG,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAAA;CACnD,CAAA;AAID,MAAM,MAAM,uBAAuB,GAAG;IACpC,0FAA0F;IAC1F,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,wFAAwF;IACxF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB;;;OAGG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAID,MAAM,MAAM,gBAAgB,CAAC,KAAK,GAAG,SAAS,IAAI;IAChD,2CAA2C;IAC3C,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,CAAA;IACvC,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC,KAAK,IAAI,CAAA;IACtD,0BAA0B;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAA;CAC3B,CAAA;AAID;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,GAAG,SAAS,EACtD,IAAI,EAAE,uBAAuB,GAC5B,MAAM,gBAAgB,CAAC,KAAK,CAAC,CAoC/B"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* withPartIds — stamps a stable id onto every draft part arriving without one.
|
|
3
|
+
*
|
|
4
|
+
* A transport is allowed to yield a draft (`AgentPartDraft` — `id` optional); this wraps such a
|
|
5
|
+
* generator and normalizes it into a fully-identified stream, minting `${runId}#${n}` for any
|
|
6
|
+
* part that arrives without an `id`. A part that already carries an id passes through untouched
|
|
7
|
+
* (idempotent) and does not advance the counter.
|
|
8
|
+
*
|
|
9
|
+
* NOT a replay-convergence mechanism. The minted id is a bare per-call sequence number with no
|
|
10
|
+
* relationship to content or offset — it identifies "the nth id-less part THIS invocation saw",
|
|
11
|
+
* nothing more. Calling `withPartIds` again over a resumed/replayed stream restarts its counter at
|
|
12
|
+
* 0, so the resumed stream's first delta mints the SAME id as the original run's first delta
|
|
13
|
+
* (`${runId}#0`) regardless of whether it carries the same content — if the resumed transport
|
|
14
|
+
* re-sends the full text as one chunk while the original sent it as several deltas, mergePart's
|
|
15
|
+
* tail-splice will corrupt the accumulated text rather than converge it. A transport that needs
|
|
16
|
+
* genuine replay convergence (one asserting `ResumableAgentTransport`'s `idempotentReplay: true`)
|
|
17
|
+
* MUST mint its own content-stable ids — e.g. `aiSdkTransport`'s `${chatId}#${index}` /
|
|
18
|
+
* `tool#${toolCallId}` — and must not rely on this helper for that guarantee. Combining
|
|
19
|
+
* `withPartIds` with a transport that asserts `idempotentReplay: true` is only safe when that
|
|
20
|
+
* transport already mints stable ids itself, in which case every part already carries an `id` and
|
|
21
|
+
* `withPartIds` is a no-op passthrough (see the idempotent behavior above) — it is never the thing
|
|
22
|
+
* providing replay safety.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* const identified = withPartIds(runId, transport.stream(input, signal))
|
|
26
|
+
* for await (const part of identified) {
|
|
27
|
+
* // part.id is always defined here
|
|
28
|
+
* }
|
|
29
|
+
*/
|
|
30
|
+
export declare function withPartIds<TPart extends {
|
|
31
|
+
id?: string;
|
|
32
|
+
}>(runId: string, source: AsyncGenerator<TPart>): AsyncGenerator<TPart & {
|
|
33
|
+
id: string;
|
|
34
|
+
}>;
|
|
35
|
+
//# sourceMappingURL=id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../../src/agent/id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAuB,WAAW,CAAC,KAAK,SAAS;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,EAC9D,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,cAAc,CAAC,KAAK,CAAC,GAC5B,cAAc,CAAC,KAAK,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,CAUxC"}
|
package/dist/agent/id.js
ADDED
package/dist/agent/index.d.ts
CHANGED
|
@@ -30,10 +30,15 @@
|
|
|
30
30
|
* )
|
|
31
31
|
* }
|
|
32
32
|
*/
|
|
33
|
-
export type { AgentPart, StartPart, TextPart, ReasoningPart, ToolCallPart, SourcePart, ErrorPart, } from './parts.js';
|
|
34
|
-
export { parseAgentPart, isStartPart } from './parts.js';
|
|
35
|
-
export
|
|
36
|
-
export {
|
|
33
|
+
export type { AgentPart, AgentPartDraft, Drafted, StartPart, TextPart, ReasoningPart, ToolCallPart, ToolCallState, SourcePart, ErrorPart, } from './parts.js';
|
|
34
|
+
export { parseAgentPart, isStartPart, isToolCallSettled, TERMINAL_TOOL_STATES } from './parts.js';
|
|
35
|
+
export { mergePart } from './merge.js';
|
|
36
|
+
export { withPartIds } from './id.js';
|
|
37
|
+
export { coalesceParts } from './coalesce.js';
|
|
38
|
+
export { definePartRenderers, narrowAgentPart } from './foreign.js';
|
|
39
|
+
export type { ForeignPart, TranscriptPart, ConsumerPart, PartRenderers, PartRenderContext, PartRenderer, } from './foreign.js';
|
|
40
|
+
export type { AgentTransport, ResumableAgentTransport } from './transport.js';
|
|
41
|
+
export { edenTransport, isResumable } from './transport.js';
|
|
37
42
|
export { aiSdkTransport } from './ai-sdk-transport.js';
|
|
38
43
|
export type { AiSdkTransport, AiSdkTransportOptions } from './ai-sdk-transport.js';
|
|
39
44
|
export { useAgentStream } from './use-agent-stream.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,YAAY,EACV,SAAS,EACT,SAAS,EACT,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,UAAU,EACV,SAAS,GACV,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,YAAY,EACV,SAAS,EACT,cAAc,EACd,OAAO,EACP,SAAS,EACT,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,aAAa,EACb,UAAU,EACV,SAAS,GACV,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAG9F,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAGnC,OAAO,EAAE,WAAW,EAAE,MAAM,MAAM,CAAA;AAGlC,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG1C,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAChE,YAAY,EACV,WAAW,EACX,cAAc,EACd,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,YAAY,GACb,MAAM,WAAW,CAAA;AAGlB,YAAY,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAC1E,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAGxD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAG/E,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,YAAY,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAG5E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAC5D,YAAY,EACV,cAAc,EACd,sBAAsB,EACtB,wBAAwB,GACzB,MAAM,yBAAyB,CAAA;AAGhC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AACtC,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,aAAa,CAAA;AAGpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AACvD,YAAY,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAA;AAGjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAA;AAClD,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAA;AAGvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAC7C,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAG5F,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA;AAC5C,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA"}
|
package/dist/agent/index.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import { parseAgentPart, isStartPart } from "./parts.js";
|
|
2
|
-
import {
|
|
1
|
+
import { parseAgentPart, isStartPart, isToolCallSettled, TERMINAL_TOOL_STATES } from "./parts.js";
|
|
2
|
+
import { mergePart } from "./merge.js";
|
|
3
|
+
import { withPartIds } from "./id.js";
|
|
4
|
+
import { coalesceParts } from "./coalesce.js";
|
|
5
|
+
import { definePartRenderers, narrowAgentPart } from "./foreign.js";
|
|
6
|
+
import { edenTransport, isResumable } from "./transport.js";
|
|
3
7
|
import { aiSdkTransport } from "./ai-sdk-transport.js";
|
|
4
8
|
import { useAgentStream } from "./use-agent-stream.js";
|
|
5
9
|
import { useAgentThreadRuns } from "./use-agent-thread-runs.js";
|
|
@@ -11,13 +15,21 @@ import { heuristicOutcome } from "./outcome.js";
|
|
|
11
15
|
export {
|
|
12
16
|
BasaltStickToBottom,
|
|
13
17
|
PartList,
|
|
18
|
+
TERMINAL_TOOL_STATES,
|
|
14
19
|
aiSdkTransport,
|
|
20
|
+
coalesceParts,
|
|
15
21
|
createChatHistoryStore,
|
|
16
22
|
createThreadsStore,
|
|
23
|
+
definePartRenderers,
|
|
17
24
|
edenTransport,
|
|
18
25
|
heuristicOutcome,
|
|
26
|
+
isResumable,
|
|
19
27
|
isStartPart,
|
|
28
|
+
isToolCallSettled,
|
|
29
|
+
mergePart,
|
|
30
|
+
narrowAgentPart,
|
|
20
31
|
parseAgentPart,
|
|
21
32
|
useAgentStream,
|
|
22
|
-
useAgentThreadRuns
|
|
33
|
+
useAgentThreadRuns,
|
|
34
|
+
withPartIds
|
|
23
35
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** The structural bound `mergePart` (and the hooks that call it) actually need — an `AgentPart` or
|
|
2
|
+
* a `ForeignPart` both satisfy it, so this is the widened constraint, not a new closed union. */
|
|
3
|
+
export type PartLike = {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly type: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function mergePart<TPart extends PartLike>(parts: readonly TPart[], next: TPart): TPart[];
|
|
8
|
+
//# sourceMappingURL=merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/agent/merge.ts"],"names":[],"mappings":"AA+BA;iGACiG;AACjG,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAgBrE,wBAAgB,SAAS,CAAC,KAAK,SAAS,QAAQ,EAAE,KAAK,EAAE,SAAS,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,GAAG,KAAK,EAAE,CAiB/F"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
function isTextLikeType(type) {
|
|
2
|
+
return type === "text" || type === "reasoning";
|
|
3
|
+
}
|
|
4
|
+
function spliceText(existing, next) {
|
|
5
|
+
const offset = next.offset ?? existing.text.length;
|
|
6
|
+
return existing.text.slice(0, offset) + next.text + existing.text.slice(offset + next.text.length);
|
|
7
|
+
}
|
|
8
|
+
function mergePart(parts, next) {
|
|
9
|
+
const index = parts.findIndex((part) => part.id === next.id);
|
|
10
|
+
if (index === -1) return [...parts, next];
|
|
11
|
+
const existing = parts[index];
|
|
12
|
+
const spliceable = existing.type === next.type && isTextLikeType(next.type);
|
|
13
|
+
const merged = spliceable ? {
|
|
14
|
+
...next,
|
|
15
|
+
text: spliceText(existing, next)
|
|
16
|
+
} : next;
|
|
17
|
+
const out = parts.slice();
|
|
18
|
+
out[index] = merged;
|
|
19
|
+
return out;
|
|
20
|
+
}
|
|
21
|
+
export {
|
|
22
|
+
mergePart
|
|
23
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"part-list.d.ts","sourceRoot":"","sources":["../../src/agent/part-list.tsx"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAGhC,OAAO,KAAK,EACV,SAAS,EAMV,MAAM,SAAS,CAAA;AAIhB,MAAM,MAAM,gBAAgB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI,CAAC,KAAK,EAAE;IAC1E,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACtC,KAAK,EAAE,MAAM,CAAA;CACd,KAAK,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;AAExB,MAAM,MAAM,qBAAqB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI,CAAC,KAAK,EAAE;IAC/E,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,WAAW,CAAA;KAAE,CAAC,CAAA;IAC3C,KAAK,EAAE,MAAM,CAAA;CACd,KAAK,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;AAExB,MAAM,MAAM,oBAAoB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI,CAAC,KAAK,EAAE;IAC9E,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACtC,KAAK,EAAE,MAAM,CAAA;CACd,KAAK,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;AAExB,MAAM,MAAM,kBAAkB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI,CAAC,KAAK,EAAE;IAC5E,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAA;IACxC,KAAK,EAAE,MAAM,CAAA;CACd,KAAK,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;AAExB,MAAM,MAAM,iBAAiB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI,CAAC,KAAK,EAAE;IAC3E,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;IACvC,KAAK,EAAE,MAAM,CAAA;CACd,KAAK,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;AAExB;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI;IACpE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAA;IACtC,QAAQ,CAAC,SAAS,EAAE,qBAAqB,CAAC,KAAK,CAAC,CAAA;IAChD,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC,KAAK,CAAC,CAAA;IAC1C,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAA;IAC1C,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAA;CACzC,CAAA;
|
|
1
|
+
{"version":3,"file":"part-list.d.ts","sourceRoot":"","sources":["../../src/agent/part-list.tsx"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAGhC,OAAO,KAAK,EACV,SAAS,EAMV,MAAM,SAAS,CAAA;AAIhB,MAAM,MAAM,gBAAgB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI,CAAC,KAAK,EAAE;IAC1E,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACtC,KAAK,EAAE,MAAM,CAAA;CACd,KAAK,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;AAExB,MAAM,MAAM,qBAAqB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI,CAAC,KAAK,EAAE;IAC/E,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,WAAW,CAAA;KAAE,CAAC,CAAA;IAC3C,KAAK,EAAE,MAAM,CAAA;CACd,KAAK,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;AAExB,MAAM,MAAM,oBAAoB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI,CAAC,KAAK,EAAE;IAC9E,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACtC,KAAK,EAAE,MAAM,CAAA;CACd,KAAK,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;AAExB,MAAM,MAAM,kBAAkB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI,CAAC,KAAK,EAAE;IAC5E,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAA;KAAE,CAAC,CAAA;IACxC,KAAK,EAAE,MAAM,CAAA;CACd,KAAK,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;AAExB,MAAM,MAAM,iBAAiB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI,CAAC,KAAK,EAAE;IAC3E,IAAI,EAAE,OAAO,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAAA;IACvC,KAAK,EAAE,MAAM,CAAA;CACd,KAAK,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;AAExB;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI;IACpE,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAA;IACtC,QAAQ,CAAC,SAAS,EAAE,qBAAqB,CAAC,KAAK,CAAC,CAAA;IAChD,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC,KAAK,CAAC,CAAA;IAC1C,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC,KAAK,CAAC,CAAA;IAC1C,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAA;CACzC,CAAA;AAqJD,MAAM,MAAM,aAAa,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI;IAC/D,iDAAiD;IACjD,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,CAAA;IACvB;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAA;CACzD,CAAA;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,QAAQ,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,EAAE,EAC5D,KAAK,EACL,UAAU,GACX,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,CAgEpC"}
|
package/dist/agent/part-list.js
CHANGED
|
@@ -22,6 +22,10 @@ const CODE_BLOCK_STYLE = {
|
|
|
22
22
|
padding: "var(--vx-space-agent-code-inset)",
|
|
23
23
|
overflowX: "auto"
|
|
24
24
|
};
|
|
25
|
+
const STATUS_LINE_STYLE = {
|
|
26
|
+
marginTop: "var(--vx-space-agent-part-gap-top)",
|
|
27
|
+
color: VX.status.bad
|
|
28
|
+
};
|
|
25
29
|
function DefaultText({ part }) {
|
|
26
30
|
return /* @__PURE__ */ jsx(
|
|
27
31
|
"div",
|
|
@@ -56,7 +60,13 @@ function DefaultToolCall({ part }) {
|
|
|
56
60
|
return /* @__PURE__ */ jsxs("div", { className: "basalt-agent-tool", style: RAIL_STYLE, children: [
|
|
57
61
|
/* @__PURE__ */ jsx("span", { className: "basalt-agent-tool-name", style: MICRO_LABEL_STYLE, children: part.toolName }),
|
|
58
62
|
/* @__PURE__ */ jsx("pre", { className: "basalt-agent-tool-input", style: CODE_BLOCK_STYLE, children: JSON.stringify(part.input, null, 2) }),
|
|
59
|
-
part.output !== void 0 && /* @__PURE__ */ jsx("pre", { className: "basalt-agent-tool-
|
|
63
|
+
part.state === "output-error" && part.input === void 0 && part.rawInput !== void 0 && /* @__PURE__ */ jsx("pre", { className: "basalt-agent-tool-raw-input", style: CODE_BLOCK_STYLE, children: JSON.stringify(part.rawInput, null, 2) }),
|
|
64
|
+
part.state === "output-available" && /* @__PURE__ */ jsx("pre", { className: "basalt-agent-tool-output", style: CODE_BLOCK_STYLE, children: JSON.stringify(part.output, null, 2) }),
|
|
65
|
+
part.state === "output-error" && /* @__PURE__ */ jsx("div", { className: "basalt-agent-tool-error", role: "alert", style: STATUS_LINE_STYLE, children: part.errorText }),
|
|
66
|
+
part.state === "output-denied" && /* @__PURE__ */ jsxs("div", { className: "basalt-agent-tool-denied", style: STATUS_LINE_STYLE, children: [
|
|
67
|
+
"Denied",
|
|
68
|
+
part.approval.reason !== void 0 ? `: ${part.approval.reason}` : ""
|
|
69
|
+
] })
|
|
60
70
|
] });
|
|
61
71
|
}
|
|
62
72
|
function DefaultSource({ part }) {
|
|
@@ -109,23 +119,23 @@ function PartList({
|
|
|
109
119
|
return null;
|
|
110
120
|
case "text": {
|
|
111
121
|
const Render = renderers.text;
|
|
112
|
-
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Render, { part, index }) },
|
|
122
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Render, { part, index }) }, part.id);
|
|
113
123
|
}
|
|
114
124
|
case "reasoning": {
|
|
115
125
|
const Render = renderers.reasoning;
|
|
116
|
-
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Render, { part, index }) },
|
|
126
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Render, { part, index }) }, part.id);
|
|
117
127
|
}
|
|
118
128
|
case "tool": {
|
|
119
129
|
const Render = renderers.tool;
|
|
120
|
-
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Render, { part, index }) },
|
|
130
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Render, { part, index }) }, part.id);
|
|
121
131
|
}
|
|
122
132
|
case "source": {
|
|
123
133
|
const Render = renderers.source;
|
|
124
|
-
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Render, { part, index }) },
|
|
134
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Render, { part, index }) }, part.id);
|
|
125
135
|
}
|
|
126
136
|
case "error": {
|
|
127
137
|
const Render = renderers.error;
|
|
128
|
-
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Render, { part, index }) },
|
|
138
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(Render, { part, index }) }, part.id);
|
|
129
139
|
}
|
|
130
140
|
default:
|
|
131
141
|
return assertNever(part);
|
package/dist/agent/parts.d.ts
CHANGED
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
* explicitly and carry NO t.Object/t.Union response schema. Validate at yield-time. See
|
|
10
10
|
* agent/rules/basalt-agent.md for the full doctrine.
|
|
11
11
|
*
|
|
12
|
+
* Part identity: every variant carries a stable `id` (see `PartBase`). Transports are permitted to
|
|
13
|
+
* yield a DRAFT — `id` omitted — via `AgentPartDraft`; the consuming hooks (or `withPartIds`)
|
|
14
|
+
* normalize a draft into a fully-identified part before it is ever accumulated. `parseAgentPart`
|
|
15
|
+
* validates the FULL (identified) shape — a draft is a separate, narrower concern.
|
|
16
|
+
*
|
|
12
17
|
* @example
|
|
13
18
|
* import type { AgentPart } from 'basalt-ui/agent'
|
|
14
19
|
* function describe(p: AgentPart): string {
|
|
@@ -23,49 +28,110 @@
|
|
|
23
28
|
* }
|
|
24
29
|
* }
|
|
25
30
|
*/
|
|
31
|
+
/** Every AgentPart variant carries a stable id — the addressing key for `mergePart`/`coalesceParts`. */
|
|
32
|
+
type PartBase = {
|
|
33
|
+
readonly id: string;
|
|
34
|
+
};
|
|
26
35
|
/**
|
|
27
36
|
* Emitted once at stream start, carrying the run id and an opaque token a transport can use to
|
|
28
37
|
* resume this run after a disconnect. Not renderable content — UI code should treat it as a
|
|
29
38
|
* no-op signal, not conversation content.
|
|
30
39
|
*/
|
|
31
|
-
export type StartPart = {
|
|
40
|
+
export type StartPart = PartBase & {
|
|
32
41
|
readonly type: 'start';
|
|
33
42
|
readonly runId: string;
|
|
34
43
|
readonly resumeToken?: string;
|
|
35
44
|
};
|
|
36
|
-
/**
|
|
37
|
-
|
|
45
|
+
/**
|
|
46
|
+
* A streamed text fragment from the assistant. `offset` is the character position of this delta
|
|
47
|
+
* inside its part (undefined = append at the tail) — the mechanism `mergePart` uses to splice a
|
|
48
|
+
* replayed delta in place rather than duplicating it.
|
|
49
|
+
*/
|
|
50
|
+
export type TextPart = PartBase & {
|
|
38
51
|
readonly type: 'text';
|
|
39
52
|
readonly text: string;
|
|
53
|
+
readonly offset?: number;
|
|
40
54
|
};
|
|
41
|
-
/** An internal reasoning/thinking fragment (may be hidden in the UI). */
|
|
42
|
-
export type ReasoningPart = {
|
|
55
|
+
/** An internal reasoning/thinking fragment (may be hidden in the UI). Same `offset` mechanism as TextPart. */
|
|
56
|
+
export type ReasoningPart = PartBase & {
|
|
43
57
|
readonly type: 'reasoning';
|
|
44
58
|
readonly text: string;
|
|
59
|
+
readonly offset?: number;
|
|
45
60
|
};
|
|
46
|
-
/**
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
61
|
+
/** The nested approval envelope — mirrors the SDK's shape verbatim, never flattened. */
|
|
62
|
+
type ToolApproval = {
|
|
63
|
+
readonly id: string;
|
|
64
|
+
readonly approved?: boolean;
|
|
65
|
+
readonly reason?: string;
|
|
66
|
+
readonly isAutomatic?: boolean;
|
|
67
|
+
readonly signature?: string;
|
|
68
|
+
};
|
|
69
|
+
type ToolCallBase = PartBase & {
|
|
55
70
|
readonly type: 'tool';
|
|
71
|
+
/** Required on all seven states (was optional — see parts.ts history). */
|
|
72
|
+
readonly toolCallId: string;
|
|
56
73
|
readonly toolName: string;
|
|
57
|
-
|
|
58
|
-
readonly
|
|
59
|
-
readonly
|
|
74
|
+
/** Wall-clock time from first sighting of this toolCallId to its terminal state. */
|
|
75
|
+
readonly durationMs?: number;
|
|
76
|
+
readonly providerExecuted?: boolean;
|
|
60
77
|
};
|
|
78
|
+
export type ToolCallPart = (ToolCallBase & {
|
|
79
|
+
readonly state: 'input-streaming';
|
|
80
|
+
readonly input?: unknown;
|
|
81
|
+
}) | (ToolCallBase & {
|
|
82
|
+
readonly state: 'input-available';
|
|
83
|
+
readonly input: unknown;
|
|
84
|
+
}) | (ToolCallBase & {
|
|
85
|
+
readonly state: 'approval-requested';
|
|
86
|
+
readonly input: unknown;
|
|
87
|
+
readonly approval: ToolApproval & {
|
|
88
|
+
readonly approved?: never;
|
|
89
|
+
readonly reason?: never;
|
|
90
|
+
};
|
|
91
|
+
}) | (ToolCallBase & {
|
|
92
|
+
readonly state: 'approval-responded';
|
|
93
|
+
readonly input: unknown;
|
|
94
|
+
readonly approval: ToolApproval & {
|
|
95
|
+
readonly approved: boolean;
|
|
96
|
+
};
|
|
97
|
+
}) | (ToolCallBase & {
|
|
98
|
+
readonly state: 'output-available';
|
|
99
|
+
readonly input: unknown;
|
|
100
|
+
readonly output: unknown;
|
|
101
|
+
readonly preliminary?: boolean;
|
|
102
|
+
readonly approval?: ToolApproval & {
|
|
103
|
+
readonly approved?: true;
|
|
104
|
+
};
|
|
105
|
+
}) | (ToolCallBase & {
|
|
106
|
+
readonly state: 'output-error';
|
|
107
|
+
readonly input?: unknown;
|
|
108
|
+
/** The SDK's field name — there is no field named `error` anywhere in the union. */
|
|
109
|
+
readonly errorText: string;
|
|
110
|
+
/** The only place the raw, un-parsed input survives — what lets a UI render a call whose input never validated. */
|
|
111
|
+
readonly rawInput?: unknown;
|
|
112
|
+
readonly approval?: ToolApproval & {
|
|
113
|
+
readonly approved?: true;
|
|
114
|
+
};
|
|
115
|
+
}) | (ToolCallBase & {
|
|
116
|
+
readonly state: 'output-denied';
|
|
117
|
+
readonly input: unknown;
|
|
118
|
+
readonly approval: ToolApproval & {
|
|
119
|
+
readonly approved: false;
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
export type ToolCallState = ToolCallPart['state'];
|
|
123
|
+
/** The three states a tool call can never leave — see `isToolCallSettled`. */
|
|
124
|
+
export declare const TERMINAL_TOOL_STATES: readonly ["output-available", "output-error", "output-denied"];
|
|
125
|
+
/** True once a tool call has reached one of `TERMINAL_TOOL_STATES` — no further state transition. */
|
|
126
|
+
export declare function isToolCallSettled(part: ToolCallPart): boolean;
|
|
61
127
|
/** A cited source URL referenced by the assistant. */
|
|
62
|
-
export type SourcePart = {
|
|
128
|
+
export type SourcePart = PartBase & {
|
|
63
129
|
readonly type: 'source';
|
|
64
130
|
readonly url: string;
|
|
65
131
|
readonly title?: string;
|
|
66
132
|
};
|
|
67
133
|
/** A fatal or recoverable error emitted in-stream by the agent. */
|
|
68
|
-
export type ErrorPart = {
|
|
134
|
+
export type ErrorPart = PartBase & {
|
|
69
135
|
readonly type: 'error';
|
|
70
136
|
readonly message: string;
|
|
71
137
|
};
|
|
@@ -73,12 +139,24 @@ export type ErrorPart = {
|
|
|
73
139
|
* The complete discriminated union of all structured agent stream parts.
|
|
74
140
|
*
|
|
75
141
|
* @example
|
|
76
|
-
* const part: AgentPart = { type: 'text', text: 'Hello' }
|
|
142
|
+
* const part: AgentPart = { id: 'p1', type: 'text', text: 'Hello' }
|
|
77
143
|
*/
|
|
78
144
|
export type AgentPart = StartPart | TextPart | ReasoningPart | ToolCallPart | SourcePart | ErrorPart;
|
|
145
|
+
/**
|
|
146
|
+
* An AgentPart with `id` optional — the shape a transport is allowed to yield. The naked type
|
|
147
|
+
* parameter (not `AgentPart extends unknown ? ... : never` written some other way) is deliberate:
|
|
148
|
+
* it makes the conditional type distribute over the AgentPart union member-by-member, so
|
|
149
|
+
* `Drafted<AgentPart>` is `Drafted<StartPart> | Drafted<TextPart> | ...` rather than one flattened
|
|
150
|
+
* (and wrong) shape.
|
|
151
|
+
*/
|
|
152
|
+
export type Drafted<T> = T extends unknown ? Omit<T, 'id'> & {
|
|
153
|
+
readonly id?: string;
|
|
154
|
+
} : never;
|
|
155
|
+
export type AgentPartDraft = Drafted<AgentPart>;
|
|
79
156
|
/**
|
|
80
157
|
* Runtime type-narrowing guard: validates an unknown value against the AgentPart discriminated
|
|
81
|
-
* union and returns the narrowed type or null when validation fails.
|
|
158
|
+
* union and returns the narrowed type or null when validation fails. Validates the FULL
|
|
159
|
+
* (identified) shape — an `id`-less draft is a separate concern handled by `withPartIds`.
|
|
82
160
|
*
|
|
83
161
|
* @example
|
|
84
162
|
* const raw = JSON.parse(line)
|
|
@@ -88,4 +166,5 @@ export type AgentPart = StartPart | TextPart | ReasoningPart | ToolCallPart | So
|
|
|
88
166
|
export declare function parseAgentPart(raw: unknown): AgentPart | null;
|
|
89
167
|
/** Type guard: narrows an unknown value to StartPart. */
|
|
90
168
|
export declare function isStartPart(part: unknown): part is StartPart;
|
|
169
|
+
export {};
|
|
91
170
|
//# sourceMappingURL=parts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parts.d.ts","sourceRoot":"","sources":["../../src/agent/parts.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"parts.d.ts","sourceRoot":"","sources":["../../src/agent/parts.ts"],"names":[],"mappings":"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"}
|