@aparte/core 0.19.2 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/dist/client/aparte-client.d.ts +76 -97
- package/dist/client/aparte-client.d.ts.map +1 -1
- package/dist/client/stream-adapter.d.ts +7 -13
- package/dist/client/stream-adapter.d.ts.map +1 -1
- package/dist/client/wire-history.d.ts +4 -5
- package/dist/client/wire-history.d.ts.map +1 -1
- package/dist/components/bubble/aparte-chat-bubble.d.ts +89 -58
- package/dist/components/bubble/aparte-chat-bubble.d.ts.map +1 -1
- package/dist/components/bubble/bubble-sync.d.ts +1 -1
- package/dist/components/chat/aparte-chat.d.ts +15 -13
- package/dist/components/chat/aparte-chat.d.ts.map +1 -1
- package/dist/components/chat/glide-gate.d.ts +13 -0
- package/dist/components/chat/glide-gate.d.ts.map +1 -0
- package/dist/components/composer/aparte-composer-action.d.ts +3 -3
- package/dist/components/composer/aparte-composer-add-attachment.d.ts +2 -2
- package/dist/components/composer/aparte-composer-cancel.d.ts +1 -1
- package/dist/components/composer/aparte-composer-input.d.ts +4 -7
- package/dist/components/composer/aparte-composer-input.d.ts.map +1 -1
- package/dist/components/composer/aparte-composer-send.d.ts +9 -11
- package/dist/components/composer/aparte-composer-send.d.ts.map +1 -1
- package/dist/components/composer/aparte-composer.d.ts +50 -80
- package/dist/components/composer/aparte-composer.d.ts.map +1 -1
- package/dist/components/context/aparte-context.d.ts +13 -7
- package/dist/components/context/aparte-context.d.ts.map +1 -1
- package/dist/components/conversation-list/aparte-conversation-list.d.ts +25 -13
- package/dist/components/conversation-list/aparte-conversation-list.d.ts.map +1 -1
- package/dist/components/elicitation/aparte-elicitation.d.ts +15 -22
- package/dist/components/elicitation/aparte-elicitation.d.ts.map +1 -1
- package/dist/components/scroll-rail/aparte-scroll-rail.d.ts +10 -11
- package/dist/components/scroll-rail/aparte-scroll-rail.d.ts.map +1 -1
- package/dist/components/sidebar/aparte-sidebar.d.ts +16 -3
- package/dist/components/sidebar/aparte-sidebar.d.ts.map +1 -1
- package/dist/components/split/aparte-split.d.ts +12 -3
- package/dist/components/split/aparte-split.d.ts.map +1 -1
- package/dist/components/status/aparte-chat-status.d.ts +5 -3
- package/dist/components/status/aparte-chat-status.d.ts.map +1 -1
- package/dist/components/suggestions/aparte-suggestions.d.ts +6 -9
- package/dist/components/suggestions/aparte-suggestions.d.ts.map +1 -1
- package/dist/components/viewport/aparte-chat-viewport.d.ts +76 -69
- package/dist/components/viewport/aparte-chat-viewport.d.ts.map +1 -1
- package/dist/config/aparte-config.d.ts +169 -141
- package/dist/config/aparte-config.d.ts.map +1 -1
- package/dist/config/icon-provider.d.ts +19 -2
- package/dist/config/icon-provider.d.ts.map +1 -1
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/locale.d.ts +61 -89
- package/dist/config/locale.d.ts.map +1 -1
- package/dist/config/sanitize.d.ts.map +1 -1
- package/dist/conversations/conversation-controller.d.ts +18 -3
- package/dist/conversations/conversation-controller.d.ts.map +1 -1
- package/dist/conversations/conversation-manager.d.ts +6 -6
- package/dist/conversations/conversation-manager.d.ts.map +1 -1
- package/dist/conversations/index.d.ts +1 -1
- package/dist/conversations/index.d.ts.map +1 -1
- package/dist/custom-elements.json +5656 -4759
- package/dist/{dialog-triggers-CEazY76J.js → dialog-triggers-3Rk7PuZa.js} +555 -375
- package/dist/dialog-triggers-3Rk7PuZa.js.map +1 -0
- package/dist/elicitation/approval-panel.d.ts.map +1 -1
- package/dist/elicitation/index.d.ts +6 -1
- package/dist/elicitation/index.d.ts.map +1 -1
- package/dist/elicitation/panel.d.ts +11 -21
- package/dist/elicitation/panel.d.ts.map +1 -1
- package/dist/elicitation/types.d.ts +19 -27
- package/dist/elicitation/types.d.ts.map +1 -1
- package/dist/generated/element-attributes.d.ts +16 -10
- package/dist/generated/element-attributes.d.ts.map +1 -1
- package/dist/host/aparte-chat-host.d.ts +17 -32
- package/dist/host/aparte-chat-host.d.ts.map +1 -1
- package/dist/icons/extended.d.ts +1 -2
- package/dist/icons/extended.d.ts.map +1 -1
- package/dist/icons.d.ts +6 -8
- package/dist/icons.d.ts.map +1 -1
- package/dist/icons.js.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +13 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +775 -337
- package/dist/index.js.map +1 -1
- package/dist/index.node.d.ts +7 -4
- package/dist/index.node.d.ts.map +1 -1
- package/dist/index.node.js +2 -2
- package/dist/index.node.js.map +1 -1
- package/dist/interop/dialog-triggers.d.ts +2 -2
- package/dist/interop/element-props.d.ts +16 -27
- package/dist/interop/element-props.d.ts.map +1 -1
- package/dist/parsers/aparte-stream-parser.d.ts.map +1 -1
- package/dist/primitives/icon/aparte-icon.d.ts.map +1 -1
- package/dist/primitives/select/aparte-option.d.ts +3 -2
- package/dist/primitives/select/aparte-option.d.ts.map +1 -1
- package/dist/primitives/select/aparte-select.d.ts +24 -21
- package/dist/primitives/select/aparte-select.d.ts.map +1 -1
- package/dist/renderers/markdown-stream.d.ts.map +1 -1
- package/dist/renderers/segment-renderers.d.ts +11 -17
- package/dist/renderers/segment-renderers.d.ts.map +1 -1
- package/dist/renderers/segments/code.d.ts.map +1 -1
- package/dist/renderers/segments/error.d.ts.map +1 -1
- package/dist/renderers/segments/text.d.ts.map +1 -1
- package/dist/renderers/segments/thinking.d.ts.map +1 -1
- package/dist/renderers/segments/tool-call.d.ts.map +1 -1
- package/dist/runtime/message-repository.d.ts +8 -15
- package/dist/runtime/message-repository.d.ts.map +1 -1
- package/dist/transport/agent-handler.d.ts +2 -0
- package/dist/transport/agent-handler.d.ts.map +1 -1
- package/dist/transport/backend-handler.d.ts +4 -6
- package/dist/transport/backend-handler.d.ts.map +1 -1
- package/dist/transport/backend-transport.d.ts +15 -1
- package/dist/transport/backend-transport.d.ts.map +1 -1
- package/dist/transport/types.d.ts +7 -10
- package/dist/transport/types.d.ts.map +1 -1
- package/dist/types/chat.d.ts +10 -18
- package/dist/types/chat.d.ts.map +1 -1
- package/dist/types/element-attributes.d.ts +6 -12
- package/dist/types/element-attributes.d.ts.map +1 -1
- package/dist/types/element-map.d.ts +6 -19
- package/dist/types/element-map.d.ts.map +1 -1
- package/dist/types/event-map.d.ts +11 -17
- package/dist/types/event-map.d.ts.map +1 -1
- package/dist/types/events.d.ts +5 -14
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/imperative-api.d.ts +3 -1
- package/dist/types/imperative-api.d.ts.map +1 -1
- package/dist/types/index.d.ts +4 -4
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/model-provider.d.ts +7 -9
- package/dist/types/model-provider.d.ts.map +1 -1
- package/dist/types/segments.d.ts +29 -13
- package/dist/types/segments.d.ts.map +1 -1
- package/dist/types/tools.d.ts +21 -23
- package/dist/types/tools.d.ts.map +1 -1
- package/dist/utils/copy-text.d.ts +1 -2
- package/dist/utils/copy-text.d.ts.map +1 -1
- package/dist/utils/css-escape.d.ts +1 -1
- package/dist/utils/escape.d.ts +4 -19
- package/dist/utils/escape.d.ts.map +1 -1
- package/dist/utils/files-to-attachments.d.ts +2 -2
- package/dist/utils/fold-text.d.ts +13 -0
- package/dist/utils/fold-text.d.ts.map +1 -0
- package/dist/utils/is-awaiting-reply.d.ts +2 -5
- package/dist/utils/is-awaiting-reply.d.ts.map +1 -1
- package/dist/utils/presence.d.ts +5 -5
- package/dist/utils/segments.d.ts +54 -78
- package/dist/utils/segments.d.ts.map +1 -1
- package/dist/utils/tool-input.d.ts +1 -1
- package/dist/utils/tool-input.d.ts.map +1 -1
- package/dist/utils/transcript.d.ts +2 -2
- package/dist/utils/uuid.d.ts +0 -11
- package/dist/utils/uuid.d.ts.map +1 -1
- package/package.json +30 -4
- package/dist/dialog-triggers-CEazY76J.js.map +0 -1
package/dist/types/segments.d.ts
CHANGED
|
@@ -48,16 +48,15 @@ export interface AparteSegmentBase {
|
|
|
48
48
|
/**
|
|
49
49
|
* What core measured about a segment. Lives in `meta.aparte`, not on the segment.
|
|
50
50
|
*
|
|
51
|
-
*
|
|
52
|
-
* carries a timestamp on a content block** — verified rather than assumed: Anthropic's
|
|
51
|
+
* **No protocol carries a timestamp on a content block**: Anthropic's
|
|
53
52
|
* blocks have none (and neither does the message), OpenAI's `output_text` part is
|
|
54
53
|
* `{annotations, logprobs, text, type}` with `created_at` on the item above it, and the
|
|
55
54
|
* AI SDK's `UIMessage.parts` have none either. What the AI SDK does have is a metadata
|
|
56
55
|
* bag whose canonical example is literally `{ createdAt, model, totalTokens }` — at the
|
|
57
56
|
* message level. A per-block `id` has industry precedent; per-block time has none.
|
|
58
57
|
*
|
|
59
|
-
* So this is a **local measurement**, and the shape says so. It stays typed
|
|
60
|
-
*
|
|
58
|
+
* So this is a **local measurement**, and the shape says so. It stays typed, and it is
|
|
59
|
+
* namespaced under
|
|
61
60
|
* `aparte` because `meta` is the consumer's: a flat `startedAt` there would collide
|
|
62
61
|
* with a key of their own.
|
|
63
62
|
*
|
|
@@ -128,15 +127,9 @@ export interface AparteThinkingSegment extends AparteSegmentBase {
|
|
|
128
127
|
content: string;
|
|
129
128
|
/**
|
|
130
129
|
* Open the block. **Absent means CLOSED** — a reasoning block is a disclosure,
|
|
131
|
-
* and the reader opens it.
|
|
130
|
+
* and the reader opens it. The content is behind a click, streaming or settled.
|
|
132
131
|
*
|
|
133
|
-
*
|
|
134
|
-
* emitted `collapsed: false` on every block it produced, so a reasoning block
|
|
135
|
-
* stayed unfolded for the whole conversation and buried the answer under it. No
|
|
136
|
-
* assistant on the market does that — the content is behind a click, streaming
|
|
137
|
-
* or settled.
|
|
138
|
-
*
|
|
139
|
-
* `false` is still how you open one on purpose. Only ABSENT changed meaning.
|
|
132
|
+
* `false` opens one on purpose.
|
|
140
133
|
*/
|
|
141
134
|
collapsed?: boolean;
|
|
142
135
|
label?: string;
|
|
@@ -161,6 +154,10 @@ export interface AparteCodeSegment extends AparteSegmentBase {
|
|
|
161
154
|
content: string;
|
|
162
155
|
language?: string;
|
|
163
156
|
filename?: string;
|
|
157
|
+
/**
|
|
158
|
+
* @deprecated Read by nothing: no renderer and no stylesheet draws line numbers, so setting it
|
|
159
|
+
* changes nothing. It will be removed in a later minor.
|
|
160
|
+
*/
|
|
164
161
|
showLineNumbers?: boolean;
|
|
165
162
|
}
|
|
166
163
|
/**
|
|
@@ -181,6 +178,10 @@ export interface AparteErrorSegment extends AparteSegmentBase {
|
|
|
181
178
|
type: 'error';
|
|
182
179
|
content: string;
|
|
183
180
|
details?: string;
|
|
181
|
+
/**
|
|
182
|
+
* @deprecated Set by nothing and read by nothing: the error renderer draws `content` and
|
|
183
|
+
* `details` only. Put a stack in `details` to show it. It will be removed in a later minor.
|
|
184
|
+
*/
|
|
184
185
|
stack?: string;
|
|
185
186
|
}
|
|
186
187
|
/**
|
|
@@ -268,7 +269,22 @@ export interface AparteCustomSegment extends AparteSegmentBase {
|
|
|
268
269
|
* segment — a `type` of its own, through `registerSegmentRenderer` and
|
|
269
270
|
* `registerStreamBlock` — the way any consumer registers a `chart` or a `citation`.
|
|
270
271
|
*/
|
|
271
|
-
export type AparteSegment = AparteTextSegment | AparteThinkingSegment | AparteCodeSegment | AparteErrorSegment | AparteCustomSegment | AparteToolCallSegment;
|
|
272
|
+
export type AparteSegment = AparteTextSegment | AparteThinkingSegment | AparteCodeSegment | AparteErrorSegment | AparteCustomSegment | AparteToolCallSegment | AparteSegmentTypes[keyof AparteSegmentTypes];
|
|
273
|
+
/**
|
|
274
|
+
* The segment types an app or a plugin adds, one key per `type`, merged into this interface;
|
|
275
|
+
* each one joins {@link AparteSegment}, so `addSegment`, `appendMessage` and
|
|
276
|
+
* `AparteMessage.segments` take it without a cast.
|
|
277
|
+
*
|
|
278
|
+
* @example
|
|
279
|
+
* declare module '@aparte/core' {
|
|
280
|
+
* interface AparteSegmentTypes {
|
|
281
|
+
* chart: AparteSegmentBase & { type: 'chart'; data: { label: string; value: number }[] };
|
|
282
|
+
* }
|
|
283
|
+
* }
|
|
284
|
+
* viewport.addSegment('a1', { id: 'c1', type: 'chart', data: [{ label: 'Q1', value: 4 }] });
|
|
285
|
+
*/
|
|
286
|
+
export interface AparteSegmentTypes {
|
|
287
|
+
}
|
|
272
288
|
/** Segment type discriminator values */
|
|
273
289
|
export type AparteSegmentType = AparteSegment['type'];
|
|
274
290
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"segments.d.ts","sourceRoot":"","sources":["../../src/types/segments.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,wDAAwD;AACxD,MAAM,WAAW,iBAAiB;IAC9B,gCAAgC;IAChC,EAAE,EAAE,MAAM,CAAC;IAEX,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IAEb,kDAAkD;IAClD,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAkBlB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;QAAE,MAAM,CAAC,EAAE,mBAAmB,CAAA;KAAE,CAAC;CACrE;AAED
|
|
1
|
+
{"version":3,"file":"segments.d.ts","sourceRoot":"","sources":["../../src/types/segments.ts"],"names":[],"mappings":"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"}
|
package/dist/types/tools.d.ts
CHANGED
|
@@ -30,9 +30,6 @@ export interface AparteTool {
|
|
|
30
30
|
* same turn runs — and then the model gets a turn to answer it, so it can
|
|
31
31
|
* say what it will do instead. The refusal may carry the user's own words.
|
|
32
32
|
*
|
|
33
|
-
* All three clauses of this comment used to say something else: the default
|
|
34
|
-
* renderer surfaced the buttons, an `aparte-tool-decision` event resolved
|
|
35
|
-
* them, and a refusal ended the turn. None of that is true any more.
|
|
36
33
|
*/
|
|
37
34
|
needsApproval?: boolean;
|
|
38
35
|
}
|
|
@@ -44,11 +41,8 @@ export interface AparteTool {
|
|
|
44
41
|
* (`<aparte-elicitation>` renders the panel there), and the transcript row shows only a
|
|
45
42
|
* state — there is no Approve/Reject control in a bubble.
|
|
46
43
|
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* it shipped with no presenter and no `approvalResolver`, and every `needsApproval` call
|
|
50
|
-
* aborted with nothing clickable on screen. The sibling docblock on `needsApproval`
|
|
51
|
-
* records the same correction; this one was missed in the same file.
|
|
44
|
+
* With no presenter and no `approvalResolver`, every `needsApproval` call aborts with
|
|
45
|
+
* nothing clickable on screen.
|
|
52
46
|
*
|
|
53
47
|
* @event aparte-tool-approval-request
|
|
54
48
|
*/
|
|
@@ -111,19 +105,13 @@ export type AparteToolHandler = (call: AparteToolCall, signal: AbortSignal, cont
|
|
|
111
105
|
/**
|
|
112
106
|
* Which chat a tool handler is running for.
|
|
113
107
|
*
|
|
114
|
-
* Optional and third, so
|
|
115
|
-
* nothing has to be rewritten to ignore it.
|
|
108
|
+
* Optional and third, so a handler that does not need it ignores it.
|
|
116
109
|
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
* The model was told the user refused a question the user was never shown.
|
|
123
|
-
*
|
|
124
|
-
* That failure is described in `AparteConfig.requestUserInput` as "a lie told
|
|
125
|
-
* quietly", and the plugin walked straight into it because the handler signature
|
|
126
|
-
* gave it nothing to walk around with.
|
|
110
|
+
* A handler needs it to reach the right instance: `requestUserInput` resolves its
|
|
111
|
+
* presenter with `resolveConfig(request.target ?? null)`, so without a `target` it
|
|
112
|
+
* resolves against the GLOBAL config, finds no presenter on an instance config, and
|
|
113
|
+
* rejects with an `AparteElicitationAbortError` (`name` `'AbortError'`, reason
|
|
114
|
+
* `'no-presenter'`): nothing is shown. Pass `target` from this context.
|
|
127
115
|
*
|
|
128
116
|
* The loop supplies it — `runStreamAgent`, or the runner you injected — so
|
|
129
117
|
* a handler behaves the same whichever one is running.
|
|
@@ -161,6 +149,17 @@ export interface AparteToolContext {
|
|
|
161
149
|
* defensively — a summary that throws shows nothing rather than breaking the row.
|
|
162
150
|
*/
|
|
163
151
|
export type AparteToolSummary = (segment: AparteToolCallSegment) => string;
|
|
152
|
+
/**
|
|
153
|
+
* A tool's arguments as a person reads them: the text the approval panel shows under its
|
|
154
|
+
* question and the default tool row shows behind its disclosure — one formatter for both, so
|
|
155
|
+
* the two cannot disagree. Registered via aparteGlobalConfig.registerToolInputFormatter(toolName, formatter).
|
|
156
|
+
*
|
|
157
|
+
* Without one, both show the arguments as the model sent them, pretty-printed JSON. Return
|
|
158
|
+
* plain text: it is written as text, never parsed as HTML; `''` shows no arguments at all.
|
|
159
|
+
* `input` is whatever the model chose, so read it defensively — a formatter that throws
|
|
160
|
+
* falls back to the JSON.
|
|
161
|
+
*/
|
|
162
|
+
export type AparteToolInputFormatter = (input: Record<string, unknown>) => string;
|
|
164
163
|
/**
|
|
165
164
|
* Per-tool segment renderer.
|
|
166
165
|
* Registered via aparteGlobalConfig.registerToolRenderer(toolName, renderer).
|
|
@@ -176,8 +175,7 @@ export interface AparteToolRenderer {
|
|
|
176
175
|
* **The segment carries model-chosen data.** `segment.toolCall.input` is
|
|
177
176
|
* whatever the model decided to pass, and `segment.result` is whatever the tool
|
|
178
177
|
* returned — on the SEGMENT, because `AparteToolCall` is `{ id, name, input }`
|
|
179
|
-
* and nothing else
|
|
180
|
-
* not compile; the first renderer written against it found out.
|
|
178
|
+
* and nothing else (there is no `segment.toolCall.result`).
|
|
181
179
|
* Both values are untrusted.
|
|
182
180
|
*
|
|
183
181
|
* Return an **HTMLElement** and there is no innerHTML surface at all — set
|
|
@@ -187,7 +185,7 @@ export interface AparteToolRenderer {
|
|
|
187
185
|
* Return a **string** and core inserts it with `innerHTML`, so every
|
|
188
186
|
* interpolated value must go through `escapeHtml` (text position) or
|
|
189
187
|
* `escapeAttr` (inside an attribute). The natural first thing to write here is
|
|
190
|
-
*
|
|
188
|
+
* `` `<div>Searching for ${s.toolCall.input.query}</div>` ``, and that is a direct
|
|
191
189
|
* model-to-DOM XSS in the host page's origin.
|
|
192
190
|
*
|
|
193
191
|
* Return an empty string to render nothing (e.g. a UI-only tool like
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/types/tools.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE3D,2CAA2C;AAC3C,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,8GAA8G;IAC9G,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/types/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,8 +17,7 @@
|
|
|
17
17
|
* the path clipboard.js and copy-to-clipboard take, for the same reason.
|
|
18
18
|
*
|
|
19
19
|
* Rejects when neither path could copy, so a caller's "copied" confirmation can stay
|
|
20
|
-
* honest.
|
|
21
|
-
* here, so the sweep cannot come undone one call site at a time.
|
|
20
|
+
* honest.
|
|
22
21
|
*/
|
|
23
22
|
export declare function copyText(text: string): Promise<void>;
|
|
24
23
|
//# sourceMappingURL=copy-text.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copy-text.d.ts","sourceRoot":"","sources":["../../src/utils/copy-text.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"copy-text.d.ts","sourceRoot":"","sources":["../../src/utils/copy-text.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkCpD"}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Segment/message ids are random UUIDs in the default flow, so this is
|
|
10
10
|
* defense-in-depth: a hostile, stream-supplied id containing `"` (e.g. a tool-call
|
|
11
|
-
* id)
|
|
11
|
+
* id) cannot break out of the selector into a `SyntaxError` or a
|
|
12
12
|
* selector-list that mis-targets another element.
|
|
13
13
|
*
|
|
14
14
|
* A raw newline (or CR / form feed) is not allowed inside a CSS string either — it
|
package/dist/utils/escape.d.ts
CHANGED
|
@@ -1,26 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* HTML escaping — one implementation, for every interpolation core makes.
|
|
3
3
|
*
|
|
4
|
-
* There used to be SEVEN copies of this across the package (`_escapeHtml` in the
|
|
5
|
-
* bubble and in the config, `_escapeAttr` in the chat shell, the composer action
|
|
6
|
-
* and the composer input, plus `escapeHtml` and `escapeAttr` in the segment
|
|
7
|
-
* renderers). They had already drifted: the chat shell's copy escaped only `&`,
|
|
8
|
-
* `"` and `<`, leaving `'` and `>` through, so it was strictly weaker than its
|
|
9
|
-
* six siblings while looking identical at the call site. That is the failure mode
|
|
10
|
-
* a duplicated security helper always ends in — one of them stops matching, and
|
|
11
|
-
* nothing tells you which.
|
|
12
|
-
*
|
|
13
4
|
* Escapes all five characters that matter, which makes the result safe in BOTH
|
|
14
5
|
* text position and quoted-attribute position (single or double quotes). Callers
|
|
15
6
|
* that read better saying "attribute" use {@link escapeAttr}, which is this same
|
|
16
7
|
* function under a second name — an alias, deliberately not a second body.
|
|
17
8
|
*
|
|
18
9
|
* PUBLIC. Both names are exported from the barrel and documented in the
|
|
19
|
-
* customization guide, because a render hook that returns a string needs them
|
|
20
|
-
* telling an author to "escape it yourself" without naming the function is how a
|
|
21
|
-
* capability becomes invisible. An earlier version of this comment claimed the
|
|
22
|
-
* opposite ("not exported from the package barrel… not a public API") while
|
|
23
|
-
* `index.ts` exported both — the export was real, the comment was not.
|
|
10
|
+
* customization guide, because a render hook that returns a string needs them.
|
|
24
11
|
*/
|
|
25
12
|
export declare function escapeHtml(value: string): string;
|
|
26
13
|
/**
|
|
@@ -34,13 +21,11 @@ export declare function escapeHtml(value: string): string;
|
|
|
34
21
|
* REQUIRES A QUOTED ATTRIBUTE. `title="${escapeAttr(v)}"` and `title='…'` are
|
|
35
22
|
* both safe; bare `title=${escapeAttr(v)}` is NOT, because a space, tab, newline
|
|
36
23
|
* or backtick in the value ends an unquoted attribute and starts the next one —
|
|
37
|
-
* and none of those five escaped characters is one of them.
|
|
38
|
-
*
|
|
24
|
+
* and none of those five escaped characters is one of them. No unquoted attribute
|
|
25
|
+
* interpolation exists in the library.
|
|
39
26
|
*
|
|
40
27
|
* The fix is to quote the attribute, not to escape harder: encoding spaces would
|
|
41
|
-
* make every legitimate `title="Hello world"` read `Hello world`.
|
|
42
|
-
* `pnpm check:attr-escaping` now rejects an unquoted attribute interpolation
|
|
43
|
-
* outright rather than trusting this function to cover a position it cannot.
|
|
28
|
+
* make every legitimate `title="Hello world"` read `Hello world`.
|
|
44
29
|
*/
|
|
45
30
|
export declare const escapeAttr: typeof escapeHtml;
|
|
46
31
|
//# sourceMappingURL=escape.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"escape.d.ts","sourceRoot":"","sources":["../../src/utils/escape.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"escape.d.ts","sourceRoot":"","sources":["../../src/utils/escape.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAchD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,UAAU,mBAAa,CAAC"}
|
|
@@ -32,8 +32,8 @@ export declare function filesToAttachments(files: readonly File[]): AparteAttach
|
|
|
32
32
|
/**
|
|
33
33
|
* Release the object URLs of attachments that are no longer on screen.
|
|
34
34
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
35
|
+
* Until revoked, every `File` a session sent stays reachable until the page goes
|
|
36
|
+
* away. Only the caller knows when an attachment stops being rendered —
|
|
37
37
|
* a persisted conversation may re-render one much later — so this is a function
|
|
38
38
|
* rather than something `filesToAttachments` could schedule.
|
|
39
39
|
*
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text as a search compares it: no accents, lower case, trimmed — so "Écrire" finds "ecrire".
|
|
3
|
+
* Shared by the conversation list's filter and the sidebar's search field.
|
|
4
|
+
*/
|
|
5
|
+
export declare function foldText(text: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* Hide the conversation rows under `root` whose title does not contain `needle` (already
|
|
8
|
+
* folded), and the date groups left with none; return how many rows match. An empty needle
|
|
9
|
+
* shows everything. The conversation list runs it on every render; the sidebar runs it itself
|
|
10
|
+
* on a list that has not upgraded yet, whose rows are the page's own markup.
|
|
11
|
+
*/
|
|
12
|
+
export declare function filterConversationRows(root: ParentNode, needle: string): number;
|
|
13
|
+
//# sourceMappingURL=fold-text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fold-text.d.ts","sourceRoot":"","sources":["../../src/utils/fold-text.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAW/E"}
|
|
@@ -6,14 +6,11 @@ import type { AparteMessage } from '../types/index.js';
|
|
|
6
6
|
*
|
|
7
7
|
* Two clauses:
|
|
8
8
|
*
|
|
9
|
-
* 1. **Stated**: `status` is `'streaming'` or `'pending'
|
|
10
|
-
* condition every call site used before this helper existed, role included, so
|
|
11
|
-
* no existing behaviour shifts.
|
|
9
|
+
* 1. **Stated**: `status` is `'streaming'` or `'pending'`, whatever the role.
|
|
12
10
|
* 2. **Inferred**: an **assistant** message with **no `status` at all** and nothing
|
|
13
11
|
* in it — no `content`, no `segments`. That is the empty shell a token stream is
|
|
14
12
|
* about to fill (`appendMessage({ role: 'assistant', content: '' })` from a
|
|
15
|
-
* hand-rolled loop).
|
|
16
|
-
* on a message that had never said anything.
|
|
13
|
+
* hand-rolled loop).
|
|
17
14
|
*
|
|
18
15
|
* Only silence is interpreted. An explicit `status` — including `'completed'` on an
|
|
19
16
|
* empty message — is the application talking, and is believed.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"is-awaiting-reply.d.ts","sourceRoot":"","sources":["../../src/utils/is-awaiting-reply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD
|
|
1
|
+
{"version":3,"file":"is-awaiting-reply.d.ts","sourceRoot":"","sources":["../../src/utils/is-awaiting-reply.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAC,GAAG,OAAO,CAMjH"}
|
package/dist/utils/presence.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* What a presence-attribute SETTER makes of what it was handed
|
|
2
|
+
* What a presence-attribute SETTER makes of what it was handed.
|
|
3
3
|
*
|
|
4
4
|
* The generated attribute types map a presence attribute to `'' | null | undefined`,
|
|
5
5
|
* because React and Vue stringify what they set on a custom element — so `''` is the
|
|
6
6
|
* documented spelling for ON. Svelte 5 does not take the attribute path: it assigns
|
|
7
|
-
* the PROPERTY whenever the element has one, which
|
|
8
|
-
* types
|
|
9
|
-
* the attribute
|
|
7
|
+
* the PROPERTY whenever the element has one, which hands these setters the `''` the
|
|
8
|
+
* types promise — and `toggleAttribute(name, '')` reads an empty string as falsy, so
|
|
9
|
+
* the attribute would be REMOVED, the opposite of what the template asked for.
|
|
10
10
|
*
|
|
11
|
-
* One rule
|
|
11
|
+
* One rule serves both paths without forking the spelling: on a presence property, an
|
|
12
12
|
* empty string means ON, exactly as an empty attribute does. Everything else keeps
|
|
13
13
|
* JavaScript's own truthiness (`false`, `null`, `undefined` → OFF).
|
|
14
14
|
*/
|
package/dist/utils/segments.d.ts
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* What a segment knows about itself — stamped in one place.
|
|
3
3
|
*
|
|
4
|
-
* A segment
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* app itself: stamping in the parser would have left a TOOL CALL — the single most
|
|
16
|
-
* useful duration in the whole transcript — with no measurement at all. Worse, the
|
|
17
|
-
* parser's own `segmentCounter` would have produced a wrong index: it is recreated
|
|
18
|
-
* on every `turn-start`, while a tool round-trip appends to the SAME message across
|
|
19
|
-
* turns, so one message would hold two segments at index 0, silently.
|
|
4
|
+
* A segment carries an identity (`messageId`, `index`) and a measurement
|
|
5
|
+
* (`startedAt`, `endedAt`), so a custom renderer, which receives only the segment, can
|
|
6
|
+
* learn its message and its duration.
|
|
7
|
+
*
|
|
8
|
+
* **Why the stamp lives here and not in `AparteStreamParser`.** `tool_call` segments
|
|
9
|
+
* are built by the stream adapter and `prefixSegments` by the app itself: stamping in
|
|
10
|
+
* the parser would leave
|
|
11
|
+
* a TOOL CALL — the single most useful duration in the whole transcript — with no
|
|
12
|
+
* measurement at all. The parser's own `segmentCounter` would also produce a wrong
|
|
13
|
+
* index: it is recreated on every `turn-start`, while a tool round-trip appends to the
|
|
14
|
+
* SAME message across turns, so one message would hold two segments at index 0.
|
|
20
15
|
*
|
|
21
16
|
* A segment can only reach a transcript one way — through `addSegment` — and there
|
|
22
17
|
* are exactly two owners of the array behind it: `aparte-chat-viewport` (native) and
|
|
@@ -33,7 +28,7 @@ import type { AparteSegmentDefaults, AparteSegmentTiming, AparteSegment } from '
|
|
|
33
28
|
*
|
|
34
29
|
* Returns a new object; the caller's segment is never mutated — the viewport hands
|
|
35
30
|
* the same segment object to the repository AND to the bubble, so mutating one is
|
|
36
|
-
* action at a distance
|
|
31
|
+
* action at a distance.
|
|
37
32
|
*
|
|
38
33
|
* A value already present is never overwritten, so a segment rehydrated from a
|
|
39
34
|
* consumer's storage keeps the numbers it was persisted with.
|
|
@@ -42,13 +37,11 @@ export declare function stampSegmentOnInsert(segments: readonly AparteSegment[],
|
|
|
42
37
|
/**
|
|
43
38
|
* A segment arriving from STORAGE or a server, rather than starting now.
|
|
44
39
|
*
|
|
45
|
-
* The counterpart of {@link stampSegmentOnInsert}
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* stored conversation produced different numbers depending on the mode and on whether
|
|
51
|
-
* a branch tree had been saved. Not a lie so much as an incoherence.
|
|
40
|
+
* The counterpart of {@link stampSegmentOnInsert}: the two are not the same act, and
|
|
41
|
+
* treating them as one would invent history — a conversation from three weeks ago
|
|
42
|
+
* would claim each of its segments had started this second. Every load path goes
|
|
43
|
+
* through this one, so the same stored conversation produces the same numbers
|
|
44
|
+
* whatever the mode and whether a branch tree was saved.
|
|
52
45
|
*
|
|
53
46
|
* What it writes, and why each:
|
|
54
47
|
*
|
|
@@ -64,15 +57,14 @@ export declare function stampSegmentOnInsert(segments: readonly AparteSegment[],
|
|
|
64
57
|
* `openSegmentIds`, which reads exactly this flag — would have the next turn-close
|
|
65
58
|
* stamp it a brand-new `endedAt`.
|
|
66
59
|
* - a `tool_call` persisted as `awaiting-approval` — or `pending` in a message that is
|
|
67
|
-
*
|
|
60
|
+
* not in flight, a call saved while it ran, which a server loop's cut connection
|
|
68
61
|
* leaves behind — becomes `'aborted'`, for the same
|
|
69
62
|
* reason and through a hole the line above cannot reach: `isSegmentSettled` reads
|
|
70
|
-
* STATUS for a tool call, not `isStreaming`, so a restored gate
|
|
71
|
-
* that awaited the decision is gone and the promise it would have settled went
|
|
72
|
-
* the page, so the request is unanswerable — and `'aborted'` rather than
|
|
73
|
-
* because nobody refused anything.
|
|
74
|
-
*
|
|
75
|
-
* normalisation this function was already the single funnel for. The exception is a
|
|
63
|
+
* STATUS for a tool call, not `isStreaming`, so a restored gate would stay OPEN. The
|
|
64
|
+
* loop that awaited the decision is gone and the promise it would have settled went
|
|
65
|
+
* with the page, so the request is unanswerable — and `'aborted'` rather than
|
|
66
|
+
* `'rejected'` because nobody refused anything. Consumers need not normalise those
|
|
67
|
+
* statuses on save. The exception is a
|
|
76
68
|
* call that carries a continuation ticket (`deferred.ticket`): a server loop paused
|
|
77
69
|
* on it, nothing in the page was awaiting it, and it can still be answered
|
|
78
70
|
* (`AparteClient.resumeDeferred`).
|
|
@@ -104,12 +96,10 @@ export declare function isSegmentSettled(segment: AparteSegment): boolean;
|
|
|
104
96
|
* Move `endedAt` to now while the segment is open; freeze it once it settles.
|
|
105
97
|
*
|
|
106
98
|
* `endedAt` is **the moment content last arrived**, and that is the only honest
|
|
107
|
-
* signal available. Two simpler rules
|
|
99
|
+
* signal available. Two simpler rules are wrong:
|
|
108
100
|
*
|
|
109
101
|
* - *"ends when the turn ends"* — a reasoning block would then span the whole
|
|
110
|
-
* answer that followed it. 2s of thinking before a 20s reply
|
|
111
|
-
* mocked stream hides this (it moves from reasoning to text in milliseconds); a
|
|
112
|
-
* real model does not.
|
|
102
|
+
* answer that followed it. 2s of thinking before a 20s reply would read "22s".
|
|
113
103
|
* - *"ends when the next segment starts"* — the same error, smaller: if the next
|
|
114
104
|
* segment opens ten seconds later, those ten seconds are counted as thinking,
|
|
115
105
|
* while the person watching the screen knows perfectly well nothing happened.
|
|
@@ -128,7 +118,7 @@ export declare function stampSegmentOnUpdate(segment: AparteSegment, updates: Pa
|
|
|
128
118
|
/**
|
|
129
119
|
* Merge an update into a segment without one writer erasing the other's `meta`.
|
|
130
120
|
*
|
|
131
|
-
* `{ ...segment, ...updates }` is wrong
|
|
121
|
+
* `{ ...segment, ...updates }` is wrong because `meta` has two writers. A consumer's
|
|
132
122
|
* `updateSegment(id, { meta: { cost } })` is presentation, not activity, so it passes
|
|
133
123
|
* through {@link stampSegmentOnUpdate} untouched — and a plain spread would then
|
|
134
124
|
* replace the whole bag and take `meta.aparte` with it. The measurement would vanish
|
|
@@ -136,8 +126,7 @@ export declare function stampSegmentOnUpdate(segment: AparteSegment, updates: Pa
|
|
|
136
126
|
*
|
|
137
127
|
* So the bag is merged one level, and `aparte` inside it merged again. Every site that
|
|
138
128
|
* folds an update into a segment goes through here — the viewport, the host and the
|
|
139
|
-
* bubble
|
|
140
|
-
* once.
|
|
129
|
+
* bubble.
|
|
141
130
|
*/
|
|
142
131
|
export declare function mergeSegmentUpdate(segment: AparteSegment, updates: Partial<AparteSegment>): AparteSegment;
|
|
143
132
|
/**
|
|
@@ -145,19 +134,15 @@ export declare function mergeSegmentUpdate(segment: AparteSegment, updates: Part
|
|
|
145
134
|
*
|
|
146
135
|
* The five identity/measurement fields are optional because they describe a
|
|
147
136
|
* LIFECYCLE: a segment built by hand or freshly emitted by the parser has not been
|
|
148
|
-
* inserted yet, so it has no start, and an open segment has no end.
|
|
149
|
-
* required would either force every creation site to stamp — six of them, which is
|
|
150
|
-
* the forgotten-sibling shape this seam exists to prevent — or force a hand-written
|
|
151
|
-
* literal to invent values the owner then refuses to overwrite.
|
|
137
|
+
* inserted yet, so it has no start, and an open segment has no end.
|
|
152
138
|
*
|
|
153
|
-
* The cost of that optionality lands on the reader, and this
|
|
154
|
-
* guard
|
|
139
|
+
* The cost of that optionality lands on the reader, and this removes it. Hand-written,
|
|
140
|
+
* the guard is
|
|
155
141
|
*
|
|
156
142
|
* if (!isSegmentSettled(seg) || !seg.startedAt || !seg.endedAt) return;
|
|
157
143
|
*
|
|
158
144
|
* — three conditions to get right, and the last two are wrong at epoch 0, where a
|
|
159
|
-
* valid timestamp is falsy.
|
|
160
|
-
* to 0 routinely, so the trap was already in the repo waiting for its first victim.
|
|
145
|
+
* valid timestamp is falsy.
|
|
161
146
|
*
|
|
162
147
|
* It deliberately does NOT ask whether the segment is finished: during a turn a
|
|
163
148
|
* growing duration is exactly what a "thinking…" counter shows. Pair it with
|
|
@@ -168,12 +153,10 @@ export declare function segmentDuration(segment: AparteSegment): number | undefi
|
|
|
168
153
|
* The patch that records "content just arrived on this segment".
|
|
169
154
|
*
|
|
170
155
|
* The append paths do not go through {@link stampSegmentOnUpdate} — they rebuild
|
|
171
|
-
* the segment themselves
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
* — which is not a style preference: `pnpm check:segment-stamp` refused the two
|
|
176
|
-
* inline `endedAt: Date.now()` this replaced, and it was right to.
|
|
156
|
+
* the segment themselves (the viewport must not mutate an object the bubble shares;
|
|
157
|
+
* the host coalesces a frame's chunks into one absolute write). They still have to
|
|
158
|
+
* move `endedAt`, because content arriving IS the activity it measures. So they spread
|
|
159
|
+
* this in, and the rule stays in one file (`pnpm check:segment-stamp` enforces it).
|
|
177
160
|
*
|
|
178
161
|
* Empty once the segment has settled, so a late write cannot move a final end.
|
|
179
162
|
*/
|
|
@@ -183,14 +166,13 @@ export declare function stampSegmentActivity(segment: AparteSegment): Partial<Ap
|
|
|
183
166
|
* that it CLOSED, when it did.
|
|
184
167
|
*
|
|
185
168
|
* The parser marks the segments it closes (`</think>`, a closing fence,
|
|
186
|
-
* `</artifact>`, the opening of the next block).
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
* patch by hand — that is how the same rule ends up spelled three different ways.
|
|
169
|
+
* `</artifact>`, the opening of the next block). Forwarding `{ content }` alone would
|
|
170
|
+
* hand the owner a finished segment that looks exactly like a streaming one, and the
|
|
171
|
+
* end would have to be inferred from the end of the TURN — a reasoning block would
|
|
172
|
+
* read "Thinking" for as long as the answer takes to stream.
|
|
173
|
+
*
|
|
174
|
+
* Every site that forwards parser output goes through here, so the rule is spelled
|
|
175
|
+
* once.
|
|
194
176
|
*/
|
|
195
177
|
export declare function segmentContentUpdate(segment: AparteSegment): Partial<AparteSegment>;
|
|
196
178
|
/**
|
|
@@ -212,13 +194,12 @@ export declare function isTerminalStatus(status: string | null | undefined): boo
|
|
|
212
194
|
* (`updateMessage({ status: 'completed' })`). So the message's end is the segments'
|
|
213
195
|
* end, and this says which ones are still waiting for it.
|
|
214
196
|
*
|
|
215
|
-
* It returns ids rather than settling the array itself, and that is the point
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
* already depend on.
|
|
197
|
+
* It returns ids rather than settling the array itself, and that is the point: a
|
|
198
|
+
* silent mutation notifies nobody, so the model would gain its `endedAt` while the
|
|
199
|
+
* RENDERER never learned the segment had settled. Routing each close through the
|
|
200
|
+
* owner's own `updateSegment` gives one path that stamps the model AND repaints the
|
|
201
|
+
* bubble, which is also the path `update()` and the incremental Markdown flush
|
|
202
|
+
* depend on.
|
|
222
203
|
*
|
|
223
204
|
* Already-closed segments are skipped, so reporting a turn finished twice — a
|
|
224
205
|
* re-render, a branch switch, a reloaded conversation — cannot move an end.
|
|
@@ -227,21 +208,16 @@ export declare function openSegmentIds(segments: readonly AparteSegment[]): stri
|
|
|
227
208
|
/**
|
|
228
209
|
* Adopt every segment of a message arriving from storage or a server.
|
|
229
210
|
*
|
|
230
|
-
* The message-level counterpart of {@link adoptSegment},
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
* straight to the repository, one did nothing, and the host's `appendMessage` — same
|
|
235
|
-
* name as the viewport's, opposite behaviour — did nothing either. The same stored
|
|
236
|
-
* conversation therefore produced different numbers depending on the mode and on
|
|
237
|
-
* whether a branch tree had been saved.
|
|
211
|
+
* The message-level counterpart of {@link adoptSegment}, shared by the FOUR entry paths
|
|
212
|
+
* for historical data (`setMessages`, `importTree`, `addMessage`, and the framework
|
|
213
|
+
* host's own list setter), so the same stored conversation produces the same numbers
|
|
214
|
+
* whatever the mode and whether a branch tree was saved.
|
|
238
215
|
*
|
|
239
216
|
* Always returns a NEW object, even for a message with no segments. That looks like a
|
|
240
217
|
* missed optimisation and is the invariant of this whole file: the viewport hands the
|
|
241
218
|
* same object to the repository AND to the framework's list, so sharing one makes the
|
|
242
|
-
* immediate paint and the coalesced write land on the same string twice
|
|
243
|
-
*
|
|
244
|
-
* for exactly that bug, within minutes of my writing the shortcut.
|
|
219
|
+
* immediate paint and the coalesced write land on the same string twice, doubling
|
|
220
|
+
* every streamed reply.
|
|
245
221
|
*/
|
|
246
222
|
export declare function adoptMessageSegments<T extends {
|
|
247
223
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"segments.d.ts","sourceRoot":"","sources":["../../src/utils/segments.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"segments.d.ts","sourceRoot":"","sources":["../../src/utils/segments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AA2BnG;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAChC,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,qBAAqB,GACjC,aAAa,CAWf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,YAAY,CACxB,QAAQ,EAAE,SAAS,aAAa,EAAE,EAClC,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,MAAM;AACjB,yFAAyF;AACzF,IAAI,UAAQ,GACb,aAAa,CAYf;AASD;;;;;;GAMG;AACH,wBAAgB,aAAa,CACzB,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,GACrC,mBAAmB,GAAG,SAAS,CAEjC;AA6CD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAGhE;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,oBAAoB,CAChC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,GAChC,OAAO,CAAC,aAAa,CAAC,CAgBxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAC9B,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,GAChC,aAAa,CAef;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAI1E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAEnF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAMnF;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE3E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,MAAM,EAAE,CAE3E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CAYzH;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,IAAI,CAMhE"}
|
|
@@ -16,5 +16,5 @@
|
|
|
16
16
|
* The return is TEXT and never markup: both call sites put it on screen through
|
|
17
17
|
* `textContent` or an escaped interpolation, because the arguments are model-authored.
|
|
18
18
|
*/
|
|
19
|
-
export declare function describeToolInput(input: unknown): string;
|
|
19
|
+
export declare function describeToolInput(input: unknown, format?: (input: Record<string, unknown>) => string): string;
|
|
20
20
|
//# sourceMappingURL=tool-input.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-input.d.ts","sourceRoot":"","sources":["../../src/utils/tool-input.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"tool-input.d.ts","sourceRoot":"","sources":["../../src/utils/tool-input.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,GAAG,MAAM,CAe7G"}
|