basalt-ui 2.4.0 → 2.5.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/CHANGELOG.md +16 -0
- package/MIGRATING.md +34 -12
- package/agent/rules/basalt-state.md +1 -1
- package/dist/agent/ai-sdk-transport.d.ts.map +1 -1
- package/dist/agent/ai-sdk-transport.js +4 -1
- package/dist/agent/index.d.ts +1 -1
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/run-records.d.ts +12 -3
- package/dist/agent/run-records.d.ts.map +1 -1
- package/dist/agent/run-records.js +16 -3
- package/dist/agent/transport.d.ts +10 -3
- package/dist/agent/transport.d.ts.map +1 -1
- package/dist/agent/use-agent-thread-runs.d.ts.map +1 -1
- package/dist/agent/use-agent-thread-runs.js +23 -7
- package/dist/charts/DualPanel.d.ts.map +1 -1
- package/dist/charts/DualPanel.js +14 -5
- package/dist/charts/MirroredBars.d.ts.map +1 -1
- package/dist/charts/MirroredBars.js +6 -4
- package/dist/charts/compile.d.ts +4 -0
- package/dist/charts/compile.d.ts.map +1 -1
- package/dist/charts/compile.js +40 -11
- package/dist/charts/panel.d.ts +6 -0
- package/dist/charts/panel.d.ts.map +1 -1
- package/dist/charts/panel.js +10 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/provider/index.d.ts.map +1 -1
- package/dist/provider/index.js +8 -2
- package/dist/state/fields.d.ts +10 -15
- package/dist/state/fields.d.ts.map +1 -1
- package/dist/state/fields.js +27 -1
- package/dist/telemetry.d.ts +58 -4
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +13 -5
- package/llms.txt +2 -2
- package/package.json +1 -1
- package/src/agent/ai-sdk-transport.ts +5 -2
- package/src/agent/index.ts +1 -1
- package/src/agent/run-records.ts +27 -3
- package/src/agent/transport.ts +11 -5
- package/src/agent/use-agent-thread-runs.ts +35 -8
- package/src/charts/DualPanel.tsx +13 -4
- package/src/charts/MirroredBars.tsx +5 -3
- package/src/charts/compile.ts +59 -12
- package/src/charts/panel.tsx +16 -1
- package/src/index.ts +1 -1
- package/src/provider/index.tsx +8 -2
- package/src/state/fields.ts +41 -19
- package/src/telemetry.ts +70 -7
package/src/telemetry.ts
CHANGED
|
@@ -65,7 +65,61 @@ export type BasaltEvent =
|
|
|
65
65
|
| Ok<'chat.turn', ChatAttrs>
|
|
66
66
|
| Err<'chat.turn', ChatAttrs, Span>
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
/** W3C trace-context request headers a sink contributes to one chat turn's request. */
|
|
69
|
+
export type TraceHeaders = {
|
|
70
|
+
readonly traceparent: string
|
|
71
|
+
readonly tracestate?: string | undefined
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* How a traced chat turn ended: its `chat.turn` event fired (`settled`/`failed`), or `stopped` — a
|
|
76
|
+
* `stop()`, an unmount or a newer run taking the thread over — which emits no event. The one
|
|
77
|
+
* lifecycle vocabulary of the run records too.
|
|
78
|
+
*/
|
|
79
|
+
export type ChatTurnEnd = 'settled' | 'failed' | 'stopped'
|
|
80
|
+
|
|
81
|
+
/** The turn a sink is asked to trace. */
|
|
82
|
+
type ChatTurnInit = { readonly threadId: string; readonly messageId: string }
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* What a sink returns from `startChatTurn`. `settle` runs once, synchronously, right after the
|
|
86
|
+
* turn's `chat.turn` event (`settled`/`failed`), or when the turn is cut short (`stopped`) — the
|
|
87
|
+
* point to end a span opened in `startChatTurn`. It runs even when `headers` is absent or
|
|
88
|
+
* malformed (dropped, the request goes out untraced), so the span never leaks.
|
|
89
|
+
*/
|
|
90
|
+
export type ChatTurnTrace = {
|
|
91
|
+
readonly headers?: TraceHeaders | undefined
|
|
92
|
+
readonly settle?: ((end: ChatTurnEnd) => void) | undefined
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* The event sink. It may carry one optional hook, `startChatTurn`, called when a new chat turn
|
|
97
|
+
* begins (not on a resume): open your span there and return its `traceparent` (and `tracestate`)
|
|
98
|
+
* and `aiSdkTransport` sends them with that turn's request to the chat endpoint — never anywhere
|
|
99
|
+
* else. A sink without the hook, or no sink, changes nothing on the wire. basalt has no OTel
|
|
100
|
+
* dependency; the hook is where the consumer's SDK does the work.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* export const telemetry: Telemetry = Object.assign(onEvent, {
|
|
104
|
+
* startChatTurn({ threadId }) {
|
|
105
|
+
* const span = tracer.startSpan('chat.turn', {
|
|
106
|
+
* attributes: { 'basalt.chat.thread_id': threadId },
|
|
107
|
+
* })
|
|
108
|
+
* const carrier: Record<string, string> = {}
|
|
109
|
+
* propagation.inject(trace.setSpan(context.active(), span), carrier)
|
|
110
|
+
* return {
|
|
111
|
+
* headers: { traceparent: carrier.traceparent ?? '', tracestate: carrier.tracestate },
|
|
112
|
+
* settle(end) {
|
|
113
|
+
* if (end === 'failed') span.setStatus({ code: SpanStatusCode.ERROR })
|
|
114
|
+
* span.end()
|
|
115
|
+
* },
|
|
116
|
+
* }
|
|
117
|
+
* },
|
|
118
|
+
* })
|
|
119
|
+
*/
|
|
120
|
+
export type Telemetry = ((event: BasaltEvent) => void) & {
|
|
121
|
+
readonly startChatTurn?: ((turn: ChatTurnInit) => ChatTurnTrace | undefined) | undefined
|
|
122
|
+
}
|
|
69
123
|
|
|
70
124
|
export const now = (): number => performance.timeOrigin + performance.now()
|
|
71
125
|
|
|
@@ -73,18 +127,27 @@ export const now = (): number => performance.timeOrigin + performance.now()
|
|
|
73
127
|
export const errorName = (error: unknown): string => (error instanceof Error ? error.name : 'Error')
|
|
74
128
|
|
|
75
129
|
/**
|
|
76
|
-
*
|
|
77
|
-
* events.
|
|
130
|
+
* The wrapped emitter over a sink read at call time (a ref), so a swapped sink is never stale. It is
|
|
131
|
+
* called synchronously and a throwing sink never breaks a render; no sink, no events. Its
|
|
132
|
+
* `startChatTurn` forwards the sink's hook; the hook's consumer validates the headers.
|
|
78
133
|
*/
|
|
79
|
-
export function
|
|
80
|
-
|
|
81
|
-
return (event) => {
|
|
134
|
+
export function createLiveEmitter(read: () => Telemetry | undefined): Telemetry {
|
|
135
|
+
const emit = (event: BasaltEvent): void => {
|
|
82
136
|
try {
|
|
83
|
-
|
|
137
|
+
read()?.(event)
|
|
84
138
|
} catch {
|
|
85
139
|
// a throwing sink must never break the app (§ 7 delivery rules)
|
|
86
140
|
}
|
|
87
141
|
}
|
|
142
|
+
return Object.assign(emit, {
|
|
143
|
+
startChatTurn(turn: ChatTurnInit): ChatTurnTrace | undefined {
|
|
144
|
+
try {
|
|
145
|
+
return read()?.startChatTurn?.(turn)
|
|
146
|
+
} catch {
|
|
147
|
+
return undefined
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
})
|
|
88
151
|
}
|
|
89
152
|
|
|
90
153
|
function noop(): void {}
|