@aleph-alpha/chat-kit 1.11.1 → 1.12.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/dist/adapters/responses-api.d.ts +54 -5
- package/dist/adapters/responses-api.d.ts.map +1 -1
- package/dist/adapters/responses-api.js +43 -9
- package/dist/composables/index.js +1 -1
- package/dist/handlers/index.js +1 -1
- package/dist/handlers/useMessageHandler.d.ts +6 -2
- package/dist/handlers/useMessageHandler.d.ts.map +1 -1
- package/dist/helpers/conversationTree.d.ts +10 -1
- package/dist/helpers/conversationTree.d.ts.map +1 -1
- package/dist/{index-BLq6_Lt2.js → index-Ct5hD214.js} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/{useMessageHandler-ZRC-gIOJ.js → useMessageHandler-CMdy-lm0.js} +36 -9
- package/package.json +1 -1
- package/src/adapters/responses-api.spec.ts +70 -0
- package/src/adapters/responses-api.ts +123 -12
- package/src/handlers/useMessageHandler.spec.ts +214 -0
- package/src/handlers/useMessageHandler.ts +28 -3
- package/src/helpers/conversationTree.spec.ts +134 -0
- package/src/helpers/conversationTree.ts +32 -1
- package/src/index.ts +1 -0
- package/src/types.ts +15 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ConversationTree } from '../types';
|
|
1
|
+
import type { ConversationTree, MessageMetadata, TreeMessage } from '../types';
|
|
2
2
|
/**
|
|
3
3
|
* Annotation attached to a Responses-API content part (citations, file
|
|
4
4
|
* references, etc.). chat-kit does not render annotations itself; the shape
|
|
@@ -157,6 +157,21 @@ export interface ResponseAttachment {
|
|
|
157
157
|
fileName: string;
|
|
158
158
|
searchStoreId: string;
|
|
159
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Render-side attachment shape produced by `responsesToTree`. Stored under
|
|
162
|
+
* `metadata.attachments` on the user `TreeMessage` (chat-kit's `BaseMessage`
|
|
163
|
+
* /`TreeMessage` carry `metadata` as an opaque `Record<string, unknown>`).
|
|
164
|
+
*
|
|
165
|
+
* The shape is intentionally minimal — a human-readable `name` plus the
|
|
166
|
+
* optional ids needed to resolve a public URL for the file. Consumers
|
|
167
|
+
* using a different attachment shape can either skip this adapter or
|
|
168
|
+
* project this onto their own type at the read site.
|
|
169
|
+
*/
|
|
170
|
+
export interface ResponseMessageAttachment {
|
|
171
|
+
name: string;
|
|
172
|
+
fileId?: string;
|
|
173
|
+
searchStoreId?: string;
|
|
174
|
+
}
|
|
160
175
|
/**
|
|
161
176
|
* One stored response from the OpenAI-style Responses API, as returned by
|
|
162
177
|
* `GET /conversations/:id/responses`. `previous_response_id` chains
|
|
@@ -174,7 +189,7 @@ export interface StoredResponse {
|
|
|
174
189
|
output: ResponseOutput[];
|
|
175
190
|
request_input: Record<string, unknown>[];
|
|
176
191
|
metadata?: Record<string, unknown> & {
|
|
177
|
-
attachments?:
|
|
192
|
+
attachments?: string;
|
|
178
193
|
};
|
|
179
194
|
conversation?: {
|
|
180
195
|
id: string;
|
|
@@ -192,6 +207,38 @@ export interface ResponseList {
|
|
|
192
207
|
object: 'list';
|
|
193
208
|
data: StoredResponse[];
|
|
194
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Per-node metadata produced by `responsesToTree`. The adapter is the
|
|
212
|
+
* single point that knows about the Responses-API wire format, so it
|
|
213
|
+
* stamps the originating `responseId` onto every node it emits. Anything
|
|
214
|
+
* downstream that reads it (typically a host app linking a tree message
|
|
215
|
+
* back to its server-side response) does so via this narrower metadata
|
|
216
|
+
* shape — chat-kit core stays oblivious to the field and treats it as
|
|
217
|
+
* opaque metadata.
|
|
218
|
+
*/
|
|
219
|
+
export type ResponseTreeMessageMetadata = MessageMetadata & {
|
|
220
|
+
responseId: string;
|
|
221
|
+
attachments?: ResponseMessageAttachment[];
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* Tree node emitted by `responsesToTree`. Structurally a `TreeMessage`,
|
|
225
|
+
* but with `metadata` narrowed to {@link ResponseTreeMessageMetadata} and
|
|
226
|
+
* promoted from optional to required: every node carries at least the
|
|
227
|
+
* originating `responseId`. Assignable to `TreeMessage` so the resulting
|
|
228
|
+
* tree can be passed directly to `useMessageHandler().setTree(...)`.
|
|
229
|
+
*/
|
|
230
|
+
export type ResponseTreeMessage = Omit<TreeMessage, 'metadata'> & {
|
|
231
|
+
metadata: ResponseTreeMessageMetadata;
|
|
232
|
+
};
|
|
233
|
+
/**
|
|
234
|
+
* `ConversationTree` returned by `responsesToTree`. Same shape as the
|
|
235
|
+
* core `ConversationTree`, with every node typed as a
|
|
236
|
+
* {@link ResponseTreeMessage} so callers can read `metadata.responseId`
|
|
237
|
+
* without re-narrowing. Structurally assignable to `ConversationTree`.
|
|
238
|
+
*/
|
|
239
|
+
export interface ResponseConversationTree extends ConversationTree {
|
|
240
|
+
nodes: Record<string, ResponseTreeMessage>;
|
|
241
|
+
}
|
|
195
242
|
/**
|
|
196
243
|
* Convert an OpenAI Responses API list (already ordered by `created_at`
|
|
197
244
|
* ascending) into a chat-kit `ConversationTree`.
|
|
@@ -202,8 +249,10 @@ export interface ResponseList {
|
|
|
202
249
|
* last message immediately. Sibling responses (same `previous_response_id`)
|
|
203
250
|
* surface as branches; the latest one wins as the active branch.
|
|
204
251
|
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
252
|
+
* Every emitted node carries `metadata.responseId` pointing back to the
|
|
253
|
+
* originating `StoredResponse.id` (see {@link ResponseTreeMessage}). The
|
|
254
|
+
* return type is assignable to `ConversationTree`, so you can pipe it
|
|
255
|
+
* straight into `useMessageHandler().setTree(...)`.
|
|
207
256
|
*/
|
|
208
|
-
export declare function responsesToTree(responses: StoredResponse[]):
|
|
257
|
+
export declare function responsesToTree(responses: StoredResponse[]): ResponseConversationTree;
|
|
209
258
|
//# sourceMappingURL=responses-api.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"responses-api.d.ts","sourceRoot":"","sources":["../../src/adapters/responses-api.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EACV,gBAAgB,
|
|
1
|
+
{"version":3,"file":"responses-api.d.ts","sourceRoot":"","sources":["../../src/adapters/responses-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -83,21 +83,53 @@ function extractInputText(rawContent) {
|
|
|
83
83
|
}
|
|
84
84
|
return text.trim();
|
|
85
85
|
}
|
|
86
|
+
function parseResponseAttachments(resp) {
|
|
87
|
+
const raw = resp.metadata?.attachments;
|
|
88
|
+
if (!raw) return null;
|
|
89
|
+
let attachments;
|
|
90
|
+
try {
|
|
91
|
+
attachments = JSON.parse(raw);
|
|
92
|
+
} catch {
|
|
93
|
+
console.warn(
|
|
94
|
+
"[chat-kit] Failed to parse metadata.attachments as JSON; skipping.",
|
|
95
|
+
raw
|
|
96
|
+
);
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
if (!Array.isArray(attachments) || attachments.length === 0) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
return attachments;
|
|
103
|
+
}
|
|
86
104
|
function responseToMessageNodes(resp) {
|
|
87
105
|
const nodes = [];
|
|
106
|
+
const responseAttachments = parseResponseAttachments(resp);
|
|
107
|
+
let userNodesPushed = 0;
|
|
88
108
|
if (resp.request_input) {
|
|
89
109
|
for (const [idx, input] of resp.request_input.entries()) {
|
|
90
110
|
const role = input.role;
|
|
91
111
|
const rawContent = input.content;
|
|
92
112
|
const text = extractInputText(rawContent);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
113
|
+
const userContent = text || responseAttachments?.length;
|
|
114
|
+
if (role !== "user" || !userContent) continue;
|
|
115
|
+
const metadata = { responseId: resp.id };
|
|
116
|
+
if (responseAttachments && userNodesPushed === 0) {
|
|
117
|
+
metadata.attachments = responseAttachments.map(
|
|
118
|
+
(a) => ({
|
|
119
|
+
name: a.fileName,
|
|
120
|
+
fileId: a.fileId,
|
|
121
|
+
searchStoreId: a.searchStoreId
|
|
122
|
+
})
|
|
123
|
+
);
|
|
100
124
|
}
|
|
125
|
+
nodes.push({
|
|
126
|
+
id: `user-${resp.id}-${idx}`,
|
|
127
|
+
role: "user",
|
|
128
|
+
content: [textPart(text)],
|
|
129
|
+
createdAt: new Date(resp.created_at * 1e3),
|
|
130
|
+
metadata
|
|
131
|
+
});
|
|
132
|
+
userNodesPushed += 1;
|
|
101
133
|
}
|
|
102
134
|
}
|
|
103
135
|
const assistantParts = toAssistantParts(resp);
|
|
@@ -106,7 +138,8 @@ function responseToMessageNodes(resp) {
|
|
|
106
138
|
id: getAssistantNodeId(resp),
|
|
107
139
|
role: "assistant",
|
|
108
140
|
content: assistantParts,
|
|
109
|
-
createdAt: new Date((resp.completed_at ?? resp.created_at) * 1e3)
|
|
141
|
+
createdAt: new Date((resp.completed_at ?? resp.created_at) * 1e3),
|
|
142
|
+
metadata: { responseId: resp.id }
|
|
110
143
|
});
|
|
111
144
|
}
|
|
112
145
|
return nodes;
|
|
@@ -127,7 +160,8 @@ function responsesToTree(responses) {
|
|
|
127
160
|
role: node.role,
|
|
128
161
|
content: node.content,
|
|
129
162
|
status: "completed",
|
|
130
|
-
createdAt: node.createdAt
|
|
163
|
+
createdAt: node.createdAt,
|
|
164
|
+
metadata: node.metadata
|
|
131
165
|
};
|
|
132
166
|
if (parentId !== null) {
|
|
133
167
|
const parent = treeNodes[parentId];
|
package/dist/handlers/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BaseMessage, ConversationTree, MessageContent, MessageRole, MessageStatus } from '../types';
|
|
1
|
+
import type { BaseMessage, ConversationTree, MessageContent, MessageMetadata, MessageRole, MessageStatus } from '../types';
|
|
2
2
|
import { type Ref } from 'vue';
|
|
3
3
|
export declare const useMessageHandler: () => {
|
|
4
4
|
messages: Ref<BaseMessage[]>;
|
|
@@ -9,14 +9,18 @@ export declare const useMessageHandler: () => {
|
|
|
9
9
|
content: MessageContent[];
|
|
10
10
|
role: MessageRole;
|
|
11
11
|
status: MessageStatus;
|
|
12
|
+
metadata?: MessageMetadata;
|
|
12
13
|
}) => void;
|
|
13
14
|
setCurrentUserMessage: (text: string) => void;
|
|
14
15
|
getMessageById: (id: string) => BaseMessage | undefined;
|
|
15
16
|
clearCurrentUserMessage: () => void;
|
|
16
|
-
commitUserMessage: (
|
|
17
|
+
commitUserMessage: (opts?: {
|
|
18
|
+
metadata?: MessageMetadata;
|
|
19
|
+
}) => BaseMessage;
|
|
17
20
|
updateMessageId: (oldId: string, newId: string) => void;
|
|
18
21
|
clearMessages: () => void;
|
|
19
22
|
setTree: (incoming: ConversationTree) => void;
|
|
20
23
|
navigate: (targetId: string) => void;
|
|
24
|
+
cutBranchAfter: (messageId: string) => void;
|
|
21
25
|
};
|
|
22
26
|
//# sourceMappingURL=useMessageHandler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMessageHandler.d.ts","sourceRoot":"","sources":["../../src/handlers/useMessageHandler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useMessageHandler.d.ts","sourceRoot":"","sources":["../../src/handlers/useMessageHandler.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,WAAW,EACX,aAAa,EAEd,MAAM,UAAU,CAAC;AAClB,OAAO,EAAqC,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AAElE,eAAO,MAAM,iBAAiB;cA6IJ,GAAG,CAAC,WAAW,EAAE,CAAC;;;6BArFV;QAC9B,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,cAAc,EAAE,CAAC;QAC1B,IAAI,EAAE,WAAW,CAAC;QAClB,MAAM,EAAE,aAAa,CAAC;QACtB,QAAQ,CAAC,EAAE,eAAe,CAAC;KAC5B;kCAnDoC,MAAM;yBAiFf,MAAM,KAAG,WAAW,GAAG,SAAS;;+BAzE1B;QAChC,QAAQ,CAAC,EAAE,eAAe,CAAC;KAC5B,KAAG,WAAW;6BAqFiB,MAAM,SAAS,MAAM;;wBAiB1B,gBAAgB;yBAKf,MAAM;gCAQC,MAAM;CAmB1C,CAAC"}
|
|
@@ -6,8 +6,17 @@ export declare function createEmptyTree(): ConversationTree;
|
|
|
6
6
|
*/
|
|
7
7
|
export declare function getLinearPath(tree: ConversationTree): BaseMessage[];
|
|
8
8
|
export declare function addNode(tree: ConversationTree, node: TreeMessage): void;
|
|
9
|
-
export declare function updateNode(tree: ConversationTree, id: string, updates: Partial<Pick<TreeMessage, 'content' | 'status' | 'role'>>): void;
|
|
9
|
+
export declare function updateNode(tree: ConversationTree, id: string, updates: Partial<Pick<TreeMessage, 'content' | 'status' | 'role' | 'metadata'>>): void;
|
|
10
10
|
export declare function updateNodeId(tree: ConversationTree, oldId: string, newId: string): void;
|
|
11
|
+
/**
|
|
12
|
+
* Remove every descendant of the node with the given id, keeping the node
|
|
13
|
+
* itself intact. The node's `childrenIds` is cleared and `activeChildIndex`
|
|
14
|
+
* is reset to 0, which makes the node the new leaf of its branch.
|
|
15
|
+
*
|
|
16
|
+
* Useful when editing a message and discarding the conversation that was
|
|
17
|
+
* generated after it.
|
|
18
|
+
*/
|
|
19
|
+
export declare function cutBranchAfter(tree: ConversationTree, id: string): void;
|
|
11
20
|
/**
|
|
12
21
|
* Navigate to a different branch by updating the parent's activeChildIndex
|
|
13
22
|
* to point at the target sibling.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conversationTree.d.ts","sourceRoot":"","sources":["../../src/helpers/conversationTree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE3E,wBAAgB,eAAe,IAAI,gBAAgB,CAElD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,gBAAgB,GAAG,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"conversationTree.d.ts","sourceRoot":"","sources":["../../src/helpers/conversationTree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE3E,wBAAgB,eAAe,IAAI,gBAAgB,CAElD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,gBAAgB,GAAG,WAAW,EAAE,CAmCnE;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAYvE;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,gBAAgB,EACtB,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,OAAO,CACd,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC,CAC9D,GACA,IAAI,CAUN;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,gBAAgB,EACtB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,IAAI,CAsBN;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI,CAevE;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAWvE"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { g as generateId } from "./generateId-BHf0W4Rq.js";
|
|
2
2
|
import { ref, shallowRef, computed, readonly, toRaw, toValue, watch } from "vue";
|
|
3
|
-
import { u as useMessageHandler } from "./useMessageHandler-
|
|
3
|
+
import { u as useMessageHandler } from "./useMessageHandler-CMdy-lm0.js";
|
|
4
4
|
import "./purify.es-md74IFlY.js";
|
|
5
5
|
function secondsToDate(seconds) {
|
|
6
6
|
return new Date(seconds * 1e3);
|
package/dist/index.d.ts
CHANGED
|
@@ -7,5 +7,5 @@ export { SdkError, createDocumentUploadProvider, defaultDocumentUploadConfig, de
|
|
|
7
7
|
export type { DocumentUploadConfig, DocumentUploadProvider, FileEntry, FileStatus, } from './composables/fileUpload';
|
|
8
8
|
export { CkAgentMessage, CkConversation, CkConversationLayout, CkCopyMessageActionButton, CkFeedbackButton, CkFileItemsList, CkHistory, CkHistoryItem, CkHistoryWrapper, CkInput, CkMarkdownRenderer, CkMessageActionButton, CkPromptActionButton, CkPromptStopButton, CkPromptInput, CkPromptInputDisclaimer, CkSendIcon, CkStopIcon, CkUserMessage, } from './components';
|
|
9
9
|
export type { CkConversationLayoutProps, CkConversationProps, CkFeedbackButtonProps, CkFeedbackValue, CkFileEntry, CkFileItemsListEmits, CkFileItemsListProps, CkHistoryEmits, CkHistoryItemEmits, CkHistoryItemProps, CkHistoryProps, CkHistoryWrapperProps, CkMarkdownElementClasses, CkMarkdownRendererProps, CkUserMessageProps, } from './components';
|
|
10
|
-
export type { BaseMessage, Conversation, ConversationTree, MessageContent, MessageContentStatus, MessageReasoningContent, MessageRole, MessageStatus, MessageTextContent, MessageToolContent, TreeMessage, } from './types';
|
|
10
|
+
export type { BaseMessage, Conversation, ConversationTree, MessageContent, MessageContentStatus, MessageMetadata, MessageReasoningContent, MessageRole, MessageStatus, MessageTextContent, MessageToolContent, TreeMessage, } from './types';
|
|
11
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AASpB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,OAAO,EACL,OAAO,EACP,uBAAuB,EACvB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,aAAa,EACb,6BAA6B,EAC7B,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,QAAQ,EACR,4BAA4B,EAC5B,2BAA2B,EAC3B,gBAAgB,EAChB,kCAAkC,GACnC,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,oBAAoB,EACpB,sBAAsB,EACtB,SAAS,EACT,UAAU,GACX,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EACL,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,yBAAyB,EACzB,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,OAAO,EACP,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,uBAAuB,EACvB,UAAU,EACV,UAAU,EACV,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,yBAAyB,EACzB,mBAAmB,EACnB,qBAAqB,EACrB,eAAe,EACf,WAAW,EACX,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAGtB,YAAY,EACV,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,uBAAuB,EACvB,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,GACZ,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AASpB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,GAChB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,OAAO,EACL,OAAO,EACP,uBAAuB,EACvB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,uBAAuB,EACvB,cAAc,EACd,eAAe,EACf,aAAa,EACb,6BAA6B,EAC7B,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,QAAQ,EACR,4BAA4B,EAC5B,2BAA2B,EAC3B,gBAAgB,EAChB,kCAAkC,GACnC,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,oBAAoB,EACpB,sBAAsB,EACtB,SAAS,EACT,UAAU,GACX,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EACL,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,yBAAyB,EACzB,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,OAAO,EACP,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,uBAAuB,EACvB,UAAU,EACV,UAAU,EACV,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,yBAAyB,EACzB,mBAAmB,EACnB,qBAAqB,EACrB,eAAe,EACf,WAAW,EACX,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAGtB,YAAY,EACV,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,uBAAuB,EACvB,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,kBAAkB,EAClB,WAAW,GACZ,MAAM,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { u } from "./useMessageHandler-
|
|
1
|
+
import { u } from "./useMessageHandler-CMdy-lm0.js";
|
|
2
2
|
import { C, d, p, u as u2, a } from "./useChatKitLabels-ftC52m7f.js";
|
|
3
|
-
import { S, c, d as d2, a as a2, u as u3, b, e, f } from "./index-
|
|
3
|
+
import { S, c, d as d2, a as a2, u as u3, b, e, f } from "./index-Ct5hD214.js";
|
|
4
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, q } from "./CkInput.vue_vue_type_script_setup_true_lang-C1Jnn1fK.js";
|
|
5
5
|
export {
|
|
6
6
|
C as CHAT_KIT_LABELS,
|
package/dist/types.d.ts
CHANGED
|
@@ -57,6 +57,18 @@ export interface MessageReasoningContent {
|
|
|
57
57
|
* Discriminated union of all content parts that can appear inside a message.
|
|
58
58
|
*/
|
|
59
59
|
export type MessageContent = MessageTextContent | MessageToolContent | MessageReasoningContent;
|
|
60
|
+
/**
|
|
61
|
+
* Open-ended metadata bag carried alongside a message. chat-kit is
|
|
62
|
+
* intentionally agnostic about its contents — adapter authors
|
|
63
|
+
* (`responsesToTree`, …) and message handlers preserve the value verbatim
|
|
64
|
+
* through the tree → linear path projection, but never inspect it.
|
|
65
|
+
*
|
|
66
|
+
* Consumers attach their own well-known keys (attachments, citations,
|
|
67
|
+
* ratings, …) and define their own typed projections at the read site
|
|
68
|
+
* rather than extending this base type. That keeps the handler API stable
|
|
69
|
+
* even as the shape of what gets stored on a message evolves.
|
|
70
|
+
*/
|
|
71
|
+
export type MessageMetadata = Record<string, unknown>;
|
|
60
72
|
export interface BaseMessage {
|
|
61
73
|
id: string;
|
|
62
74
|
role: MessageRole;
|
|
@@ -65,6 +77,7 @@ export interface BaseMessage {
|
|
|
65
77
|
status: MessageStatus;
|
|
66
78
|
siblingIds?: string[];
|
|
67
79
|
siblingIndex?: number;
|
|
80
|
+
metadata?: MessageMetadata;
|
|
68
81
|
}
|
|
69
82
|
export interface TreeMessage {
|
|
70
83
|
id: string;
|
|
@@ -75,6 +88,7 @@ export interface TreeMessage {
|
|
|
75
88
|
content: MessageContent[];
|
|
76
89
|
status: MessageStatus;
|
|
77
90
|
createdAt: Date;
|
|
91
|
+
metadata?: MessageMetadata;
|
|
78
92
|
}
|
|
79
93
|
export interface ConversationTree {
|
|
80
94
|
nodes: Record<string, TreeMessage>;
|
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;;;;;;;;;;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;
|
|
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;;;;;;;;;;GAUG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEtD,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;IACtB,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;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;IAChB,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;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"}
|
|
@@ -16,7 +16,8 @@ function getLinearPath(tree) {
|
|
|
16
16
|
role: node.role,
|
|
17
17
|
content: node.content,
|
|
18
18
|
createdAt: node.createdAt,
|
|
19
|
-
status: node.status
|
|
19
|
+
status: node.status,
|
|
20
|
+
...node.metadata !== void 0 ? { metadata: node.metadata } : {}
|
|
20
21
|
};
|
|
21
22
|
if (node.parentId !== null) {
|
|
22
23
|
const parent = nodes[node.parentId];
|
|
@@ -49,6 +50,7 @@ function updateNode(tree, id, updates) {
|
|
|
49
50
|
if (updates.content !== void 0) node.content = updates.content;
|
|
50
51
|
if (updates.status !== void 0) node.status = updates.status;
|
|
51
52
|
if (updates.role !== void 0) node.role = updates.role;
|
|
53
|
+
if ("metadata" in updates) node.metadata = updates.metadata;
|
|
52
54
|
}
|
|
53
55
|
function updateNodeId(tree, oldId, newId) {
|
|
54
56
|
const node = tree.nodes[oldId];
|
|
@@ -69,6 +71,20 @@ function updateNodeId(tree, oldId, newId) {
|
|
|
69
71
|
}
|
|
70
72
|
if (tree.rootId === oldId) tree.rootId = newId;
|
|
71
73
|
}
|
|
74
|
+
function cutBranchAfter(tree, id) {
|
|
75
|
+
const node = tree.nodes[id];
|
|
76
|
+
if (!node) return;
|
|
77
|
+
const stack = [...node.childrenIds];
|
|
78
|
+
while (stack.length > 0) {
|
|
79
|
+
const currentId = stack.pop();
|
|
80
|
+
const current = tree.nodes[currentId];
|
|
81
|
+
if (!current) continue;
|
|
82
|
+
stack.push(...current.childrenIds);
|
|
83
|
+
delete tree.nodes[currentId];
|
|
84
|
+
}
|
|
85
|
+
node.childrenIds = [];
|
|
86
|
+
node.activeChildIndex = 0;
|
|
87
|
+
}
|
|
72
88
|
function navigate(tree, targetId) {
|
|
73
89
|
const node = tree.nodes[targetId];
|
|
74
90
|
if (!node || node.parentId === null) return;
|
|
@@ -92,7 +108,7 @@ const useMessageHandler = () => {
|
|
|
92
108
|
function clearCurrentUserMessage() {
|
|
93
109
|
currentUserMessage.value = "";
|
|
94
110
|
}
|
|
95
|
-
function commitUserMessage() {
|
|
111
|
+
function commitUserMessage(opts) {
|
|
96
112
|
const id = generateId();
|
|
97
113
|
const text = currentUserMessage.value.trim();
|
|
98
114
|
if (!text) throw new Error("No message");
|
|
@@ -107,17 +123,20 @@ const useMessageHandler = () => {
|
|
|
107
123
|
role: "user",
|
|
108
124
|
content,
|
|
109
125
|
status: "completed",
|
|
110
|
-
createdAt: /* @__PURE__ */ new Date()
|
|
126
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
127
|
+
...opts?.metadata !== void 0 ? { metadata: opts.metadata } : {}
|
|
111
128
|
};
|
|
112
129
|
addNode(tree, node);
|
|
113
130
|
clearCurrentUserMessage();
|
|
114
|
-
|
|
131
|
+
const base = {
|
|
115
132
|
id: node.id,
|
|
116
133
|
role: node.role,
|
|
117
134
|
content: node.content,
|
|
118
135
|
createdAt: node.createdAt,
|
|
119
136
|
status: node.status
|
|
120
137
|
};
|
|
138
|
+
if (node.metadata !== void 0) base.metadata = node.metadata;
|
|
139
|
+
return base;
|
|
121
140
|
}
|
|
122
141
|
function updateMessage(message) {
|
|
123
142
|
const existing = tree.nodes[message.id];
|
|
@@ -125,7 +144,8 @@ const useMessageHandler = () => {
|
|
|
125
144
|
updateNode(tree, message.id, {
|
|
126
145
|
content: message.content,
|
|
127
146
|
role: message.role,
|
|
128
|
-
status: message.status
|
|
147
|
+
status: message.status,
|
|
148
|
+
...message.metadata !== void 0 ? { metadata: message.metadata } : {}
|
|
129
149
|
});
|
|
130
150
|
} else {
|
|
131
151
|
const node = {
|
|
@@ -136,7 +156,8 @@ const useMessageHandler = () => {
|
|
|
136
156
|
role: message.role,
|
|
137
157
|
content: message.content,
|
|
138
158
|
status: message.status,
|
|
139
|
-
createdAt: /* @__PURE__ */ new Date()
|
|
159
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
160
|
+
...message.metadata !== void 0 ? { metadata: message.metadata } : {}
|
|
140
161
|
};
|
|
141
162
|
addNode(tree, node);
|
|
142
163
|
}
|
|
@@ -144,13 +165,15 @@ const useMessageHandler = () => {
|
|
|
144
165
|
function getMessageById(id) {
|
|
145
166
|
const node = tree.nodes[id];
|
|
146
167
|
if (!node) return void 0;
|
|
147
|
-
|
|
168
|
+
const base = {
|
|
148
169
|
id: node.id,
|
|
149
170
|
role: node.role,
|
|
150
171
|
content: node.content,
|
|
151
172
|
createdAt: node.createdAt,
|
|
152
|
-
status: node.status
|
|
173
|
+
status: node.status,
|
|
174
|
+
...node.metadata !== void 0 ? { metadata: node.metadata } : {}
|
|
153
175
|
};
|
|
176
|
+
return base;
|
|
154
177
|
}
|
|
155
178
|
function updateMessageId(oldId, newId) {
|
|
156
179
|
updateNodeId(tree, oldId, newId);
|
|
@@ -165,6 +188,9 @@ const useMessageHandler = () => {
|
|
|
165
188
|
function navigate$1(targetId) {
|
|
166
189
|
navigate(tree, targetId);
|
|
167
190
|
}
|
|
191
|
+
function cutBranchAfter$1(messageId) {
|
|
192
|
+
cutBranchAfter(tree, messageId);
|
|
193
|
+
}
|
|
168
194
|
return {
|
|
169
195
|
messages,
|
|
170
196
|
currentUserMessage: readonly(currentUserMessage),
|
|
@@ -177,7 +203,8 @@ const useMessageHandler = () => {
|
|
|
177
203
|
updateMessageId,
|
|
178
204
|
clearMessages,
|
|
179
205
|
setTree,
|
|
180
|
-
navigate: navigate$1
|
|
206
|
+
navigate: navigate$1,
|
|
207
|
+
cutBranchAfter: cutBranchAfter$1
|
|
181
208
|
};
|
|
182
209
|
};
|
|
183
210
|
export {
|
package/package.json
CHANGED
|
@@ -371,6 +371,76 @@ describe('responsesToTree', () => {
|
|
|
371
371
|
}
|
|
372
372
|
});
|
|
373
373
|
|
|
374
|
+
it('stamps the originating responseId onto every emitted node', () => {
|
|
375
|
+
const tree = responsesToTree([
|
|
376
|
+
makeResponse({
|
|
377
|
+
id: 'r1',
|
|
378
|
+
request_input: [userInput('Hello')],
|
|
379
|
+
output: [assistantOutput('msg-a1', 'Hi')],
|
|
380
|
+
}),
|
|
381
|
+
makeResponse({
|
|
382
|
+
id: 'r2',
|
|
383
|
+
previous_response_id: 'r1',
|
|
384
|
+
request_input: [userInput('Follow-up')],
|
|
385
|
+
output: [assistantOutput('msg-a2', 'Reply')],
|
|
386
|
+
}),
|
|
387
|
+
]);
|
|
388
|
+
|
|
389
|
+
expect(tree.nodes['user-r1-0']!.metadata.responseId).toBe('r1');
|
|
390
|
+
expect(tree.nodes['msg-a1']!.metadata.responseId).toBe('r1');
|
|
391
|
+
expect(tree.nodes['user-r2-0']!.metadata.responseId).toBe('r2');
|
|
392
|
+
expect(tree.nodes['msg-a2']!.metadata.responseId).toBe('r2');
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
it('parses metadata.attachments (JSON-encoded string) onto the first user node of a response', () => {
|
|
396
|
+
const tree = responsesToTree([
|
|
397
|
+
makeResponse({
|
|
398
|
+
id: 'r1',
|
|
399
|
+
request_input: [userInput('With files')],
|
|
400
|
+
output: [assistantOutput('msg-a1', 'OK')],
|
|
401
|
+
// The Responses API serialises attachments as a JSON-encoded
|
|
402
|
+
// string on the wire (transports flatten nested metadata).
|
|
403
|
+
metadata: {
|
|
404
|
+
attachments: JSON.stringify([
|
|
405
|
+
{ fileName: 'report.pdf', fileId: 'f1', searchStoreId: 's1' },
|
|
406
|
+
]),
|
|
407
|
+
},
|
|
408
|
+
}),
|
|
409
|
+
]);
|
|
410
|
+
|
|
411
|
+
expect(tree.nodes['user-r1-0']!.metadata).toEqual({
|
|
412
|
+
responseId: 'r1',
|
|
413
|
+
attachments: [{ name: 'report.pdf', fileId: 'f1', searchStoreId: 's1' }],
|
|
414
|
+
});
|
|
415
|
+
// The assistant turn does not inherit attachments but still carries
|
|
416
|
+
// its responseId stamp.
|
|
417
|
+
expect(tree.nodes['msg-a1']!.metadata).toEqual({ responseId: 'r1' });
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
it('skips malformed metadata.attachments without polluting the tree', () => {
|
|
421
|
+
const warn = vi.spyOn(console, 'warn').mockImplementation(() => undefined);
|
|
422
|
+
try {
|
|
423
|
+
const tree = responsesToTree([
|
|
424
|
+
makeResponse({
|
|
425
|
+
id: 'r1',
|
|
426
|
+
request_input: [userInput('Hello')],
|
|
427
|
+
output: [assistantOutput('msg-a1', 'Hi')],
|
|
428
|
+
metadata: {
|
|
429
|
+
attachments: '{not json',
|
|
430
|
+
},
|
|
431
|
+
}),
|
|
432
|
+
]);
|
|
433
|
+
|
|
434
|
+
// The malformed attachments are dropped, but `responseId` is still
|
|
435
|
+
// stamped on every node the adapter emits.
|
|
436
|
+
expect(tree.nodes['user-r1-0']!.metadata).toEqual({ responseId: 'r1' });
|
|
437
|
+
expect(tree.nodes['user-r1-0']!.metadata.attachments).toBeUndefined();
|
|
438
|
+
expect(warn).toHaveBeenCalled();
|
|
439
|
+
} finally {
|
|
440
|
+
warn.mockRestore();
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
|
|
374
444
|
it('chains the next response under a reasoning-only assistant turn', () => {
|
|
375
445
|
const tree = responsesToTree([
|
|
376
446
|
makeResponse({
|