basalt-ui 1.11.0 → 1.13.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 +21 -21
- package/CHANGELOG.md +32 -0
- package/README.md +63 -51
- package/agent/rules/basalt-agent.md +14 -0
- package/agent/rules/basalt-content.md +16 -3
- package/configs/oxlint-plugin.js +7 -3
- package/configs/oxlint-plugin.test.ts +34 -5
- package/configs/oxlint.json +4 -4
- package/dist/agent/adapter.d.ts +150 -0
- package/dist/agent/adapter.d.ts.map +1 -0
- package/dist/agent/adapter.js +482 -0
- package/dist/agent/adapter.test.d.ts +2 -0
- package/dist/agent/adapter.test.d.ts.map +1 -0
- package/dist/agent/ai-sdk-transport.d.ts.map +1 -1
- package/dist/agent/ai-sdk-transport.js +6 -2
- package/dist/agent/ai-sdk-transport.test.d.ts +2 -0
- package/dist/agent/ai-sdk-transport.test.d.ts.map +1 -0
- package/dist/agent/coalesce.d.ts +20 -4
- package/dist/agent/coalesce.d.ts.map +1 -1
- package/dist/agent/coalesce.js +76 -8
- package/dist/agent/coalesce.test.d.ts +2 -0
- package/dist/agent/coalesce.test.d.ts.map +1 -0
- package/dist/agent/foreign.test.d.ts +2 -0
- package/dist/agent/foreign.test.d.ts.map +1 -0
- package/dist/agent/id.d.ts +78 -0
- package/dist/agent/id.d.ts.map +1 -1
- package/dist/agent/id.js +30 -0
- package/dist/agent/id.test.d.ts +2 -0
- package/dist/agent/id.test.d.ts.map +1 -0
- package/dist/agent/index.d.ts +2 -0
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +3 -0
- package/dist/agent/merge.d.ts.map +1 -1
- package/dist/agent/merge.js +19 -7
- package/dist/agent/merge.test.d.ts +2 -0
- package/dist/agent/merge.test.d.ts.map +1 -0
- package/dist/agent/part-list.d.ts +49 -34
- package/dist/agent/part-list.d.ts.map +1 -1
- package/dist/agent/part-list.js +42 -6
- package/dist/agent/part-list.test.d.ts +2 -0
- package/dist/agent/part-list.test.d.ts.map +1 -0
- package/dist/agent/parts.d.ts +46 -10
- package/dist/agent/parts.d.ts.map +1 -1
- package/dist/agent/parts.js +16 -6
- package/dist/agent/parts.test.d.ts +2 -0
- package/dist/agent/parts.test.d.ts.map +1 -0
- package/dist/agent/thread.d.ts +18 -0
- package/dist/agent/thread.d.ts.map +1 -1
- package/dist/agent/thread.js +8 -2
- package/dist/agent/thread.test.d.ts +2 -0
- package/dist/agent/thread.test.d.ts.map +1 -0
- package/dist/agent/transport.test.d.ts +2 -0
- package/dist/agent/transport.test.d.ts.map +1 -0
- package/dist/agent/use-agent-stream.d.ts.map +1 -1
- package/dist/agent/use-agent-stream.js +2 -2
- package/dist/agent/use-agent-stream.test.d.ts +2 -0
- package/dist/agent/use-agent-stream.test.d.ts.map +1 -0
- package/dist/agent/use-agent-thread-runs.d.ts +24 -3
- package/dist/agent/use-agent-thread-runs.d.ts.map +1 -1
- package/dist/agent/use-agent-thread-runs.foreign.test.d.ts +2 -0
- package/dist/agent/use-agent-thread-runs.foreign.test.d.ts.map +1 -0
- package/dist/agent/use-agent-thread-runs.js +55 -15
- package/dist/agent/use-agent-thread-runs.resume.test.d.ts +2 -0
- package/dist/agent/use-agent-thread-runs.resume.test.d.ts.map +1 -0
- package/dist/agent/use-agent-thread-runs.test.d.ts +2 -0
- package/dist/agent/use-agent-thread-runs.test.d.ts.map +1 -0
- package/dist/agent/use-agent-thread-runs.wedge.test.d.ts +2 -0
- package/dist/agent/use-agent-thread-runs.wedge.test.d.ts.map +1 -0
- package/dist/agent-chat/composer.d.ts +130 -8
- package/dist/agent-chat/composer.d.ts.map +1 -1
- package/dist/agent-chat/composer.js +189 -23
- package/dist/agent-chat/composer.test.d.ts +2 -0
- package/dist/agent-chat/composer.test.d.ts.map +1 -0
- package/dist/agent-chat/index.d.ts +5 -1
- package/dist/agent-chat/index.d.ts.map +1 -1
- package/dist/agent-chat/index.js +2 -0
- package/dist/agent-chat/message-affordances.d.ts +59 -0
- package/dist/agent-chat/message-affordances.d.ts.map +1 -0
- package/dist/agent-chat/message-affordances.js +7 -0
- package/dist/agent-chat/relative-time.d.ts +27 -0
- package/dist/agent-chat/relative-time.d.ts.map +1 -0
- package/dist/agent-chat/relative-time.js +27 -0
- package/dist/agent-chat/relative-time.test.d.ts +2 -0
- package/dist/agent-chat/relative-time.test.d.ts.map +1 -0
- package/dist/agent-chat/thread-detail-panel.d.ts.map +1 -1
- package/dist/agent-chat/thread-detail-panel.js +1 -1
- package/dist/agent-chat/thread-feed-row.d.ts +65 -0
- package/dist/agent-chat/thread-feed-row.d.ts.map +1 -0
- package/dist/agent-chat/thread-feed-row.js +156 -0
- package/dist/agent-chat/thread-feed-row.test.d.ts +2 -0
- package/dist/agent-chat/thread-feed-row.test.d.ts.map +1 -0
- package/dist/agent-chat/thread-feed.d.ts +34 -5
- package/dist/agent-chat/thread-feed.d.ts.map +1 -1
- package/dist/agent-chat/thread-feed.js +52 -19
- package/dist/agent-chat/thread-feed.test.d.ts +2 -0
- package/dist/agent-chat/thread-feed.test.d.ts.map +1 -0
- package/dist/agent-chat/thread-message.d.ts +183 -2
- package/dist/agent-chat/thread-message.d.ts.map +1 -1
- package/dist/agent-chat/thread-message.js +329 -37
- package/dist/agent-chat/thread-message.test.d.ts +2 -0
- package/dist/agent-chat/thread-message.test.d.ts.map +1 -0
- package/dist/agent-chat/thread-outcome-card.d.ts.map +1 -1
- package/dist/agent-chat/thread-outcome-card.js +1 -16
- package/dist/agent-chat/thread-workspace.d.ts +14 -2
- package/dist/agent-chat/thread-workspace.d.ts.map +1 -1
- package/dist/agent-chat/thread-workspace.js +30 -4
- package/dist/agent-chat/thread-workspace.test.d.ts +2 -0
- package/dist/agent-chat/thread-workspace.test.d.ts.map +1 -0
- package/dist/agent-chat/tool-chip.test.d.ts +2 -0
- package/dist/agent-chat/tool-chip.test.d.ts.map +1 -0
- package/dist/agent-chat/virtualize.d.ts +123 -0
- package/dist/agent-chat/virtualize.d.ts.map +1 -0
- package/dist/agent-chat/virtualize.js +9 -0
- package/dist/agent-chat/virtualize.type-guard.test.d.ts +2 -0
- package/dist/agent-chat/virtualize.type-guard.test.d.ts.map +1 -0
- package/dist/charts/primitives/ChartFrame.test.d.ts +2 -0
- package/dist/charts/primitives/ChartFrame.test.d.ts.map +1 -0
- package/dist/charts/utils/domain.test.d.ts +2 -0
- package/dist/charts/utils/domain.test.d.ts.map +1 -0
- package/dist/cli/check-theme.test.d.ts +2 -0
- package/dist/cli/check-theme.test.d.ts.map +1 -0
- package/dist/cli/help.test.d.ts +2 -0
- package/dist/cli/help.test.d.ts.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/init-sync.test.d.ts +2 -0
- package/dist/cli/init-sync.test.d.ts.map +1 -0
- package/dist/cli/placement-engine.test.d.ts +2 -0
- package/dist/cli/placement-engine.test.d.ts.map +1 -0
- package/dist/cli/tarball-parity.test.d.ts +2 -0
- package/dist/cli/tarball-parity.test.d.ts.map +1 -0
- package/dist/cli/template-format.test.d.ts +2 -0
- package/dist/cli/template-format.test.d.ts.map +1 -0
- package/dist/cli/template-ledger.test.d.ts +2 -0
- package/dist/cli/template-ledger.test.d.ts.map +1 -0
- package/dist/cli/tokens-css.test.d.ts +2 -0
- package/dist/cli/tokens-css.test.d.ts.map +1 -0
- package/dist/content/article-actions.test.d.ts +2 -0
- package/dist/content/article-actions.test.d.ts.map +1 -0
- package/dist/content/article-model.test.d.ts +2 -0
- package/dist/content/article-model.test.d.ts.map +1 -0
- package/dist/content/block-split.test.d.ts +2 -0
- package/dist/content/block-split.test.d.ts.map +1 -0
- package/dist/content/fence-block.d.ts +37 -10
- package/dist/content/fence-block.d.ts.map +1 -1
- package/dist/content/fence-block.js +80 -14
- package/dist/content/heading-components.d.ts.map +1 -1
- package/dist/content/heading-components.js +7 -4
- package/dist/content/heading-components.test.d.ts +2 -0
- package/dist/content/heading-components.test.d.ts.map +1 -0
- package/dist/content/index.d.ts +6 -3
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +5 -1
- package/dist/content/markdown.d.ts +101 -14
- package/dist/content/markdown.d.ts.map +1 -1
- package/dist/content/markdown.js +141 -28
- package/dist/content/markdown.test.d.ts +2 -0
- package/dist/content/markdown.test.d.ts.map +1 -0
- package/dist/content/prose.module.css.test.d.ts +2 -0
- package/dist/content/prose.module.css.test.d.ts.map +1 -0
- package/dist/content/sanitize.d.ts +170 -0
- package/dist/content/sanitize.d.ts.map +1 -0
- package/dist/content/sanitize.js +178 -0
- package/dist/content/sanitize.test.d.ts +2 -0
- package/dist/content/sanitize.test.d.ts.map +1 -0
- package/dist/content/slug.test.d.ts +2 -0
- package/dist/content/slug.test.d.ts.map +1 -0
- package/dist/dashboard/stat-card.test.d.ts +2 -0
- package/dist/dashboard/stat-card.test.d.ts.map +1 -0
- package/dist/data/index.d.ts +5 -1
- package/dist/data/index.d.ts.map +1 -1
- package/dist/data/virtual-list.d.ts.map +1 -1
- package/dist/data/virtual.d.ts +2 -1
- package/dist/data/virtual.d.ts.map +1 -1
- package/dist/guard/check-source.test.d.ts +2 -0
- package/dist/guard/check-source.test.d.ts.map +1 -0
- package/dist/guard/guard-hook.test.d.ts +2 -0
- package/dist/guard/guard-hook.test.d.ts.map +1 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -1
- package/dist/provider/index.test.d.ts +2 -0
- package/dist/provider/index.test.d.ts.map +1 -0
- package/dist/provider/lab-theme.test.d.ts +2 -0
- package/dist/provider/lab-theme.test.d.ts.map +1 -0
- package/dist/router-tanstack/multi-search-param-store.test.d.ts +2 -0
- package/dist/router-tanstack/multi-search-param-store.test.d.ts.map +1 -0
- package/dist/styles.floor.test.d.ts +2 -0
- package/dist/styles.floor.test.d.ts.map +1 -0
- package/dist/surfaces.d.ts +5 -5
- package/dist/surfaces.d.ts.map +1 -1
- package/dist/surfaces.js +14 -4
- package/dist/theme/border-coverage.test.d.ts +18 -0
- package/dist/theme/border-coverage.test.d.ts.map +1 -0
- package/dist/theme/contrast.test.d.ts +2 -0
- package/dist/theme/contrast.test.d.ts.map +1 -0
- package/dist/theme/density-option.test.d.ts +2 -0
- package/dist/theme/density-option.test.d.ts.map +1 -0
- package/dist/theme/density-relations.test.d.ts +2 -0
- package/dist/theme/density-relations.test.d.ts.map +1 -0
- package/dist/theme/derive-theme.test.d.ts +2 -0
- package/dist/theme/derive-theme.test.d.ts.map +1 -0
- package/dist/theme/fonts-option.test.d.ts +2 -0
- package/dist/theme/fonts-option.test.d.ts.map +1 -0
- package/dist/theme/radius-option.test.d.ts +2 -0
- package/dist/theme/radius-option.test.d.ts.map +1 -0
- package/dist/theme/radius.test.d.ts +2 -0
- package/dist/theme/radius.test.d.ts.map +1 -0
- package/dist/theme/shadow-surfaces.test.d.ts +26 -0
- package/dist/theme/shadow-surfaces.test.d.ts.map +1 -0
- package/dist/theme/spacing.test.d.ts +2 -0
- package/dist/theme/spacing.test.d.ts.map +1 -0
- package/dist/theme/use-basalt-spacing.test.d.ts +2 -0
- package/dist/theme/use-basalt-spacing.test.d.ts.map +1 -0
- package/dist/theme-lab/derive-controls.test.d.ts +2 -0
- package/dist/theme-lab/derive-controls.test.d.ts.map +1 -0
- package/dist/theme-lab/derive-state.test.d.ts +2 -0
- package/dist/theme-lab/derive-state.test.d.ts.map +1 -0
- package/dist/theme-lab/theme-lab.test.d.ts +2 -0
- package/dist/theme-lab/theme-lab.test.d.ts.map +1 -0
- package/dist/tokens/build-fonts-css.test.d.ts +2 -0
- package/dist/tokens/build-fonts-css.test.d.ts.map +1 -0
- package/dist/tokens/build-radius-css.test.d.ts +2 -0
- package/dist/tokens/build-radius-css.test.d.ts.map +1 -0
- package/dist/tokens/density.test.d.ts +2 -0
- package/dist/tokens/density.test.d.ts.map +1 -0
- package/dist/tokens/derive-radius.test.d.ts +2 -0
- package/dist/tokens/derive-radius.test.d.ts.map +1 -0
- package/dist/tokens/derive.test.d.ts +2 -0
- package/dist/tokens/derive.test.d.ts.map +1 -0
- package/dist/tokens/palette.test.d.ts +2 -0
- package/dist/tokens/palette.test.d.ts.map +1 -0
- package/dist/vite-color-mix.test.d.ts +2 -0
- package/dist/vite-color-mix.test.d.ts.map +1 -0
- package/dist/vite.test.d.ts +2 -0
- package/dist/vite.test.d.ts.map +1 -0
- package/llms.txt +9 -9
- package/package.json +7 -2
- package/src/agent/adapter.test.ts +1640 -0
- package/src/agent/adapter.ts +945 -0
- package/src/agent/ai-sdk-transport.test.ts +117 -26
- package/src/agent/ai-sdk-transport.ts +8 -2
- package/src/agent/coalesce.test.ts +202 -9
- package/src/agent/coalesce.ts +126 -15
- package/src/agent/foreign.test.ts +5 -1
- package/src/agent/id.test.ts +101 -3
- package/src/agent/id.ts +118 -0
- package/src/agent/index.ts +8 -0
- package/src/agent/merge.test.ts +87 -0
- package/src/agent/merge.ts +57 -10
- package/src/agent/part-list.test.tsx +31 -1
- package/src/agent/part-list.tsx +77 -29
- package/src/agent/parts.test.ts +121 -4
- package/src/agent/parts.ts +78 -17
- package/src/agent/thread.test.ts +75 -2
- package/src/agent/thread.ts +25 -1
- package/src/agent/use-agent-stream.test.tsx +31 -5
- package/src/agent/use-agent-stream.ts +6 -3
- package/src/agent/use-agent-thread-runs.foreign.test.tsx +5 -0
- package/src/agent/use-agent-thread-runs.resume.test.tsx +16 -11
- package/src/agent/use-agent-thread-runs.test.tsx +356 -17
- package/src/agent/use-agent-thread-runs.ts +159 -23
- package/src/agent/use-agent-thread-runs.wedge.test.tsx +93 -7
- package/src/agent-chat/composer.test.tsx +924 -0
- package/src/agent-chat/composer.tsx +521 -52
- package/src/agent-chat/index.ts +13 -1
- package/src/agent-chat/message-affordances.ts +61 -0
- package/src/agent-chat/relative-time.test.ts +95 -0
- package/src/agent-chat/relative-time.ts +55 -0
- package/src/agent-chat/thread-detail-panel.tsx +3 -1
- package/src/agent-chat/thread-feed-row.test.tsx +510 -0
- package/src/agent-chat/thread-feed-row.tsx +274 -0
- package/src/agent-chat/thread-feed.test.tsx +241 -0
- package/src/agent-chat/thread-feed.tsx +119 -18
- package/src/agent-chat/thread-message.test.tsx +1078 -4
- package/src/agent-chat/thread-message.tsx +795 -42
- package/src/agent-chat/thread-outcome-card.tsx +1 -25
- package/src/agent-chat/thread-workspace.test.tsx +169 -0
- package/src/agent-chat/thread-workspace.tsx +70 -6
- package/src/agent-chat/virtualize.ts +132 -0
- package/src/agent-chat/virtualize.type-guard.test.ts +49 -0
- package/src/cli/index.ts +0 -1
- package/src/cli/template-format.test.ts +2 -2
- package/src/content/fence-block.tsx +242 -15
- package/src/content/heading-components.test.tsx +65 -0
- package/src/content/heading-components.tsx +26 -5
- package/src/content/index.ts +19 -3
- package/src/content/markdown.test.tsx +603 -0
- package/src/content/markdown.tsx +355 -35
- package/src/content/sanitize.test.ts +659 -0
- package/src/content/sanitize.ts +510 -0
- package/src/dashboard/stat-card.test.tsx +6 -1
- package/src/data/index.ts +5 -1
- package/src/data/virtual-list.tsx +2 -1
- package/src/data/virtual.ts +2 -1
- package/src/index.ts +18 -1
- package/src/surfaces.ts +13 -3
- package/src/theme/contrast.test.ts +1 -4
- package/src/theme/density-relations.test.ts +4 -2
- package/src/theme/fonts-option.test.ts +7 -1
- package/src/theme/shadow-surfaces.test.ts +21 -6
- package/src/theme/use-basalt-spacing.test.tsx +2 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk-transport.test.d.ts","sourceRoot":"","sources":["../../src/agent/ai-sdk-transport.test.ts"],"names":[],"mappings":""}
|
package/dist/agent/coalesce.d.ts
CHANGED
|
@@ -12,10 +12,26 @@
|
|
|
12
12
|
* wire, the SDK re-supplies `input` by reading it back off the stored invocation, and a merge that
|
|
13
13
|
* replaces wholesale rather than accumulating would lose it outright.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
15
|
+
* A settled tool part can arrive without a `toolCallId` at all — `approval-responded` plus the
|
|
16
|
+
* three terminal states all carry it as optional (see `MaybeIdentified` in `parts.ts`).
|
|
17
|
+
* `approval-responded` is where the WIRE itself omits it: the SDK's `tool-approval-response` chunk
|
|
18
|
+
* carries no `toolCallId`, only `approval.id`, so it is resolved by reverse lookup on `approval.id`
|
|
19
|
+
* instead — this maintains an `approvalId -> toolCallId` side index while folding and routes such a
|
|
20
|
+
* part through it. A part resolvable by neither key is kept as-is rather than dropped; never
|
|
21
|
+
* silently discard a part.
|
|
22
|
+
*
|
|
23
|
+
* The fold is strictly LEFT-TO-RIGHT with no backtracking: the side index only holds ids seen so
|
|
24
|
+
* far, so an unidentified `approval-responded` arriving BEFORE its `approval-requested` stays its
|
|
25
|
+
* own block and the later request opens a second one. That is deliberate, not an oversight —
|
|
26
|
+
* reconciling backwards would let the request (the later arrival) win under the "later state wins"
|
|
27
|
+
* rule and render an already-answered call as still pending, which is worse than two blocks in an
|
|
28
|
+
* ordering the wire never produces.
|
|
29
|
+
*
|
|
30
|
+
* **This function never throws.** It is public, it runs on the render path, and it folds data that
|
|
31
|
+
* came off a wire — so every anomaly (an unrecognized tool state, an unresolvable id) degrades to
|
|
32
|
+
* "keep the part as it arrived", announced in dev, rather than aborting the render. A throw here
|
|
33
|
+
* would turn one malformed chunk into a permanently dead transcript. Exhaustiveness over the tool
|
|
34
|
+
* states is still enforced, but at COMPILE time only (see `mergeToolPart`'s default branch).
|
|
19
35
|
*
|
|
20
36
|
* @example
|
|
21
37
|
* import { coalesceParts } from 'basalt-ui/agent'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coalesce.d.ts","sourceRoot":"","sources":["../../src/agent/coalesce.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"coalesce.d.ts","sourceRoot":"","sources":["../../src/agent/coalesce.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,KAAK,EAAE,SAAS,EAAyC,MAAM,SAAS,CAAA;AA8I/E,wBAAgB,aAAa,CAAC,KAAK,SAAS,SAAS,EAAE,KAAK,EAAE,SAAS,KAAK,EAAE,GAAG,KAAK,EAAE,CA+CvF"}
|
package/dist/agent/coalesce.js
CHANGED
|
@@ -2,27 +2,95 @@ function isTextLikeType(type) {
|
|
|
2
2
|
return type === "text" || type === "reasoning";
|
|
3
3
|
}
|
|
4
4
|
function resolveToolCallId(part, toolCallIdByApprovalId) {
|
|
5
|
-
if (
|
|
5
|
+
if (part.toolCallId !== void 0) return part.toolCallId;
|
|
6
6
|
const approval = "approval" in part ? part.approval : void 0;
|
|
7
7
|
return approval !== void 0 ? toolCallIdByApprovalId.get(approval.id) : void 0;
|
|
8
8
|
}
|
|
9
9
|
function registerApprovalIndex(part, toolCallIdByApprovalId) {
|
|
10
10
|
const approval = "approval" in part ? part.approval : void 0;
|
|
11
11
|
if (approval === void 0) return;
|
|
12
|
-
if (
|
|
12
|
+
if (part.toolCallId === void 0) return;
|
|
13
13
|
toolCallIdByApprovalId.set(approval.id, part.toolCallId);
|
|
14
14
|
}
|
|
15
15
|
function mergeToolPart(existing, next) {
|
|
16
16
|
const existingInput = "input" in existing ? existing.input : void 0;
|
|
17
17
|
const nextInput = "input" in next ? next.input : void 0;
|
|
18
18
|
const input = nextInput !== void 0 ? nextInput : existingInput;
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
const durationMs = next.durationMs ?? existing.durationMs;
|
|
20
|
+
const providerExecuted = next.providerExecuted ?? existing.providerExecuted;
|
|
21
|
+
const settledToolCallId = next.toolCallId ?? existing.toolCallId;
|
|
22
|
+
const common = {
|
|
23
|
+
id: next.id,
|
|
24
|
+
type: "tool",
|
|
25
|
+
toolName: next.toolName.length > 0 ? next.toolName : existing.toolName,
|
|
26
|
+
...durationMs !== void 0 ? { durationMs } : {},
|
|
27
|
+
...providerExecuted !== void 0 ? { providerExecuted } : {}
|
|
25
28
|
};
|
|
29
|
+
switch (next.state) {
|
|
30
|
+
case "input-streaming":
|
|
31
|
+
return {
|
|
32
|
+
...common,
|
|
33
|
+
toolCallId: next.toolCallId,
|
|
34
|
+
state: "input-streaming",
|
|
35
|
+
...input !== void 0 ? { input } : {}
|
|
36
|
+
};
|
|
37
|
+
case "input-available":
|
|
38
|
+
return { ...common, toolCallId: next.toolCallId, state: "input-available", input };
|
|
39
|
+
case "approval-requested":
|
|
40
|
+
return {
|
|
41
|
+
...common,
|
|
42
|
+
toolCallId: next.toolCallId,
|
|
43
|
+
state: "approval-requested",
|
|
44
|
+
input,
|
|
45
|
+
approval: next.approval
|
|
46
|
+
};
|
|
47
|
+
case "approval-responded":
|
|
48
|
+
return {
|
|
49
|
+
...common,
|
|
50
|
+
...settledToolCallId !== void 0 ? { toolCallId: settledToolCallId } : {},
|
|
51
|
+
state: "approval-responded",
|
|
52
|
+
input,
|
|
53
|
+
approval: next.approval
|
|
54
|
+
};
|
|
55
|
+
case "output-available":
|
|
56
|
+
return {
|
|
57
|
+
...common,
|
|
58
|
+
...settledToolCallId !== void 0 ? { toolCallId: settledToolCallId } : {},
|
|
59
|
+
state: "output-available",
|
|
60
|
+
input,
|
|
61
|
+
output: next.output,
|
|
62
|
+
...next.preliminary !== void 0 ? { preliminary: next.preliminary } : {},
|
|
63
|
+
...next.approval !== void 0 ? { approval: next.approval } : {}
|
|
64
|
+
};
|
|
65
|
+
case "output-error":
|
|
66
|
+
return {
|
|
67
|
+
...common,
|
|
68
|
+
...settledToolCallId !== void 0 ? { toolCallId: settledToolCallId } : {},
|
|
69
|
+
state: "output-error",
|
|
70
|
+
errorText: next.errorText,
|
|
71
|
+
...input !== void 0 ? { input } : {},
|
|
72
|
+
...next.rawInput !== void 0 ? { rawInput: next.rawInput } : {},
|
|
73
|
+
...next.approval !== void 0 ? { approval: next.approval } : {}
|
|
74
|
+
};
|
|
75
|
+
case "output-denied":
|
|
76
|
+
return {
|
|
77
|
+
...common,
|
|
78
|
+
...settledToolCallId !== void 0 ? { toolCallId: settledToolCallId } : {},
|
|
79
|
+
state: "output-denied",
|
|
80
|
+
input,
|
|
81
|
+
approval: next.approval
|
|
82
|
+
};
|
|
83
|
+
default: {
|
|
84
|
+
const unhandled = next;
|
|
85
|
+
const fallback = unhandled;
|
|
86
|
+
if (process.env["NODE_ENV"] !== "production") {
|
|
87
|
+
console.warn(
|
|
88
|
+
`[basalt] coalesceParts: unrecognized tool state ${JSON.stringify(fallback.state)} \u2014 kept, merged best-effort`
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
return { ...fallback, ...common };
|
|
92
|
+
}
|
|
93
|
+
}
|
|
26
94
|
}
|
|
27
95
|
function coalesceParts(parts) {
|
|
28
96
|
const out = [];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"coalesce.test.d.ts","sourceRoot":"","sources":["../../src/agent/coalesce.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foreign.test.d.ts","sourceRoot":"","sources":["../../src/agent/foreign.test.ts"],"names":[],"mappings":""}
|
package/dist/agent/id.d.ts
CHANGED
|
@@ -1,3 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Id-minting helpers shared across the agent layer: `mintThreadId` (a low-stakes client-side id —
|
|
3
|
+
* threads, run/chat namespaces — used by `./thread`'s `createThreadsStore`, `./adapter`'s
|
|
4
|
+
* `createAdapterThreadsStore`/`threadsStoreAdapterContract`, `./use-agent-stream`'s per-send run
|
|
5
|
+
* id, and `aiSdkTransport`'s fixed chat id), `mintMessageId` (the higher-stakes id `appendMessage`
|
|
6
|
+
* treats as its only idempotency key), and `withPartIds` (stamps sequence ids onto streamed
|
|
7
|
+
* parts). Grouped here because they're the id-minting leaves every store/hook/transport in this
|
|
8
|
+
* layer sits above — not because they share a mechanism (`mintMessageId` deliberately diverges
|
|
9
|
+
* from `mintThreadId` on rung 3; see its own doc).
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Mints a client-side id for a LOW-COLLISION-COST use: a thread id, a per-send run-id namespace, a
|
|
13
|
+
* fixed chat id — anything minted client-side that is NOT the idempotency key some write depends
|
|
14
|
+
* on. `crypto.randomUUID()` exists only in SECURE CONTEXTS (HTTPS or localhost) — a consumer served
|
|
15
|
+
* over plain HTTP on a LAN hostname (a homelab dashboard on a bare IP, a staging box) would
|
|
16
|
+
* otherwise have `create()`, about the most basic user action a thread store has, throw a plain
|
|
17
|
+
* TypeError. A store used from a browser must not throw on a user gesture — the same principle
|
|
18
|
+
* already applied twice this release (`spliceText` clamps rather than throws, `coalesceParts`
|
|
19
|
+
* degrades rather than throws).
|
|
20
|
+
*
|
|
21
|
+
* Fallback chain, each rung reached only when the one above it is unavailable:
|
|
22
|
+
* 1. `crypto.randomUUID()` — cryptographically random, RFC 4122 UUID. The normal path.
|
|
23
|
+
* 2. `crypto.getRandomValues()` — still cryptographically random; hand-assembled into a UUIDv4
|
|
24
|
+
* via `assembleUuidV4`.
|
|
25
|
+
* 3. No usable `crypto` at all (missing entirely, or missing both methods above — an old WebView,
|
|
26
|
+
* an SSR shim). NOT cryptographically random and NOT collision-resistant in general. This rung
|
|
27
|
+
* exists solely so a caller never throws on such a host. It is acceptable ONLY because an id
|
|
28
|
+
* minted here is minted a handful of times per client session and is not the idempotency key
|
|
29
|
+
* any write depends on — `ThreadsStoreAdapter.appendMessage`'s idempotency key is the MESSAGE
|
|
30
|
+
* id (see `mintMessageId`), not this one, so a collision on this rung costs a locally
|
|
31
|
+
* merged/duplicated thread (or two runs sharing a part-id namespace), not silent data loss on
|
|
32
|
+
* the append path. Do not reuse this rung for anything with a higher collision cost than that
|
|
33
|
+
* — see `mintMessageId` for the id that needs one.
|
|
34
|
+
*/
|
|
35
|
+
export declare function mintThreadId(): string;
|
|
36
|
+
/**
|
|
37
|
+
* Mints a message id — the value `ThreadsStoreAdapter.appendMessage` treats as its ONLY
|
|
38
|
+
* idempotency key (see that method's contract doc in `./adapter`). Shares `mintThreadId`'s rungs
|
|
39
|
+
* 1-2 (`crypto.randomUUID()`, then `crypto.getRandomValues()` assembled into a UUIDv4) — both are
|
|
40
|
+
* cryptographically random and collision-resistant, and rung 2 is the fix that actually matters in
|
|
41
|
+
* practice (a plain-HTTP/LAN host still has `getRandomValues`; only `randomUUID` is secure-context-
|
|
42
|
+
* gated).
|
|
43
|
+
*
|
|
44
|
+
* Rung 3 deliberately DIVERGES from `mintThreadId`: it THROWS instead of degrading to a
|
|
45
|
+
* non-random fallback. A thread id's rung-3 collision costs a locally merged/duplicated thread —
|
|
46
|
+
* annoying, recoverable, visible. A message id's collision cost is different IN KIND, not degree:
|
|
47
|
+
* `appendMessage` is idempotent on this id, so two messages that collide are not two rows, they
|
|
48
|
+
* are ONE — the second write silently no-ops and its content is gone, with nothing downstream able
|
|
49
|
+
* to tell. Degrading here would trade a loud, debuggable failure for silent, permanent data loss.
|
|
50
|
+
*
|
|
51
|
+
* This deliberately diverges from this layer's other standing rule — render-path code degrades,
|
|
52
|
+
* never throws (`spliceText` clamps, `coalesceParts` degrades, a consumer fence renderer must not
|
|
53
|
+
* take the message down) — because minting a message id is NOT render-path code. It runs once, in
|
|
54
|
+
* the write path that constructs a message before handing it to a store (`start()`,
|
|
55
|
+
* `consumeAndFinalize`'s finalize step, `finalizeStop`, `aiSdkTransport`'s per-turn user message),
|
|
56
|
+
* never inside the per-chunk accumulation/render loop those functions guard. A host with no usable
|
|
57
|
+
* `crypto` at all (missing both `randomUUID` and `getRandomValues`) is vanishingly rare — no
|
|
58
|
+
* runtime with a DOM/fetch surface worth targeting ships without a Crypto object — and an uncaught
|
|
59
|
+
* throw here is a loud, debuggable failure rather than a message silently vanishing with no trace,
|
|
60
|
+
* but WHERE it surfaces differs by call site (audited, not assumed — this paragraph previously
|
|
61
|
+
* claimed a single shared catch handled all of them, which was false):
|
|
62
|
+
* - `consumeAndFinalize`'s own assistantMessage mint runs inside that function's try/catch, so a
|
|
63
|
+
* throw there is correctly turned into `onFailureStatus` ('error' from `start()`, 'interrupted'
|
|
64
|
+
* from the mount-time resume) — a visibly stuck-then-settled run, as originally claimed.
|
|
65
|
+
* - `useAgentThreadRuns.start()`'s userMessage mint runs BEFORE any state is touched
|
|
66
|
+
* (`appendMessage`/`setStatus`/the controller registration all come after it), so a throw there
|
|
67
|
+
* is a true no-op that propagates synchronously out of `start()` itself — not a stuck run at
|
|
68
|
+
* all, since nothing ever started. See `UseAgentThreadRunsReturn.start`'s `@throws` doc.
|
|
69
|
+
* - `finalizeStop`'s stoppedMessage mint is wrapped in its own try/catch precisely so a throw
|
|
70
|
+
* here cannot wedge the thread at 'streaming' forever (stop() has already torn down this run's
|
|
71
|
+
* bookkeeping by the time finalizeStop runs, so a second stop() is always a no-op) — see
|
|
72
|
+
* `finalizeStop`'s doc for the guarded behavior and the resulting 'error' status.
|
|
73
|
+
* A stuck spinner is debuggable; silently discarded chat history is not — that half of the
|
|
74
|
+
* original claim stands regardless of which of the three paths above catches it.
|
|
75
|
+
*
|
|
76
|
+
* @throws {Error} when neither `crypto.randomUUID` nor `crypto.getRandomValues` is available.
|
|
77
|
+
*/
|
|
78
|
+
export declare function mintMessageId(): string;
|
|
1
79
|
/**
|
|
2
80
|
* withPartIds — stamps a stable id onto every draft part arriving without one.
|
|
3
81
|
*
|
package/dist/agent/id.d.ts.map
CHANGED
|
@@ -1 +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"}
|
|
1
|
+
{"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../../src/agent/id.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAmBH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAQrC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAYtC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;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
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
function assembleUuidV4(bytes) {
|
|
2
|
+
const hex = Array.from({ length: 16 }, (_, i) => {
|
|
3
|
+
const raw = bytes.at(i) ?? 0;
|
|
4
|
+
const byte = i === 6 ? raw & 15 | 64 : i === 8 ? raw & 63 | 128 : raw;
|
|
5
|
+
return byte.toString(16).padStart(2, "0");
|
|
6
|
+
}).join("");
|
|
7
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
8
|
+
}
|
|
9
|
+
function mintThreadId() {
|
|
10
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
11
|
+
return crypto.randomUUID();
|
|
12
|
+
}
|
|
13
|
+
if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
|
|
14
|
+
return assembleUuidV4(crypto.getRandomValues(new Uint8Array(16)));
|
|
15
|
+
}
|
|
16
|
+
return `id-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
17
|
+
}
|
|
18
|
+
function mintMessageId() {
|
|
19
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
20
|
+
return crypto.randomUUID();
|
|
21
|
+
}
|
|
22
|
+
if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
|
|
23
|
+
return assembleUuidV4(crypto.getRandomValues(new Uint8Array(16)));
|
|
24
|
+
}
|
|
25
|
+
throw new Error(
|
|
26
|
+
"mintMessageId: no usable crypto (both randomUUID and getRandomValues are unavailable) \u2014 refusing to mint a non-random message id, since ThreadsStoreAdapter.appendMessage treats this id as its only idempotency key and a collision would silently drop a message."
|
|
27
|
+
);
|
|
28
|
+
}
|
|
1
29
|
async function* withPartIds(runId, source) {
|
|
2
30
|
let n = 0;
|
|
3
31
|
for await (const part of source) {
|
|
@@ -10,5 +38,7 @@ async function* withPartIds(runId, source) {
|
|
|
10
38
|
}
|
|
11
39
|
}
|
|
12
40
|
export {
|
|
41
|
+
mintMessageId,
|
|
42
|
+
mintThreadId,
|
|
13
43
|
withPartIds
|
|
14
44
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id.test.d.ts","sourceRoot":"","sources":["../../src/agent/id.test.ts"],"names":[],"mappings":""}
|
package/dist/agent/index.d.ts
CHANGED
|
@@ -55,4 +55,6 @@ export { createThreadsStore } from './thread.js';
|
|
|
55
55
|
export type { AgentThread, ThreadStatus, ThreadsStore, ThreadsStoreOptions } from './thread.js';
|
|
56
56
|
export { heuristicOutcome } from './outcome.js';
|
|
57
57
|
export type { AgentOutcome, OutcomeResolver } from './outcome.js';
|
|
58
|
+
export { createAdapterThreadsStore, threadsStoreAdapterContract } from './adapter.js';
|
|
59
|
+
export type { AdapterThreadsStoreOptions, ThreadsStoreAdapter, ThreadsStoreAdapterContractCase, } from './adapter.js';
|
|
58
60
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -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,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"}
|
|
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;AAG9D,OAAO,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAA;AAClF,YAAY,EACV,0BAA0B,EAC1B,mBAAmB,EACnB,+BAA+B,GAChC,MAAM,WAAW,CAAA"}
|
package/dist/agent/index.js
CHANGED
|
@@ -12,12 +12,14 @@ import { BasaltStickToBottom } from "./stick-to-bottom.js";
|
|
|
12
12
|
import { createChatHistoryStore } from "./history.js";
|
|
13
13
|
import { createThreadsStore } from "./thread.js";
|
|
14
14
|
import { heuristicOutcome } from "./outcome.js";
|
|
15
|
+
import { createAdapterThreadsStore, threadsStoreAdapterContract } from "./adapter.js";
|
|
15
16
|
export {
|
|
16
17
|
BasaltStickToBottom,
|
|
17
18
|
PartList,
|
|
18
19
|
TERMINAL_TOOL_STATES,
|
|
19
20
|
aiSdkTransport,
|
|
20
21
|
coalesceParts,
|
|
22
|
+
createAdapterThreadsStore,
|
|
21
23
|
createChatHistoryStore,
|
|
22
24
|
createThreadsStore,
|
|
23
25
|
definePartRenderers,
|
|
@@ -29,6 +31,7 @@ export {
|
|
|
29
31
|
mergePart,
|
|
30
32
|
narrowAgentPart,
|
|
31
33
|
parseAgentPart,
|
|
34
|
+
threadsStoreAdapterContract,
|
|
32
35
|
useAgentStream,
|
|
33
36
|
useAgentThreadRuns,
|
|
34
37
|
withPartIds
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/agent/merge.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/agent/merge.ts"],"names":[],"mappings":"AAkCA;iGACiG;AACjG,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAoDrE,wBAAgB,SAAS,CAAC,KAAK,SAAS,QAAQ,EAAE,KAAK,EAAE,SAAS,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,GAAG,KAAK,EAAE,CAyB/F"}
|
package/dist/agent/merge.js
CHANGED
|
@@ -1,19 +1,31 @@
|
|
|
1
1
|
function isTextLikeType(type) {
|
|
2
2
|
return type === "text" || type === "reasoning";
|
|
3
3
|
}
|
|
4
|
-
function spliceText(
|
|
5
|
-
const offset = next.offset ??
|
|
6
|
-
return
|
|
4
|
+
function spliceText(existingText, next) {
|
|
5
|
+
const offset = clampOffset(next.offset ?? existingText.length, existingText.length);
|
|
6
|
+
return existingText.slice(0, offset) + next.text + existingText.slice(offset + next.text.length);
|
|
7
|
+
}
|
|
8
|
+
function clampOffset(offset, length) {
|
|
9
|
+
const clamped = Number.isFinite(offset) ? Math.min(Math.max(offset, 0), length) : length;
|
|
10
|
+
if (clamped !== offset && process.env["NODE_ENV"] !== "production") {
|
|
11
|
+
console.warn(
|
|
12
|
+
`[basalt] mergePart: text offset ${offset} out of range [0, ${length}] \u2014 clamped to ${clamped}`
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
return clamped;
|
|
7
16
|
}
|
|
8
17
|
function mergePart(parts, next) {
|
|
9
18
|
const index = parts.findIndex((part) => part.id === next.id);
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
const spliceable = existing.type === next.type && isTextLikeType(next.type);
|
|
19
|
+
const existing = index === -1 ? void 0 : parts[index];
|
|
20
|
+
const spliceable = isTextLikeType(next.type) && (existing === void 0 || existing.type === next.type);
|
|
13
21
|
const merged = spliceable ? {
|
|
14
22
|
...next,
|
|
15
|
-
text: spliceText(
|
|
23
|
+
text: spliceText(
|
|
24
|
+
existing === void 0 ? "" : existing.text,
|
|
25
|
+
next
|
|
26
|
+
)
|
|
16
27
|
} : next;
|
|
28
|
+
if (existing === void 0) return [...parts, merged];
|
|
17
29
|
const out = parts.slice();
|
|
18
30
|
out[index] = merged;
|
|
19
31
|
return out;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.test.d.ts","sourceRoot":"","sources":["../../src/agent/merge.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,41 +1,41 @@
|
|
|
1
1
|
import type { JSX } from 'react';
|
|
2
2
|
import type { AgentPart } from './parts.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
index: number;
|
|
14
|
-
}) => JSX.Element | null;
|
|
15
|
-
export type ToolCallPartRenderer<TPart extends AgentPart = AgentPart> = (props: {
|
|
16
|
-
part: Extract<TPart, {
|
|
17
|
-
type: 'tool';
|
|
18
|
-
}>;
|
|
19
|
-
index: number;
|
|
20
|
-
}) => JSX.Element | null;
|
|
21
|
-
export type SourcePartRenderer<TPart extends AgentPart = AgentPart> = (props: {
|
|
22
|
-
part: Extract<TPart, {
|
|
23
|
-
type: 'source';
|
|
24
|
-
}>;
|
|
25
|
-
index: number;
|
|
26
|
-
}) => JSX.Element | null;
|
|
27
|
-
export type ErrorPartRenderer<TPart extends AgentPart = AgentPart> = (props: {
|
|
28
|
-
part: Extract<TPart, {
|
|
29
|
-
type: 'error';
|
|
30
|
-
}>;
|
|
3
|
+
/**
|
|
4
|
+
* The per-renderer argument. `settled` is `false` only while the message these parts belong to is
|
|
5
|
+
* still streaming — it converges this map toward the `PartRenderContext` a foreign renderer
|
|
6
|
+
* already receives (`./foreign`), rather than adding a third shape. Additive and
|
|
7
|
+
* source-compatible: an existing `({ part }) => …` renderer simply ignores it.
|
|
8
|
+
*
|
|
9
|
+
* Settlement is MONOTONE — a message that has settled never un-settles.
|
|
10
|
+
*/
|
|
11
|
+
type PartRenderArgs<TPart> = {
|
|
12
|
+
part: TPart;
|
|
31
13
|
index: number;
|
|
32
|
-
|
|
14
|
+
settled: boolean;
|
|
15
|
+
};
|
|
16
|
+
export type TextPartRenderer<TPart extends AgentPart = AgentPart> = (props: PartRenderArgs<Extract<TPart, {
|
|
17
|
+
type: 'text';
|
|
18
|
+
}>>) => JSX.Element | null;
|
|
19
|
+
export type ReasoningPartRenderer<TPart extends AgentPart = AgentPart> = (props: PartRenderArgs<Extract<TPart, {
|
|
20
|
+
type: 'reasoning';
|
|
21
|
+
}>>) => JSX.Element | null;
|
|
22
|
+
export type ToolCallPartRenderer<TPart extends AgentPart = AgentPart> = (props: PartRenderArgs<Extract<TPart, {
|
|
23
|
+
type: 'tool';
|
|
24
|
+
}>>) => JSX.Element | null;
|
|
25
|
+
export type SourcePartRenderer<TPart extends AgentPart = AgentPart> = (props: PartRenderArgs<Extract<TPart, {
|
|
26
|
+
type: 'source';
|
|
27
|
+
}>>) => JSX.Element | null;
|
|
28
|
+
export type ErrorPartRenderer<TPart extends AgentPart = AgentPart> = (props: PartRenderArgs<Extract<TPart, {
|
|
29
|
+
type: 'error';
|
|
30
|
+
}>>) => JSX.Element | null;
|
|
33
31
|
/**
|
|
34
32
|
* Partial map of per-type renderers. Any omitted key falls back to the headless default.
|
|
35
33
|
*
|
|
36
34
|
* @example
|
|
37
35
|
* const renderers: Partial<AgentPartRenderers> = {
|
|
38
|
-
* text: ({ part }) =>
|
|
36
|
+
* text: ({ part, settled }) => (
|
|
37
|
+
* <Markdown streaming={!settled} contentTrust="untrusted" density="chat">{part.text}</Markdown>
|
|
38
|
+
* ),
|
|
39
39
|
* }
|
|
40
40
|
*/
|
|
41
41
|
export type AgentPartRenderers<TPart extends AgentPart = AgentPart> = {
|
|
@@ -50,10 +50,17 @@ export type PartListProps<TPart extends AgentPart = AgentPart> = {
|
|
|
50
50
|
readonly parts: TPart[];
|
|
51
51
|
/**
|
|
52
52
|
* Override individual part renderers. Omitted keys fall back to the headless defaults.
|
|
53
|
-
* Pass `{ text: ({ part }) => <Markdown streaming density="chat">{part.text}</Markdown> }`
|
|
54
|
-
* enable rich markdown rendering.
|
|
53
|
+
* Pass `{ text: ({ part, settled }) => <Markdown streaming={!settled} contentTrust="untrusted" density="chat">{part.text}</Markdown> }`
|
|
54
|
+
* to enable rich markdown rendering.
|
|
55
55
|
*/
|
|
56
56
|
readonly components?: Partial<AgentPartRenderers<TPart>>;
|
|
57
|
+
/**
|
|
58
|
+
* `false` while the message these parts belong to is still streaming — forwarded to every
|
|
59
|
+
* renderer so a text renderer can drop out of streaming mode (and a fenced mermaid/diagram can
|
|
60
|
+
* upgrade) once the turn finishes. Defaults to `true`: a caller that knows nothing about a run
|
|
61
|
+
* is rendering a finished list, and un-settled must be opted into by the thing that does know.
|
|
62
|
+
*/
|
|
63
|
+
readonly settled?: boolean;
|
|
57
64
|
};
|
|
58
65
|
/**
|
|
59
66
|
* Renders a list of AgentPart values via an exhaustive switch over part.type.
|
|
@@ -69,7 +76,15 @@ export type PartListProps<TPart extends AgentPart = AgentPart> = {
|
|
|
69
76
|
* // With basalt's own Markdown for the text renderer:
|
|
70
77
|
* import { PartList } from 'basalt-ui/agent'
|
|
71
78
|
* import { Markdown } from 'basalt-ui/content'
|
|
72
|
-
* <PartList
|
|
79
|
+
* <PartList
|
|
80
|
+
* parts={parts}
|
|
81
|
+
* components={{
|
|
82
|
+
* text: ({ part, settled }) => (
|
|
83
|
+
* <Markdown streaming={!settled} contentTrust="untrusted" density="chat">{part.text}</Markdown>
|
|
84
|
+
* ),
|
|
85
|
+
* }}
|
|
86
|
+
* />
|
|
73
87
|
*/
|
|
74
|
-
export declare function PartList<TPart extends AgentPart = AgentPart>({ parts, components, }: PartListProps<TPart>): JSX.Element;
|
|
88
|
+
export declare function PartList<TPart extends AgentPart = AgentPart>({ parts, components, settled, }: PartListProps<TPart>): JSX.Element;
|
|
89
|
+
export {};
|
|
75
90
|
//# sourceMappingURL=part-list.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"part-list.d.ts","sourceRoot":"","sources":["../../src/agent/part-list.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"part-list.d.ts","sourceRoot":"","sources":["../../src/agent/part-list.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAGhC,OAAO,KAAK,EACV,SAAS,EAMV,MAAM,SAAS,CAAA;AAIhB;;;;;;;GAOG;AACH,KAAK,cAAc,CAAC,KAAK,IAAI;IAC3B,IAAI,EAAE,KAAK,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,gBAAgB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI,CAClE,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,KACpD,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;AAEvB,MAAM,MAAM,qBAAqB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI,CACvE,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,CAAC,CAAC,KACzD,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;AAEvB,MAAM,MAAM,oBAAoB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI,CACtE,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,KACpD,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;AAEvB,MAAM,MAAM,kBAAkB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI,CACpE,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC,CAAC,KACtD,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;AAEvB,MAAM,MAAM,iBAAiB,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,IAAI,CACnE,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC,KACrD,GAAG,CAAC,OAAO,GAAG,IAAI,CAAA;AAEvB;;;;;;;;;GASG;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;IACxD;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAC3B,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,QAAQ,CAAC,KAAK,SAAS,SAAS,GAAG,SAAS,EAAE,EAC5D,KAAK,EACL,UAAU,EACV,OAAc,GACf,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,CAoFpC"}
|
package/dist/agent/part-list.js
CHANGED
|
@@ -107,7 +107,8 @@ const DEFAULT_RENDERERS = {
|
|
|
107
107
|
};
|
|
108
108
|
function PartList({
|
|
109
109
|
parts,
|
|
110
|
-
components
|
|
110
|
+
components,
|
|
111
|
+
settled = true
|
|
111
112
|
}) {
|
|
112
113
|
const renderers = useMemo(
|
|
113
114
|
() => ({ ...DEFAULT_RENDERERS, ...components }),
|
|
@@ -119,23 +120,58 @@ function PartList({
|
|
|
119
120
|
return null;
|
|
120
121
|
case "text": {
|
|
121
122
|
const Render = renderers.text;
|
|
122
|
-
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
123
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
124
|
+
Render,
|
|
125
|
+
{
|
|
126
|
+
part,
|
|
127
|
+
index,
|
|
128
|
+
settled
|
|
129
|
+
}
|
|
130
|
+
) }, part.id);
|
|
123
131
|
}
|
|
124
132
|
case "reasoning": {
|
|
125
133
|
const Render = renderers.reasoning;
|
|
126
|
-
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
134
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
135
|
+
Render,
|
|
136
|
+
{
|
|
137
|
+
part,
|
|
138
|
+
index,
|
|
139
|
+
settled
|
|
140
|
+
}
|
|
141
|
+
) }, part.id);
|
|
127
142
|
}
|
|
128
143
|
case "tool": {
|
|
129
144
|
const Render = renderers.tool;
|
|
130
|
-
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
145
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
146
|
+
Render,
|
|
147
|
+
{
|
|
148
|
+
part,
|
|
149
|
+
index,
|
|
150
|
+
settled
|
|
151
|
+
}
|
|
152
|
+
) }, part.id);
|
|
131
153
|
}
|
|
132
154
|
case "source": {
|
|
133
155
|
const Render = renderers.source;
|
|
134
|
-
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
156
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
157
|
+
Render,
|
|
158
|
+
{
|
|
159
|
+
part,
|
|
160
|
+
index,
|
|
161
|
+
settled
|
|
162
|
+
}
|
|
163
|
+
) }, part.id);
|
|
135
164
|
}
|
|
136
165
|
case "error": {
|
|
137
166
|
const Render = renderers.error;
|
|
138
|
-
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
167
|
+
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
|
|
168
|
+
Render,
|
|
169
|
+
{
|
|
170
|
+
part,
|
|
171
|
+
index,
|
|
172
|
+
settled
|
|
173
|
+
}
|
|
174
|
+
) }, part.id);
|
|
139
175
|
}
|
|
140
176
|
default:
|
|
141
177
|
return assertNever(part);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"part-list.test.d.ts","sourceRoot":"","sources":["../../src/agent/part-list.test.tsx"],"names":[],"mappings":""}
|