@aleph-alpha/chat-kit 1.6.0 → 1.9.1
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/dist/{CkInput.vue_vue_type_script_setup_true_lang-C5C09u0z.js → CkInput.vue_vue_type_script_setup_true_lang-CHPs-R5p.js} +1 -1
- package/dist/adapters/responses-api.d.ts +47 -18
- package/dist/adapters/responses-api.d.ts.map +1 -1
- package/dist/adapters/responses-api.js +22 -16
- package/dist/components/base/CkHistoryItem/activeIndicator.d.ts +2 -12
- package/dist/components/base/CkHistoryItem/activeIndicator.d.ts.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/types.d.ts +12 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -4
- package/src/adapters/responses-api.spec.ts +56 -4
- package/src/adapters/responses-api.ts +89 -44
- package/src/components/base/CkHistoryItem/activeIndicator.ts +2 -13
- package/src/types.ts +12 -3
|
@@ -489,7 +489,7 @@ const _sfc_main$b = /* @__PURE__ */ defineComponent({
|
|
|
489
489
|
}
|
|
490
490
|
});
|
|
491
491
|
const CkFeedbackButton = /* @__PURE__ */ _export_sfc(_sfc_main$b, [["__scopeId", "data-v-245705b8"]]);
|
|
492
|
-
const CHAT_HISTORY_ACTIVE_INDICATOR_CLASS =
|
|
492
|
+
const CHAT_HISTORY_ACTIVE_INDICATOR_CLASS = "ui-active-indicator";
|
|
493
493
|
const _hoisted_1$3 = ["data-active"];
|
|
494
494
|
const _hoisted_2$2 = { class: "min-w-0 flex-1" };
|
|
495
495
|
const _hoisted_3$1 = { class: "truncate body-14-regular text-content-on-surface-primary" };
|
|
@@ -18,20 +18,26 @@ export interface ResponseOutputTextPart {
|
|
|
18
18
|
annotations?: ResponseAnnotation[];
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
|
-
* One reasoning fragment inside a `ResponseOutputReasoning`. The
|
|
22
|
-
* API
|
|
23
|
-
*
|
|
21
|
+
* One reasoning summary fragment inside a `ResponseOutputReasoning`. The
|
|
22
|
+
* Responses API exposes the human-readable chain-of-thought trail under
|
|
23
|
+
* `summary` as an array of `summary_text` parts; the body is surfaced for
|
|
24
|
+
* consumers that want to render it (chat-kit itself only surfaces a
|
|
24
25
|
* "thinking" indicator).
|
|
26
|
+
*
|
|
27
|
+
* This part shape is **specific to reasoning outputs** — it never appears
|
|
28
|
+
* mixed with `ResponseOutputTextPart` inside a `ResponseOutputMessage`.
|
|
25
29
|
*/
|
|
26
30
|
export interface ResponseReasoningTextPart {
|
|
27
|
-
type: '
|
|
31
|
+
type: 'summary_text';
|
|
28
32
|
text: string;
|
|
29
33
|
annotations?: ResponseAnnotation[];
|
|
30
34
|
}
|
|
31
35
|
/**
|
|
32
36
|
* Forward-compatible catch-all for content parts whose `type` chat-kit does
|
|
33
|
-
* not yet model (e.g. refusals, future part kinds
|
|
34
|
-
* `type` themselves when they need richer
|
|
37
|
+
* not yet model (e.g. refusals, future part kinds inside `unknown`-typed
|
|
38
|
+
* fields). Consumers narrow on `type` themselves when they need richer
|
|
39
|
+
* handling. Not used inside `ResponseOutputMessage` or
|
|
40
|
+
* `ResponseOutputReasoning`, whose content shapes are fixed.
|
|
35
41
|
*/
|
|
36
42
|
export interface ResponseUnknownContentPart {
|
|
37
43
|
type: string;
|
|
@@ -39,35 +45,36 @@ export interface ResponseUnknownContentPart {
|
|
|
39
45
|
annotations?: ResponseAnnotation[];
|
|
40
46
|
[key: string]: unknown;
|
|
41
47
|
}
|
|
42
|
-
/**
|
|
43
|
-
* Discriminated union of content parts that can appear inside a Responses-
|
|
44
|
-
* API output item. `ResponseOutputTextPart` and `ResponseReasoningTextPart`
|
|
45
|
-
* cover the rendered shapes; the catch-all keeps the union open.
|
|
46
|
-
*/
|
|
47
|
-
export type OutputContentPart = ResponseOutputTextPart | ResponseReasoningTextPart | ResponseUnknownContentPart;
|
|
48
48
|
/**
|
|
49
49
|
* Visible message produced by a Responses-API turn (assistant reply or
|
|
50
50
|
* echoed user input). Carries the renderable text content; `responsesToTree`
|
|
51
|
-
* extracts text from `content` to build the chat tree.
|
|
51
|
+
* extracts text from `content` to build the chat tree. All entries are
|
|
52
|
+
* `ResponseOutputTextPart`s — no reasoning or unknown parts are mixed in.
|
|
52
53
|
*/
|
|
53
54
|
export interface ResponseOutputMessage {
|
|
54
55
|
type: 'message';
|
|
55
56
|
id: string;
|
|
56
57
|
status: string;
|
|
57
58
|
role: 'assistant' | 'user';
|
|
58
|
-
content:
|
|
59
|
+
content: ResponseOutputTextPart[];
|
|
59
60
|
}
|
|
60
61
|
/**
|
|
61
|
-
* Chain-of-thought trail produced by the assistant during a turn.
|
|
62
|
-
*
|
|
63
|
-
*
|
|
62
|
+
* Chain-of-thought trail produced by the assistant during a turn. The
|
|
63
|
+
* human-readable summary lives on `summary` as an array of
|
|
64
|
+
* `ResponseReasoningTextPart`s (all `summary_text`); `content` is reserved
|
|
65
|
+
* for the opaque/raw reasoning payload the API may attach and is kept
|
|
66
|
+
* `unknown` so consumers can downcast it on their own.
|
|
67
|
+
*
|
|
68
|
+
* Surfaced in chat-kit only as a "thinking" indicator; consumers may render
|
|
69
|
+
* the `summary` parts directly when desired.
|
|
64
70
|
*/
|
|
65
71
|
export interface ResponseOutputReasoning {
|
|
66
72
|
type: 'reasoning';
|
|
67
73
|
id: string;
|
|
68
74
|
status: string;
|
|
69
75
|
role?: 'assistant' | null;
|
|
70
|
-
|
|
76
|
+
summary: ResponseReasoningTextPart[];
|
|
77
|
+
content: unknown;
|
|
71
78
|
}
|
|
72
79
|
/**
|
|
73
80
|
* Single tool entry returned inside `mcp_list_tools` (and similar tool-
|
|
@@ -86,6 +93,22 @@ export interface ResponseToolDescriptor {
|
|
|
86
93
|
* today; extend it as new tool kinds are introduced upstream.
|
|
87
94
|
*/
|
|
88
95
|
export type ResponseOutputToolType = 'mcp_list_tools' | 'mcp_call' | 'tool_call' | 'function_call' | 'web_search_call' | 'file_search_call' | 'code_interpreter_call' | 'image_generation_call' | 'local_shell_call';
|
|
96
|
+
/**
|
|
97
|
+
* Server-provided rendering hints for a tool invocation. The server emits a
|
|
98
|
+
* human-readable `text` (e.g. "Searching the web…") and a lucide.dev `icon`
|
|
99
|
+
* name to display alongside the tool, plus a `phase` describing the current
|
|
100
|
+
* lifecycle stage so the UI can swap labels/icons as the call progresses.
|
|
101
|
+
*
|
|
102
|
+
* Only `'done'` is received in a response today.
|
|
103
|
+
*/
|
|
104
|
+
export interface ResponseOutputToolDisplay {
|
|
105
|
+
/** Human-readable label to render for the tool (server-controlled). */
|
|
106
|
+
text: string;
|
|
107
|
+
/** Lucide.dev icon name to render next to the label. */
|
|
108
|
+
icon: string;
|
|
109
|
+
/** Lifecycle phase of the tool call. */
|
|
110
|
+
phase: 'done';
|
|
111
|
+
}
|
|
89
112
|
/**
|
|
90
113
|
* Tool-related output produced during a Responses-API turn. Covers tool
|
|
91
114
|
* discovery (`mcp_list_tools`), invocation (`mcp_call`, `function_call`,
|
|
@@ -109,6 +132,12 @@ export interface ResponseOutputTool {
|
|
|
109
132
|
call_id?: string;
|
|
110
133
|
/** Tool result payload (shape depends on the tool kind). */
|
|
111
134
|
output?: unknown;
|
|
135
|
+
/**
|
|
136
|
+
* Optional server-provided display hints (label, icon, phase). When
|
|
137
|
+
* present, `responsesToTree` forwards `text` and `icon` onto the
|
|
138
|
+
* resulting `MessageToolContent` so the UI can render them directly.
|
|
139
|
+
*/
|
|
140
|
+
display?: ResponseOutputToolDisplay;
|
|
112
141
|
[key: string]: unknown;
|
|
113
142
|
}
|
|
114
143
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"responses-api.d.ts","sourceRoot":"","sources":["../../src/adapters/responses-api.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EACV,gBAAgB,EAIjB,MAAM,UAAU,CAAC;AAMlB;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,aAAa,GAAG,MAAM,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,kBAAkB,EAAE,CAAC;CACpC;AAED
|
|
1
|
+
{"version":3,"file":"responses-api.d.ts","sourceRoot":"","sources":["../../src/adapters/responses-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { g as generateId } from "../generateId-BHf0W4Rq.js";
|
|
2
|
-
function extractMessageText(
|
|
3
|
-
if (typeof content === "string") return content.trim();
|
|
4
|
-
return extractTextFromParts(content);
|
|
5
|
-
}
|
|
6
|
-
function extractTextFromParts(parts) {
|
|
2
|
+
function extractMessageText(parts) {
|
|
7
3
|
let text = "";
|
|
8
4
|
for (const part of parts) {
|
|
9
5
|
if (part.type === "output_text" || part.type === "text") {
|
|
@@ -12,10 +8,10 @@ function extractTextFromParts(parts) {
|
|
|
12
8
|
}
|
|
13
9
|
return text.trim();
|
|
14
10
|
}
|
|
15
|
-
function
|
|
11
|
+
function extractReasoningSummary(parts) {
|
|
16
12
|
let text = "";
|
|
17
13
|
for (const part of parts) {
|
|
18
|
-
if (part.type === "
|
|
14
|
+
if (part.type === "summary_text") {
|
|
19
15
|
text += part.text ?? "";
|
|
20
16
|
}
|
|
21
17
|
}
|
|
@@ -24,12 +20,20 @@ function extractReasoningText(parts) {
|
|
|
24
20
|
function textPart(text, id) {
|
|
25
21
|
return { type: "text", id: id ?? generateId(), text, status: "completed" };
|
|
26
22
|
}
|
|
23
|
+
function toolPart(out) {
|
|
24
|
+
return {
|
|
25
|
+
type: "tool",
|
|
26
|
+
id: out.id,
|
|
27
|
+
name: out.name ?? out.type,
|
|
28
|
+
...out.display ? { text: out.display.text, icon: out.display.icon } : {}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
27
31
|
function toAssistantParts(resp) {
|
|
28
32
|
const parts = [];
|
|
29
33
|
for (const out of resp.output ?? []) {
|
|
30
34
|
switch (out.type) {
|
|
31
35
|
case "reasoning": {
|
|
32
|
-
const text =
|
|
36
|
+
const text = extractReasoningSummary(out.summary ?? []);
|
|
33
37
|
parts.push({
|
|
34
38
|
type: "reasoning",
|
|
35
39
|
id: out.id,
|
|
@@ -51,11 +55,7 @@ function toAssistantParts(resp) {
|
|
|
51
55
|
case "mcp_call":
|
|
52
56
|
case "function_call":
|
|
53
57
|
case "tool_call": {
|
|
54
|
-
parts.push(
|
|
55
|
-
type: "tool",
|
|
56
|
-
id: out.id,
|
|
57
|
-
name: out.name ?? out.type
|
|
58
|
-
});
|
|
58
|
+
parts.push(toolPart(out));
|
|
59
59
|
break;
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -72,10 +72,16 @@ function getAssistantNodeId(resp) {
|
|
|
72
72
|
}
|
|
73
73
|
function extractInputText(rawContent) {
|
|
74
74
|
if (typeof rawContent === "string") return rawContent.trim();
|
|
75
|
-
if (Array.isArray(rawContent))
|
|
76
|
-
|
|
75
|
+
if (!Array.isArray(rawContent)) return "";
|
|
76
|
+
let text = "";
|
|
77
|
+
for (const raw of rawContent) {
|
|
78
|
+
if (!raw || typeof raw !== "object") continue;
|
|
79
|
+
const part = raw;
|
|
80
|
+
if ((part.type === "input_text" || part.type === "output_text" || part.type === "text") && typeof part.text === "string") {
|
|
81
|
+
text += part.text;
|
|
82
|
+
}
|
|
77
83
|
}
|
|
78
|
-
return
|
|
84
|
+
return text.trim();
|
|
79
85
|
}
|
|
80
86
|
function responseToMessageNodes(resp) {
|
|
81
87
|
const nodes = [];
|
|
@@ -1,15 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* history row.
|
|
4
|
-
*
|
|
5
|
-
* The `::before` pseudo-element is always mounted so CSS has something to
|
|
6
|
-
* transition. At rest it's painted from `scale-x-0` + `opacity-0` with its
|
|
7
|
-
* transform anchored on the left edge (`origin-left`); when the row's
|
|
8
|
-
* `data-active="true"` flips on, the bar paints in from left to right while
|
|
9
|
-
* fading in, using a 200ms linear curve.
|
|
10
|
-
*
|
|
11
|
-
* Kept as a string constant (rather than generated via `cn`) so UnoCSS's
|
|
12
|
-
* static scanner picks up every utility class for atomic CSS generation.
|
|
2
|
+
* Uses the shared UI library active indicator preflight class.
|
|
13
3
|
*/
|
|
14
|
-
export declare const CHAT_HISTORY_ACTIVE_INDICATOR_CLASS = "
|
|
4
|
+
export declare const CHAT_HISTORY_ACTIVE_INDICATOR_CLASS = "ui-active-indicator";
|
|
15
5
|
//# sourceMappingURL=activeIndicator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"activeIndicator.d.ts","sourceRoot":"","sources":["../../../../src/components/base/CkHistoryItem/activeIndicator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"activeIndicator.d.ts","sourceRoot":"","sources":["../../../../src/components/base/CkHistoryItem/activeIndicator.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,mCAAmC,wBAAwB,CAAC"}
|
package/dist/components/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _, a, b, C, c, d, e, f, g, h, i, j, k, l, m, n, o, p } from "../CkInput.vue_vue_type_script_setup_true_lang-
|
|
1
|
+
import { _, a, b, C, c, d, e, f, g, h, i, j, k, l, m, n, o, p } from "../CkInput.vue_vue_type_script_setup_true_lang-CHPs-R5p.js";
|
|
2
2
|
export {
|
|
3
3
|
_ as CkAgentMessage,
|
|
4
4
|
a as CkConversation,
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { u } from "./useMessageHandler-ZRC-gIOJ.js";
|
|
2
2
|
import { C, d, p, u as u2, a } from "./useChatKitLabels-ftC52m7f.js";
|
|
3
3
|
import { S, c, d as d2, a as a2, u as u3, b, e, f } from "./index-BLq6_Lt2.js";
|
|
4
|
-
import { _, a as a3, b as b2, C as C2, c as c2, d as d3, e as e2, f as f2, g, h, i, j, k, l, m, n, o, p as p2 } from "./CkInput.vue_vue_type_script_setup_true_lang-
|
|
4
|
+
import { _, a as a3, b as b2, C as C2, c as c2, d as d3, e as e2, f as f2, g, h, i, j, k, l, m, n, o, p as p2 } from "./CkInput.vue_vue_type_script_setup_true_lang-CHPs-R5p.js";
|
|
5
5
|
export {
|
|
6
6
|
C as CHAT_KIT_LABELS,
|
|
7
7
|
_ as CkAgentMessage,
|
package/dist/types.d.ts
CHANGED
|
@@ -24,19 +24,28 @@ export interface MessageTextContent {
|
|
|
24
24
|
* Tool invocation triggered by the assistant during its turn. Only the tool
|
|
25
25
|
* name is rendered; arguments and results are intentionally outside the
|
|
26
26
|
* UI-facing model and should be tracked by the host application.
|
|
27
|
+
*
|
|
28
|
+
* `text` and `icon` are optional server-provided display hints (sourced from
|
|
29
|
+
* a `display` block on the wire payload, e.g.
|
|
30
|
+
* `ResponseOutputTool.display`). When present, the UI is expected to render
|
|
31
|
+
* the human-readable `text` and the lucide.dev `icon` instead of falling
|
|
32
|
+
* back to the raw tool `name`.
|
|
27
33
|
*/
|
|
28
34
|
export interface MessageToolContent {
|
|
29
35
|
type: 'tool';
|
|
30
36
|
id: string;
|
|
31
37
|
name: string;
|
|
38
|
+
text?: string;
|
|
39
|
+
icon?: string;
|
|
32
40
|
}
|
|
33
41
|
/**
|
|
34
42
|
* Chain-of-thought / reasoning segment produced by the assistant. `text` is
|
|
35
43
|
* the (optional) human-readable trail — populated when the underlying
|
|
36
44
|
* transport exposes reasoning content (`REASONING_MESSAGE_CONTENT` deltas
|
|
37
|
-
* during a live run, `
|
|
38
|
-
*
|
|
39
|
-
*
|
|
45
|
+
* during a live run, `summary_text` parts under
|
|
46
|
+
* `ResponseOutputReasoning.summary` when re-hydrating from the Responses
|
|
47
|
+
* API). Surfaces that only need a "Thinking…" / "Thought" indicator can
|
|
48
|
+
* ignore it and rely on `status` alone.
|
|
40
49
|
*/
|
|
41
50
|
export interface MessageReasoningContent {
|
|
42
51
|
type: 'reasoning';
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE1D,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,CAAC;AAE1E;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG,WAAW,GAAG,YAAY,CAAC;AAE9E;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,oBAAoB,CAAC;CAC9B;AAED
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE1D,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,OAAO,CAAC;AAE1E;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG,WAAW,GAAG,YAAY,CAAC;AAE9E;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,oBAAoB,CAAC;CAC9B;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,WAAW,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,oBAAoB,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,kBAAkB,GAClB,kBAAkB,GAClB,uBAAuB,CAAC;AAE5B,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,SAAS,EAAE,IAAI,CAAC;IAChB,MAAM,EAAE,aAAa,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACnC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aleph-alpha/chat-kit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.1",
|
|
4
4
|
"description": "Chat kit package for building chat interfaces with Vue",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -52,8 +52,7 @@
|
|
|
52
52
|
"node": ">=20.19.0"
|
|
53
53
|
},
|
|
54
54
|
"publishConfig": {
|
|
55
|
-
"access": "public"
|
|
56
|
-
"registry": "https://npm.pkg.github.com"
|
|
55
|
+
"access": "public"
|
|
57
56
|
},
|
|
58
57
|
"repository": {
|
|
59
58
|
"type": "git",
|
|
@@ -72,7 +71,7 @@
|
|
|
72
71
|
"remark-parse": "^11.0.0",
|
|
73
72
|
"remark-rehype": "^11.1.2",
|
|
74
73
|
"unified": "^11.0.5",
|
|
75
|
-
"@aleph-alpha/ui-library": "2.
|
|
74
|
+
"@aleph-alpha/ui-library": "2.5.1"
|
|
76
75
|
},
|
|
77
76
|
"devDependencies": {
|
|
78
77
|
"@storybook/addon-a11y": "10.2.17",
|
|
@@ -50,7 +50,8 @@ function reasoningOutput(id: string, text: string): ResponseOutputReasoning {
|
|
|
50
50
|
id,
|
|
51
51
|
status: 'completed',
|
|
52
52
|
role: null,
|
|
53
|
-
|
|
53
|
+
summary: [{ type: 'summary_text', text }],
|
|
54
|
+
content: null,
|
|
54
55
|
};
|
|
55
56
|
}
|
|
56
57
|
|
|
@@ -178,7 +179,6 @@ describe('responsesToTree', () => {
|
|
|
178
179
|
role: 'assistant',
|
|
179
180
|
content: [
|
|
180
181
|
{ type: 'output_text', text: 'first ' },
|
|
181
|
-
{ type: 'reasoning_summary', text: 'should-be-ignored' },
|
|
182
182
|
{ type: 'text', text: 'second' },
|
|
183
183
|
],
|
|
184
184
|
},
|
|
@@ -271,6 +271,57 @@ describe('responsesToTree', () => {
|
|
|
271
271
|
expect(assistant.content[2].type).toBe('text');
|
|
272
272
|
});
|
|
273
273
|
|
|
274
|
+
it('forwards `display.text` and `display.icon` from a tool output onto the resulting tool content', () => {
|
|
275
|
+
const tree = responsesToTree([
|
|
276
|
+
makeResponse({
|
|
277
|
+
id: 'r1',
|
|
278
|
+
request_input: [userInput('Hello')],
|
|
279
|
+
output: [
|
|
280
|
+
toolOutput({
|
|
281
|
+
id: 'tool-1',
|
|
282
|
+
type: 'mcp_call',
|
|
283
|
+
name: 'firecrawl_scrape',
|
|
284
|
+
display: {
|
|
285
|
+
text: 'Searching the web',
|
|
286
|
+
icon: 'globe',
|
|
287
|
+
phase: 'done',
|
|
288
|
+
},
|
|
289
|
+
}),
|
|
290
|
+
assistantOutput('msg-a1', 'Done'),
|
|
291
|
+
],
|
|
292
|
+
}),
|
|
293
|
+
]);
|
|
294
|
+
|
|
295
|
+
const tool = tree.nodes['msg-a1']!.content[0];
|
|
296
|
+
expect(tool).toMatchObject({
|
|
297
|
+
type: 'tool',
|
|
298
|
+
id: 'tool-1',
|
|
299
|
+
name: 'firecrawl_scrape',
|
|
300
|
+
text: 'Searching the web',
|
|
301
|
+
icon: 'globe',
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it('omits `text` / `icon` on tool content when the tool output has no `display` block', () => {
|
|
306
|
+
const tree = responsesToTree([
|
|
307
|
+
makeResponse({
|
|
308
|
+
id: 'r1',
|
|
309
|
+
request_input: [userInput('Hello')],
|
|
310
|
+
output: [
|
|
311
|
+
toolOutput({ id: 'tool-1', type: 'mcp_call', name: 'search' }),
|
|
312
|
+
assistantOutput('msg-a1', 'Done'),
|
|
313
|
+
],
|
|
314
|
+
}),
|
|
315
|
+
]);
|
|
316
|
+
|
|
317
|
+
const tool = tree.nodes['msg-a1']!.content[0];
|
|
318
|
+
expect(tool.type).toBe('tool');
|
|
319
|
+
if (tool.type === 'tool') {
|
|
320
|
+
expect(tool.text).toBeUndefined();
|
|
321
|
+
expect(tool.icon).toBeUndefined();
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
|
|
274
325
|
it('creates an assistant node from reasoning / tool outputs even when no message output is present', () => {
|
|
275
326
|
const tree = responsesToTree([
|
|
276
327
|
makeResponse({
|
|
@@ -294,7 +345,7 @@ describe('responsesToTree', () => {
|
|
|
294
345
|
expect(assistant.content[1].type).toBe('tool');
|
|
295
346
|
});
|
|
296
347
|
|
|
297
|
-
it('omits reasoning text when no
|
|
348
|
+
it('omits reasoning text when no summary_text parts are present', () => {
|
|
298
349
|
const tree = responsesToTree([
|
|
299
350
|
makeResponse({
|
|
300
351
|
id: 'r1',
|
|
@@ -305,7 +356,8 @@ describe('responsesToTree', () => {
|
|
|
305
356
|
id: 'rs-empty',
|
|
306
357
|
status: 'completed',
|
|
307
358
|
role: null,
|
|
308
|
-
|
|
359
|
+
summary: [],
|
|
360
|
+
content: null,
|
|
309
361
|
},
|
|
310
362
|
assistantOutput('msg-a1', 'Hi'),
|
|
311
363
|
],
|
|
@@ -52,21 +52,27 @@ export interface ResponseOutputTextPart {
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
|
-
* One reasoning fragment inside a `ResponseOutputReasoning`. The
|
|
56
|
-
* API
|
|
57
|
-
*
|
|
55
|
+
* One reasoning summary fragment inside a `ResponseOutputReasoning`. The
|
|
56
|
+
* Responses API exposes the human-readable chain-of-thought trail under
|
|
57
|
+
* `summary` as an array of `summary_text` parts; the body is surfaced for
|
|
58
|
+
* consumers that want to render it (chat-kit itself only surfaces a
|
|
58
59
|
* "thinking" indicator).
|
|
60
|
+
*
|
|
61
|
+
* This part shape is **specific to reasoning outputs** — it never appears
|
|
62
|
+
* mixed with `ResponseOutputTextPart` inside a `ResponseOutputMessage`.
|
|
59
63
|
*/
|
|
60
64
|
export interface ResponseReasoningTextPart {
|
|
61
|
-
type: '
|
|
65
|
+
type: 'summary_text';
|
|
62
66
|
text: string;
|
|
63
67
|
annotations?: ResponseAnnotation[];
|
|
64
68
|
}
|
|
65
69
|
|
|
66
70
|
/**
|
|
67
71
|
* Forward-compatible catch-all for content parts whose `type` chat-kit does
|
|
68
|
-
* not yet model (e.g. refusals, future part kinds
|
|
69
|
-
* `type` themselves when they need richer
|
|
72
|
+
* not yet model (e.g. refusals, future part kinds inside `unknown`-typed
|
|
73
|
+
* fields). Consumers narrow on `type` themselves when they need richer
|
|
74
|
+
* handling. Not used inside `ResponseOutputMessage` or
|
|
75
|
+
* `ResponseOutputReasoning`, whose content shapes are fixed.
|
|
70
76
|
*/
|
|
71
77
|
export interface ResponseUnknownContentPart {
|
|
72
78
|
type: string;
|
|
@@ -75,40 +81,37 @@ export interface ResponseUnknownContentPart {
|
|
|
75
81
|
[key: string]: unknown;
|
|
76
82
|
}
|
|
77
83
|
|
|
78
|
-
/**
|
|
79
|
-
* Discriminated union of content parts that can appear inside a Responses-
|
|
80
|
-
* API output item. `ResponseOutputTextPart` and `ResponseReasoningTextPart`
|
|
81
|
-
* cover the rendered shapes; the catch-all keeps the union open.
|
|
82
|
-
*/
|
|
83
|
-
export type OutputContentPart =
|
|
84
|
-
| ResponseOutputTextPart
|
|
85
|
-
| ResponseReasoningTextPart
|
|
86
|
-
| ResponseUnknownContentPart;
|
|
87
|
-
|
|
88
84
|
/**
|
|
89
85
|
* Visible message produced by a Responses-API turn (assistant reply or
|
|
90
86
|
* echoed user input). Carries the renderable text content; `responsesToTree`
|
|
91
|
-
* extracts text from `content` to build the chat tree.
|
|
87
|
+
* extracts text from `content` to build the chat tree. All entries are
|
|
88
|
+
* `ResponseOutputTextPart`s — no reasoning or unknown parts are mixed in.
|
|
92
89
|
*/
|
|
93
90
|
export interface ResponseOutputMessage {
|
|
94
91
|
type: 'message';
|
|
95
92
|
id: string;
|
|
96
93
|
status: string;
|
|
97
94
|
role: 'assistant' | 'user';
|
|
98
|
-
content:
|
|
95
|
+
content: ResponseOutputTextPart[];
|
|
99
96
|
}
|
|
100
97
|
|
|
101
98
|
/**
|
|
102
|
-
* Chain-of-thought trail produced by the assistant during a turn.
|
|
103
|
-
*
|
|
104
|
-
*
|
|
99
|
+
* Chain-of-thought trail produced by the assistant during a turn. The
|
|
100
|
+
* human-readable summary lives on `summary` as an array of
|
|
101
|
+
* `ResponseReasoningTextPart`s (all `summary_text`); `content` is reserved
|
|
102
|
+
* for the opaque/raw reasoning payload the API may attach and is kept
|
|
103
|
+
* `unknown` so consumers can downcast it on their own.
|
|
104
|
+
*
|
|
105
|
+
* Surfaced in chat-kit only as a "thinking" indicator; consumers may render
|
|
106
|
+
* the `summary` parts directly when desired.
|
|
105
107
|
*/
|
|
106
108
|
export interface ResponseOutputReasoning {
|
|
107
109
|
type: 'reasoning';
|
|
108
110
|
id: string;
|
|
109
111
|
status: string;
|
|
110
112
|
role?: 'assistant' | null;
|
|
111
|
-
|
|
113
|
+
summary: ResponseReasoningTextPart[];
|
|
114
|
+
content: unknown;
|
|
112
115
|
}
|
|
113
116
|
|
|
114
117
|
/**
|
|
@@ -139,6 +142,23 @@ export type ResponseOutputToolType =
|
|
|
139
142
|
| 'image_generation_call'
|
|
140
143
|
| 'local_shell_call';
|
|
141
144
|
|
|
145
|
+
/**
|
|
146
|
+
* Server-provided rendering hints for a tool invocation. The server emits a
|
|
147
|
+
* human-readable `text` (e.g. "Searching the web…") and a lucide.dev `icon`
|
|
148
|
+
* name to display alongside the tool, plus a `phase` describing the current
|
|
149
|
+
* lifecycle stage so the UI can swap labels/icons as the call progresses.
|
|
150
|
+
*
|
|
151
|
+
* Only `'done'` is received in a response today.
|
|
152
|
+
*/
|
|
153
|
+
export interface ResponseOutputToolDisplay {
|
|
154
|
+
/** Human-readable label to render for the tool (server-controlled). */
|
|
155
|
+
text: string;
|
|
156
|
+
/** Lucide.dev icon name to render next to the label. */
|
|
157
|
+
icon: string;
|
|
158
|
+
/** Lifecycle phase of the tool call. */
|
|
159
|
+
phase: 'done';
|
|
160
|
+
}
|
|
161
|
+
|
|
142
162
|
/**
|
|
143
163
|
* Tool-related output produced during a Responses-API turn. Covers tool
|
|
144
164
|
* discovery (`mcp_list_tools`), invocation (`mcp_call`, `function_call`,
|
|
@@ -162,6 +182,12 @@ export interface ResponseOutputTool {
|
|
|
162
182
|
call_id?: string;
|
|
163
183
|
/** Tool result payload (shape depends on the tool kind). */
|
|
164
184
|
output?: unknown;
|
|
185
|
+
/**
|
|
186
|
+
* Optional server-provided display hints (label, icon, phase). When
|
|
187
|
+
* present, `responsesToTree` forwards `text` and `icon` onto the
|
|
188
|
+
* resulting `MessageToolContent` so the UI can render them directly.
|
|
189
|
+
*/
|
|
190
|
+
display?: ResponseOutputToolDisplay;
|
|
165
191
|
[key: string]: unknown;
|
|
166
192
|
}
|
|
167
193
|
|
|
@@ -233,12 +259,7 @@ interface ResponseMessageNode {
|
|
|
233
259
|
createdAt: Date;
|
|
234
260
|
}
|
|
235
261
|
|
|
236
|
-
function extractMessageText(
|
|
237
|
-
if (typeof content === 'string') return content.trim();
|
|
238
|
-
return extractTextFromParts(content);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
function extractTextFromParts(parts: OutputContentPart[]): string {
|
|
262
|
+
function extractMessageText(parts: ResponseOutputTextPart[]): string {
|
|
242
263
|
let text = '';
|
|
243
264
|
for (const part of parts) {
|
|
244
265
|
if (part.type === 'output_text' || part.type === 'text') {
|
|
@@ -248,10 +269,10 @@ function extractTextFromParts(parts: OutputContentPart[]): string {
|
|
|
248
269
|
return text.trim();
|
|
249
270
|
}
|
|
250
271
|
|
|
251
|
-
function
|
|
272
|
+
function extractReasoningSummary(parts: ResponseReasoningTextPart[]): string {
|
|
252
273
|
let text = '';
|
|
253
274
|
for (const part of parts) {
|
|
254
|
-
if (part.type === '
|
|
275
|
+
if (part.type === 'summary_text') {
|
|
255
276
|
text += part.text ?? '';
|
|
256
277
|
}
|
|
257
278
|
}
|
|
@@ -262,6 +283,18 @@ function textPart(text: string, id?: string): MessageContent {
|
|
|
262
283
|
return { type: 'text', id: id ?? generateId(), text, status: 'completed' };
|
|
263
284
|
}
|
|
264
285
|
|
|
286
|
+
// Build a `MessageToolContent` for one tool invocation, forwarding the
|
|
287
|
+
// optional server-provided `display.text` / `display.icon` hints when
|
|
288
|
+
// present so the UI can render them directly.
|
|
289
|
+
function toolPart(out: ResponseOutputTool): MessageContent {
|
|
290
|
+
return {
|
|
291
|
+
type: 'tool',
|
|
292
|
+
id: out.id,
|
|
293
|
+
name: out.name ?? out.type,
|
|
294
|
+
...(out.display ? { text: out.display.text, icon: out.display.icon } : {}),
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
265
298
|
// Build the `content` array for one assistant turn from a Responses-API
|
|
266
299
|
// record. Reasoning trails, tool invocations, and visible text all belong to
|
|
267
300
|
// the same turn and are kept in their original wire order so the UI can
|
|
@@ -271,7 +304,7 @@ function toAssistantParts(resp: StoredResponse): MessageContent[] {
|
|
|
271
304
|
for (const out of resp.output ?? []) {
|
|
272
305
|
switch (out.type) {
|
|
273
306
|
case 'reasoning': {
|
|
274
|
-
const text =
|
|
307
|
+
const text = extractReasoningSummary(out.summary ?? []);
|
|
275
308
|
parts.push({
|
|
276
309
|
type: 'reasoning',
|
|
277
310
|
id: out.id,
|
|
@@ -293,11 +326,7 @@ function toAssistantParts(resp: StoredResponse): MessageContent[] {
|
|
|
293
326
|
case 'mcp_call':
|
|
294
327
|
case 'function_call':
|
|
295
328
|
case 'tool_call': {
|
|
296
|
-
parts.push(
|
|
297
|
-
type: 'tool',
|
|
298
|
-
id: out.id,
|
|
299
|
-
name: out.name ?? out.type,
|
|
300
|
-
});
|
|
329
|
+
parts.push(toolPart(out));
|
|
301
330
|
break;
|
|
302
331
|
}
|
|
303
332
|
default:
|
|
@@ -320,19 +349,35 @@ function getAssistantNodeId(resp: StoredResponse): string {
|
|
|
320
349
|
return `assistant-${resp.id}`;
|
|
321
350
|
}
|
|
322
351
|
|
|
323
|
-
//
|
|
324
|
-
//
|
|
325
|
-
//
|
|
326
|
-
//
|
|
327
|
-
//
|
|
352
|
+
// `request_input[].content` is wire-typed as `unknown` because user inputs
|
|
353
|
+
// can arrive as plain strings or as structured part arrays (e.g.
|
|
354
|
+
// `input_text`, `output_text`, `text`). We defensively pick up any
|
|
355
|
+
// text-bearing parts without relying on the strict output content shapes,
|
|
356
|
+
// which are reserved for `ResponseOutputMessage` / `ResponseOutputReasoning`.
|
|
328
357
|
function extractInputText(rawContent: unknown): string {
|
|
329
358
|
if (typeof rawContent === 'string') return rawContent.trim();
|
|
330
|
-
if (Array.isArray(rawContent))
|
|
331
|
-
|
|
359
|
+
if (!Array.isArray(rawContent)) return '';
|
|
360
|
+
let text = '';
|
|
361
|
+
for (const raw of rawContent) {
|
|
362
|
+
if (!raw || typeof raw !== 'object') continue;
|
|
363
|
+
const part = raw as { type?: unknown; text?: unknown };
|
|
364
|
+
if (
|
|
365
|
+
(part.type === 'input_text' ||
|
|
366
|
+
part.type === 'output_text' ||
|
|
367
|
+
part.type === 'text') &&
|
|
368
|
+
typeof part.text === 'string'
|
|
369
|
+
) {
|
|
370
|
+
text += part.text;
|
|
371
|
+
}
|
|
332
372
|
}
|
|
333
|
-
return
|
|
373
|
+
return text.trim();
|
|
334
374
|
}
|
|
335
375
|
|
|
376
|
+
// Within a single response, the visible messages chain linearly: every user
|
|
377
|
+
// input is followed by exactly one assistant turn (whose reasoning, tool,
|
|
378
|
+
// and text outputs are merged into one node). Across responses, branching
|
|
379
|
+
// is encoded by `previous_response_id` so several responses can share the
|
|
380
|
+
// same parent and form sibling subtrees.
|
|
336
381
|
function responseToMessageNodes(resp: StoredResponse): ResponseMessageNode[] {
|
|
337
382
|
const nodes: ResponseMessageNode[] = [];
|
|
338
383
|
if (resp.request_input) {
|
|
@@ -1,15 +1,4 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* history row.
|
|
4
|
-
*
|
|
5
|
-
* The `::before` pseudo-element is always mounted so CSS has something to
|
|
6
|
-
* transition. At rest it's painted from `scale-x-0` + `opacity-0` with its
|
|
7
|
-
* transform anchored on the left edge (`origin-left`); when the row's
|
|
8
|
-
* `data-active="true"` flips on, the bar paints in from left to right while
|
|
9
|
-
* fading in, using a 200ms linear curve.
|
|
10
|
-
*
|
|
11
|
-
* Kept as a string constant (rather than generated via `cn`) so UnoCSS's
|
|
12
|
-
* static scanner picks up every utility class for atomic CSS generation.
|
|
2
|
+
* Uses the shared UI library active indicator preflight class.
|
|
13
3
|
*/
|
|
14
|
-
export const CHAT_HISTORY_ACTIVE_INDICATOR_CLASS =
|
|
15
|
-
'before:absolute before:z-10 before:top-1/2 before:left-0 before:h-1/2 before:w-0.5 before:-translate-y-1/2 before:origin-left before:scale-x-0 before:rounded-full before:bg-background-accent-default before:opacity-0 before:transition-[transform,opacity] before:duration-200 before:ease-linear before:content-[""] data-[active=true]:before:scale-x-100 data-[active=true]:before:opacity-100';
|
|
4
|
+
export const CHAT_HISTORY_ACTIVE_INDICATOR_CLASS = 'ui-active-indicator';
|
package/src/types.ts
CHANGED
|
@@ -29,20 +29,29 @@ export interface MessageTextContent {
|
|
|
29
29
|
* Tool invocation triggered by the assistant during its turn. Only the tool
|
|
30
30
|
* name is rendered; arguments and results are intentionally outside the
|
|
31
31
|
* UI-facing model and should be tracked by the host application.
|
|
32
|
+
*
|
|
33
|
+
* `text` and `icon` are optional server-provided display hints (sourced from
|
|
34
|
+
* a `display` block on the wire payload, e.g.
|
|
35
|
+
* `ResponseOutputTool.display`). When present, the UI is expected to render
|
|
36
|
+
* the human-readable `text` and the lucide.dev `icon` instead of falling
|
|
37
|
+
* back to the raw tool `name`.
|
|
32
38
|
*/
|
|
33
39
|
export interface MessageToolContent {
|
|
34
40
|
type: 'tool';
|
|
35
41
|
id: string;
|
|
36
42
|
name: string;
|
|
43
|
+
text?: string;
|
|
44
|
+
icon?: string;
|
|
37
45
|
}
|
|
38
46
|
|
|
39
47
|
/**
|
|
40
48
|
* Chain-of-thought / reasoning segment produced by the assistant. `text` is
|
|
41
49
|
* the (optional) human-readable trail — populated when the underlying
|
|
42
50
|
* transport exposes reasoning content (`REASONING_MESSAGE_CONTENT` deltas
|
|
43
|
-
* during a live run, `
|
|
44
|
-
*
|
|
45
|
-
*
|
|
51
|
+
* during a live run, `summary_text` parts under
|
|
52
|
+
* `ResponseOutputReasoning.summary` when re-hydrating from the Responses
|
|
53
|
+
* API). Surfaces that only need a "Thinking…" / "Thought" indicator can
|
|
54
|
+
* ignore it and rely on `status` alone.
|
|
46
55
|
*/
|
|
47
56
|
export interface MessageReasoningContent {
|
|
48
57
|
type: 'reasoning';
|