@pgege/kaboo-react 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +3 -3
- package/CHANGELOG.md +36 -3
- package/README.md +58 -0
- package/dist/{chunk-RXZWOBSI.js → chunk-4TDUEMK5.js} +175 -2
- package/dist/chunk-4TDUEMK5.js.map +1 -0
- package/dist/copilotkit.cjs +158 -26
- package/dist/copilotkit.cjs.map +1 -1
- package/dist/copilotkit.d.cts +17 -2
- package/dist/copilotkit.d.ts +17 -2
- package/dist/copilotkit.js +118 -7
- package/dist/copilotkit.js.map +1 -1
- package/dist/index.cjs +1110 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +324 -4
- package/dist/index.d.ts +324 -4
- package/dist/index.js +951 -30
- package/dist/index.js.map +1 -1
- package/dist/styles.css +319 -0
- package/llms-full.txt +93 -5
- package/package.json +1 -1
- package/dist/chunk-RXZWOBSI.js.map +0 -1
package/dist/copilotkit.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { CopilotChatAssistantMessageProps, CopilotChatMessageViewProps } from '@copilotkit/react-core/v2';
|
|
2
|
+
import { CopilotChatAssistantMessageProps, CopilotChatMessageViewProps, CopilotChatUserMessageProps } from '@copilotkit/react-core/v2';
|
|
3
3
|
export { K as KabooInterruptHandler, a as KabooInterruptHandlerProps } from './KabooInterruptHandler-BO2Uv3gS.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -81,6 +81,21 @@ declare const KabooMessageView: typeof KabooMessageViewImpl & {
|
|
|
81
81
|
Cursor: ({ className, ...props }: react.HTMLAttributes<HTMLDivElement>) => react.JSX.Element;
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Drop-in replacement for `CopilotChatMessageView`'s `userMessage` slot that
|
|
86
|
+
* renders every reference the user sent as a **non-interactive chip**, so a
|
|
87
|
+
* reference reads as a reference rather than plain text:
|
|
88
|
+
*
|
|
89
|
+
* - object references cited inline (`@name`) render as chips *within* the text;
|
|
90
|
+
* - files and objects added via the `+` tray render as a chip row above the
|
|
91
|
+
* bubble (files show a thumbnail/icon + filename).
|
|
92
|
+
*
|
|
93
|
+
* Object references ride `state.kaboo_references` (not the message content), so
|
|
94
|
+
* they come from the per-message registry on {@link useReferences}; files come
|
|
95
|
+
* from the message's media parts.
|
|
96
|
+
*/
|
|
97
|
+
declare function KabooUserMessage(props: CopilotChatUserMessageProps): react.JSX.Element;
|
|
98
|
+
|
|
84
99
|
/**
|
|
85
100
|
* Renders answered `ask_user` prompts inline in the chat, anchored to the tool
|
|
86
101
|
* call. The tool call is a permanent part of the transcript, so the question and
|
|
@@ -108,4 +123,4 @@ declare function KabooAskUser({ agentId }: {
|
|
|
108
123
|
*/
|
|
109
124
|
declare function KabooToolRender(): null;
|
|
110
125
|
|
|
111
|
-
export { KabooAskUser, KabooAssistantMessage, KabooInlineCards, KabooMessageView, KabooToolRender };
|
|
126
|
+
export { KabooAskUser, KabooAssistantMessage, KabooInlineCards, KabooMessageView, KabooToolRender, KabooUserMessage };
|
package/dist/copilotkit.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { CopilotChatAssistantMessageProps, CopilotChatMessageViewProps } from '@copilotkit/react-core/v2';
|
|
2
|
+
import { CopilotChatAssistantMessageProps, CopilotChatMessageViewProps, CopilotChatUserMessageProps } from '@copilotkit/react-core/v2';
|
|
3
3
|
export { K as KabooInterruptHandler, a as KabooInterruptHandlerProps } from './KabooInterruptHandler-BO2Uv3gS.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -81,6 +81,21 @@ declare const KabooMessageView: typeof KabooMessageViewImpl & {
|
|
|
81
81
|
Cursor: ({ className, ...props }: react.HTMLAttributes<HTMLDivElement>) => react.JSX.Element;
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Drop-in replacement for `CopilotChatMessageView`'s `userMessage` slot that
|
|
86
|
+
* renders every reference the user sent as a **non-interactive chip**, so a
|
|
87
|
+
* reference reads as a reference rather than plain text:
|
|
88
|
+
*
|
|
89
|
+
* - object references cited inline (`@name`) render as chips *within* the text;
|
|
90
|
+
* - files and objects added via the `+` tray render as a chip row above the
|
|
91
|
+
* bubble (files show a thumbnail/icon + filename).
|
|
92
|
+
*
|
|
93
|
+
* Object references ride `state.kaboo_references` (not the message content), so
|
|
94
|
+
* they come from the per-message registry on {@link useReferences}; files come
|
|
95
|
+
* from the message's media parts.
|
|
96
|
+
*/
|
|
97
|
+
declare function KabooUserMessage(props: CopilotChatUserMessageProps): react.JSX.Element;
|
|
98
|
+
|
|
84
99
|
/**
|
|
85
100
|
* Renders answered `ask_user` prompts inline in the chat, anchored to the tool
|
|
86
101
|
* call. The tool call is a permanent part of the transcript, so the question and
|
|
@@ -108,4 +123,4 @@ declare function KabooAskUser({ agentId }: {
|
|
|
108
123
|
*/
|
|
109
124
|
declare function KabooToolRender(): null;
|
|
110
125
|
|
|
111
|
-
export { KabooAskUser, KabooAssistantMessage, KabooInlineCards, KabooMessageView, KabooToolRender };
|
|
126
|
+
export { KabooAskUser, KabooAssistantMessage, KabooInlineCards, KabooMessageView, KabooToolRender, KabooUserMessage };
|
package/dist/copilotkit.js
CHANGED
|
@@ -6,8 +6,9 @@ import {
|
|
|
6
6
|
KabooToolRender,
|
|
7
7
|
chatRootGroups,
|
|
8
8
|
groupTurnKey,
|
|
9
|
-
useActivity
|
|
10
|
-
|
|
9
|
+
useActivity,
|
|
10
|
+
useReferences
|
|
11
|
+
} from "./chunk-4TDUEMK5.js";
|
|
11
12
|
|
|
12
13
|
// src/integrations/KabooAssistantMessage.tsx
|
|
13
14
|
import {
|
|
@@ -49,18 +50,127 @@ import {
|
|
|
49
50
|
useCopilotKit,
|
|
50
51
|
useCopilotChatConfiguration
|
|
51
52
|
} from "@copilotkit/react-core/v2";
|
|
53
|
+
|
|
54
|
+
// src/integrations/KabooUserMessage.tsx
|
|
55
|
+
import {
|
|
56
|
+
CopilotChatUserMessage
|
|
57
|
+
} from "@copilotkit/react-core/v2";
|
|
52
58
|
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
59
|
+
var WRAP_CLASS = "copilotKitMessage copilotKitUserMessage cpk:flex cpk:flex-col cpk:items-end cpk:group cpk:pt-10";
|
|
60
|
+
var BUBBLE_CLASS = "cpk:prose cpk:dark:prose-invert cpk:bg-muted cpk:relative cpk:max-w-[80%] cpk:rounded-[18px] cpk:px-4 cpk:py-1.5 cpk:inline-block cpk:whitespace-pre-wrap";
|
|
61
|
+
var AtIcon = /* @__PURE__ */ jsxs2("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
62
|
+
/* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "4" }),
|
|
63
|
+
/* @__PURE__ */ jsx3("path", { d: "M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-3.92 7.94" })
|
|
64
|
+
] });
|
|
65
|
+
var FileIcon = /* @__PURE__ */ jsxs2("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
|
|
66
|
+
/* @__PURE__ */ jsx3("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
|
|
67
|
+
/* @__PURE__ */ jsx3("path", { d: "M14 2v6h6" })
|
|
68
|
+
] });
|
|
69
|
+
function messageText(content) {
|
|
70
|
+
if (typeof content === "string") return content;
|
|
71
|
+
if (!Array.isArray(content)) return "";
|
|
72
|
+
return content.map(
|
|
73
|
+
(p) => p && typeof p === "object" && p.type === "text" ? String(p.text ?? "") : ""
|
|
74
|
+
).filter(Boolean).join("\n");
|
|
75
|
+
}
|
|
76
|
+
function fileParts(content) {
|
|
77
|
+
if (!Array.isArray(content)) return [];
|
|
78
|
+
const out = [];
|
|
79
|
+
for (const part of content) {
|
|
80
|
+
const type = part?.type;
|
|
81
|
+
if (type !== "image" && type !== "audio" && type !== "video" && type !== "document") continue;
|
|
82
|
+
const source = part.source;
|
|
83
|
+
if (!source?.value) continue;
|
|
84
|
+
const src = source.type === "url" ? source.value : `data:${source.mimeType ?? ""};base64,${source.value}`;
|
|
85
|
+
const meta = part.metadata;
|
|
86
|
+
out.push({ kind: type, src, filename: meta?.filename ?? source.mimeType ?? "file" });
|
|
87
|
+
}
|
|
88
|
+
return out;
|
|
89
|
+
}
|
|
90
|
+
function ObjectChip({ reference, inline }) {
|
|
91
|
+
return /* @__PURE__ */ jsxs2(
|
|
92
|
+
"span",
|
|
93
|
+
{
|
|
94
|
+
className: `kaboo-chip kaboo-chip-object kaboo-msg-chip${inline ? " kaboo-msg-chip-inline" : ""}`,
|
|
95
|
+
title: reference.name,
|
|
96
|
+
children: [
|
|
97
|
+
/* @__PURE__ */ jsx3("span", { className: "kaboo-chip-ic", children: AtIcon }),
|
|
98
|
+
/* @__PURE__ */ jsx3("span", { className: "kaboo-chip-label", children: reference.name })
|
|
99
|
+
]
|
|
100
|
+
}
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
function FileChip({ file }) {
|
|
104
|
+
return /* @__PURE__ */ jsxs2("span", { className: "kaboo-chip kaboo-chip-attachment kaboo-msg-chip", title: file.filename, children: [
|
|
105
|
+
file.kind === "image" ? /* @__PURE__ */ jsx3("img", { className: "kaboo-chip-thumb", src: file.src, alt: file.filename }) : /* @__PURE__ */ jsx3("span", { className: "kaboo-chip-ic", children: FileIcon }),
|
|
106
|
+
/* @__PURE__ */ jsx3("span", { className: "kaboo-chip-label", children: file.filename })
|
|
107
|
+
] });
|
|
108
|
+
}
|
|
109
|
+
function renderInline(text, refs) {
|
|
110
|
+
if (refs.length === 0) return [text];
|
|
111
|
+
const tokens = refs.map((ref) => ({ ref, token: `@${ref.name}` })).sort((a, b) => b.token.length - a.token.length);
|
|
112
|
+
const out = [];
|
|
113
|
+
let i = 0;
|
|
114
|
+
let key = 0;
|
|
115
|
+
while (i < text.length) {
|
|
116
|
+
const hit = tokens.find((t) => text.startsWith(t.token, i));
|
|
117
|
+
if (hit) {
|
|
118
|
+
out.push(/* @__PURE__ */ jsx3(ObjectChip, { reference: hit.ref, inline: true }, key++));
|
|
119
|
+
i += hit.token.length;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
let next = text.length;
|
|
123
|
+
for (const t of tokens) {
|
|
124
|
+
const idx = text.indexOf(t.token, i + 1);
|
|
125
|
+
if (idx !== -1 && idx < next) next = idx;
|
|
126
|
+
}
|
|
127
|
+
out.push(text.slice(i, next));
|
|
128
|
+
i = next;
|
|
129
|
+
}
|
|
130
|
+
return out;
|
|
131
|
+
}
|
|
132
|
+
function KabooUserMessage(props) {
|
|
133
|
+
const { messageReferences } = useReferences();
|
|
134
|
+
const message = props.message;
|
|
135
|
+
const id = message?.id;
|
|
136
|
+
const objectRefs = (id ? messageReferences[id] : void 0) ?? [];
|
|
137
|
+
const text = messageText(message?.content);
|
|
138
|
+
const files = fileParts(message?.content);
|
|
139
|
+
const inlineRefs = objectRefs.filter((r) => text.includes(`@${r.name}`));
|
|
140
|
+
const trayRefs = objectRefs.filter((r) => !text.includes(`@${r.name}`));
|
|
141
|
+
const hasChipRow = files.length > 0 || trayRefs.length > 0;
|
|
142
|
+
const MessageRenderer = ({ content, className }) => /* @__PURE__ */ jsx3("div", { className: className ? `${BUBBLE_CLASS} ${className}` : BUBBLE_CLASS, children: renderInline(content, inlineRefs) });
|
|
143
|
+
return /* @__PURE__ */ jsx3(
|
|
144
|
+
CopilotChatUserMessage,
|
|
145
|
+
{
|
|
146
|
+
...props,
|
|
147
|
+
messageRenderer: MessageRenderer,
|
|
148
|
+
children: ({ messageRenderer, toolbar }) => /* @__PURE__ */ jsxs2("div", { "data-copilotkit": true, "data-message-id": id, className: `${WRAP_CLASS} kaboo-user-message`, children: [
|
|
149
|
+
hasChipRow && /* @__PURE__ */ jsxs2("div", { className: "kaboo-msg-refs", children: [
|
|
150
|
+
files.map((f, i) => /* @__PURE__ */ jsx3(FileChip, { file: f }, `f${i}`)),
|
|
151
|
+
trayRefs.map((r) => /* @__PURE__ */ jsx3(ObjectChip, { reference: r }, r.id))
|
|
152
|
+
] }),
|
|
153
|
+
messageRenderer,
|
|
154
|
+
toolbar
|
|
155
|
+
] })
|
|
156
|
+
}
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// src/integrations/KabooMessageView.tsx
|
|
161
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
53
162
|
function KabooMessageViewImpl(props) {
|
|
54
163
|
const { groups } = useActivity();
|
|
55
164
|
const { copilotkit } = useCopilotKit();
|
|
56
165
|
const config = useCopilotChatConfiguration();
|
|
57
166
|
const agentId = config?.agentId;
|
|
58
167
|
const threadId = config?.threadId;
|
|
59
|
-
return /* @__PURE__ */
|
|
168
|
+
return /* @__PURE__ */ jsx4(
|
|
60
169
|
CopilotChatMessageView,
|
|
61
170
|
{
|
|
62
171
|
...props,
|
|
63
172
|
assistantMessage: KabooAssistantMessage,
|
|
173
|
+
userMessage: KabooUserMessage,
|
|
64
174
|
children: ({ messages, messageElements, interruptElement, isRunning }) => {
|
|
65
175
|
const roots = chatRootGroups(groups);
|
|
66
176
|
const rootsByTurn = /* @__PURE__ */ new Map();
|
|
@@ -95,11 +205,11 @@ function KabooMessageViewImpl(props) {
|
|
|
95
205
|
return !key || !boundTurns.has(key);
|
|
96
206
|
});
|
|
97
207
|
const showStartCursor = isRunning && pending.length === 0;
|
|
98
|
-
return /* @__PURE__ */
|
|
208
|
+
return /* @__PURE__ */ jsxs3(TurnBindingProvider, { value: { rootsByMessageId }, children: [
|
|
99
209
|
messageElements,
|
|
100
|
-
pending.length > 0 && /* @__PURE__ */
|
|
210
|
+
pending.length > 0 && /* @__PURE__ */ jsx4("div", { className: "kaboo-inline-cards", children: pending.map(([groupId, group]) => /* @__PURE__ */ jsx4(AgentCard, { groupId, group, showChildren: true }, groupId)) }),
|
|
101
211
|
interruptElement,
|
|
102
|
-
showStartCursor && /* @__PURE__ */
|
|
212
|
+
showStartCursor && /* @__PURE__ */ jsx4(CopilotChatMessageView.Cursor, {})
|
|
103
213
|
] });
|
|
104
214
|
}
|
|
105
215
|
}
|
|
@@ -118,6 +228,7 @@ export {
|
|
|
118
228
|
KabooInlineCards,
|
|
119
229
|
KabooInterruptHandler,
|
|
120
230
|
KabooMessageView,
|
|
121
|
-
KabooToolRender
|
|
231
|
+
KabooToolRender,
|
|
232
|
+
KabooUserMessage
|
|
122
233
|
};
|
|
123
234
|
//# sourceMappingURL=copilotkit.js.map
|
package/dist/copilotkit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/integrations/KabooAssistantMessage.tsx","../src/context/TurnBinding.tsx","../src/integrations/KabooMessageView.tsx"],"sourcesContent":["import {\n CopilotChatAssistantMessage,\n type CopilotChatAssistantMessageProps,\n} from \"@copilotkit/react-core/v2\";\nimport { AgentCard } from \"../components/AgentCard\";\nimport { useTurnBinding } from \"../context/TurnBinding\";\n\n/**\n * Drop-in replacement for CopilotKit's assistant-message renderer that prepends\n * a first-class swarm/graph turn's member cards ABOVE the assistant's text —\n * inside the chat transcript, as part of the same turn.\n *\n * Wire it via the `messageView` slot of `CopilotChat`:\n *\n * ```tsx\n * <CopilotChat messageView={{ assistantMessage: KabooAssistantMessage }} />\n * ```\n *\n * This is used instead of `renderCustomMessages` because the `CopilotKit`\n * convenience provider hard-overrides that prop; the `messageView`/\n * `assistantMessage` slot is the supported customization surface and is not\n * clobbered.\n *\n * Which cards to show is decided by the turn binding (provided by\n * {@link KabooMessageView}), which resolves each reply message to its turn's\n * member cards — robust to an interrupt/resume splitting the turn across\n * multiple runIds. Delegate cards keep their tool-call path (they carry a\n * `toolCallId` and are excluded from `chatRootGroups`).\n */\nexport function KabooAssistantMessage(props: CopilotChatAssistantMessageProps) {\n const { message } = props;\n const { rootsByMessageId } = useTurnBinding();\n const messageId = (message as { id?: string })?.id;\n const mine = messageId ? rootsByMessageId.get(messageId) ?? [] : [];\n\n return (\n <>\n {mine.length > 0 && (\n <div className=\"kaboo-inline-cards\">\n {mine.map(([groupId, group]) => (\n <AgentCard key={groupId} groupId={groupId} group={group} showChildren />\n ))}\n </div>\n )}\n <CopilotChatAssistantMessage {...props} />\n </>\n );\n}\n","import { createContext, useContext, type ReactNode } from \"react\";\nimport type { GroupEntry } from \"../utils/groups\";\n\n/**\n * Binds each assistant reply message to the swarm/graph member cards its turn\n * produced, so those cards render *inside* that message (above its reply text)\n * in one chronological block — and a turn's cards never bleed onto a different\n * turn's reply.\n *\n * The mapping is by turn, not `runId`: an interrupt/resume changes the `runId`\n * mid-turn, so a reply's `runId` may only match the `chat_output` member while\n * earlier members carry the pre-resume `runId`. Both, however, share the\n * server-stamped `turnId` ({@link groupTurnKey}). {@link KabooMessageView}\n * resolves each reply message → its run → that run's `turnId`, then collects all\n * roots of that turn — so every member binds to the right reply regardless of\n * how many runs the turn spanned.\n *\n * `rootsByMessageId` holds the resolved cards per assistant message id; a turn\n * whose reply hasn't streamed yet isn't in the map — {@link KabooMessageView}\n * renders those roots live beneath the transcript instead.\n */\nexport interface TurnBinding {\n rootsByMessageId: Map<string, GroupEntry[]>;\n}\n\nconst TurnBindingContext = createContext<TurnBinding>({\n rootsByMessageId: new Map(),\n});\n\nexport function TurnBindingProvider({\n value,\n children,\n}: {\n value: TurnBinding;\n children: ReactNode;\n}) {\n return (\n <TurnBindingContext.Provider value={value}>\n {children}\n </TurnBindingContext.Provider>\n );\n}\n\nexport function useTurnBinding(): TurnBinding {\n return useContext(TurnBindingContext);\n}\n","import {\n CopilotChatMessageView,\n CopilotChatAssistantMessage,\n useCopilotKit,\n useCopilotChatConfiguration,\n type CopilotChatMessageViewProps,\n} from \"@copilotkit/react-core/v2\";\nimport { useActivity } from \"../hooks/useActivity\";\nimport { AgentCard } from \"../components/AgentCard\";\nimport { chatRootGroups, groupTurnKey, type GroupEntry } from \"../utils/groups\";\nimport { TurnBindingProvider } from \"../context/TurnBinding\";\nimport { KabooAssistantMessage } from \"./KabooAssistantMessage\";\n\nfunction KabooMessageViewImpl(props: CopilotChatMessageViewProps) {\n const { groups } = useActivity();\n const { copilotkit } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const agentId = config?.agentId;\n const threadId = config?.threadId;\n\n return (\n <CopilotChatMessageView\n {...props}\n assistantMessage={\n KabooAssistantMessage as unknown as typeof CopilotChatAssistantMessage\n }\n >\n {({ messages, messageElements, interruptElement, isRunning }) => {\n const roots = chatRootGroups(groups);\n\n // Bucket this turn's member cards by their stable turn key, and map each\n // AG-UI run to its turn key so a reply (whose run may be the post-resume\n // one) resolves to the whole turn — not just its chat_output member.\n const rootsByTurn = new Map<string, GroupEntry[]>();\n for (const entry of roots) {\n const key = groupTurnKey(entry[1]);\n if (!key) continue;\n const bucket = rootsByTurn.get(key);\n if (bucket) bucket.push(entry);\n else rootsByTurn.set(key, [entry]);\n }\n const runToTurn = new Map<string, string>();\n for (const g of Object.values(groups)) {\n const key = groupTurnKey(g);\n if (g.runId && key) runToTurn.set(g.runId, key);\n }\n\n // Resolve each assistant reply → its run → its turn's roots. A turn\n // whose reply hasn't streamed yet stays unbound and renders live below.\n const rootsByMessageId = new Map<string, GroupEntry[]>();\n const boundTurns = new Set<string>();\n const list = messages as Array<{ id?: string; role?: string }>;\n for (const m of list) {\n if (m?.role !== \"assistant\" || !m.id) continue;\n const runId =\n agentId && threadId\n ? copilotkit.getRunIdForMessage(agentId, threadId, m.id)\n : undefined;\n const key = runId ? runToTurn.get(runId) ?? runId : undefined;\n if (!key) continue;\n const turnRoots = rootsByTurn.get(key);\n if (turnRoots) {\n rootsByMessageId.set(m.id, turnRoots);\n boundTurns.add(key);\n }\n }\n\n const pending = roots.filter(([, g]) => {\n const key = groupTurnKey(g);\n return !key || !boundTurns.has(key);\n });\n const showStartCursor = isRunning && pending.length === 0;\n\n return (\n <TurnBindingProvider value={{ rootsByMessageId }}>\n {messageElements}\n {pending.length > 0 && (\n <div className=\"kaboo-inline-cards\">\n {pending.map(([groupId, group]) => (\n <AgentCard key={groupId} groupId={groupId} group={group} showChildren />\n ))}\n </div>\n )}\n {interruptElement}\n {showStartCursor && <CopilotChatMessageView.Cursor />}\n </TurnBindingProvider>\n );\n }}\n </CopilotChatMessageView>\n );\n}\n\n/**\n * Drop-in replacement for `CopilotChat`'s `messageView` that renders swarm/graph\n * member cards **live, inside the chat, from the moment the first agent starts**\n * — not only once the final answer streams.\n *\n * Why this exists: cards attached purely to the assistant message\n * ({@link KabooAssistantMessage}) can't appear until an assistant bubble exists,\n * which for a swarm/graph is when the `chat_output` node streams — i.e. at the\n * very end. During the earlier nodes (planner, researcher, …) there is no\n * assistant message, so the chat would show only a spinner while real work is\n * happening.\n *\n * This view renders the normal message list (with {@link KabooAssistantMessage}\n * for settled turns) and, beneath it, an \"in-progress\" block for any run whose\n * activity groups have appeared but which has **no assistant bubble yet**. As\n * soon as the run's assistant message mounts, that run becomes \"covered\" and its\n * cards render inside the message instead — so there's a seamless hand-off with\n * no duplication.\n *\n * Wire it via the `messageView` slot of `CopilotChat`:\n *\n * @example\n * ```tsx\n * import { CopilotChat } from \"@copilotkit/react-core/v2\";\n * import { KabooMessageView } from \"@pgege/kaboo-react/copilotkit\";\n *\n * function Chat() {\n * return <CopilotChat messageView={KabooMessageView} />;\n * }\n * ```\n */\nexport const KabooMessageView = Object.assign(KabooMessageViewImpl, {\n /**\n * The streaming cursor slot, re-exported from CopilotKit so `KabooMessageView`\n * is a drop-in `messageView` (the slot expects a component carrying `Cursor`).\n */\n Cursor: CopilotChatMessageView.Cursor,\n});\n"],"mappings":"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","names":["jsx","jsx","jsxs"]}
|
|
1
|
+
{"version":3,"sources":["../src/integrations/KabooAssistantMessage.tsx","../src/context/TurnBinding.tsx","../src/integrations/KabooMessageView.tsx","../src/integrations/KabooUserMessage.tsx"],"sourcesContent":["import {\n CopilotChatAssistantMessage,\n type CopilotChatAssistantMessageProps,\n} from \"@copilotkit/react-core/v2\";\nimport { AgentCard } from \"../components/AgentCard\";\nimport { useTurnBinding } from \"../context/TurnBinding\";\n\n/**\n * Drop-in replacement for CopilotKit's assistant-message renderer that prepends\n * a first-class swarm/graph turn's member cards ABOVE the assistant's text —\n * inside the chat transcript, as part of the same turn.\n *\n * Wire it via the `messageView` slot of `CopilotChat`:\n *\n * ```tsx\n * <CopilotChat messageView={{ assistantMessage: KabooAssistantMessage }} />\n * ```\n *\n * This is used instead of `renderCustomMessages` because the `CopilotKit`\n * convenience provider hard-overrides that prop; the `messageView`/\n * `assistantMessage` slot is the supported customization surface and is not\n * clobbered.\n *\n * Which cards to show is decided by the turn binding (provided by\n * {@link KabooMessageView}), which resolves each reply message to its turn's\n * member cards — robust to an interrupt/resume splitting the turn across\n * multiple runIds. Delegate cards keep their tool-call path (they carry a\n * `toolCallId` and are excluded from `chatRootGroups`).\n */\nexport function KabooAssistantMessage(props: CopilotChatAssistantMessageProps) {\n const { message } = props;\n const { rootsByMessageId } = useTurnBinding();\n const messageId = (message as { id?: string })?.id;\n const mine = messageId ? rootsByMessageId.get(messageId) ?? [] : [];\n\n return (\n <>\n {mine.length > 0 && (\n <div className=\"kaboo-inline-cards\">\n {mine.map(([groupId, group]) => (\n <AgentCard key={groupId} groupId={groupId} group={group} showChildren />\n ))}\n </div>\n )}\n <CopilotChatAssistantMessage {...props} />\n </>\n );\n}\n","import { createContext, useContext, type ReactNode } from \"react\";\nimport type { GroupEntry } from \"../utils/groups\";\n\n/**\n * Binds each assistant reply message to the swarm/graph member cards its turn\n * produced, so those cards render *inside* that message (above its reply text)\n * in one chronological block — and a turn's cards never bleed onto a different\n * turn's reply.\n *\n * The mapping is by turn, not `runId`: an interrupt/resume changes the `runId`\n * mid-turn, so a reply's `runId` may only match the `chat_output` member while\n * earlier members carry the pre-resume `runId`. Both, however, share the\n * server-stamped `turnId` ({@link groupTurnKey}). {@link KabooMessageView}\n * resolves each reply message → its run → that run's `turnId`, then collects all\n * roots of that turn — so every member binds to the right reply regardless of\n * how many runs the turn spanned.\n *\n * `rootsByMessageId` holds the resolved cards per assistant message id; a turn\n * whose reply hasn't streamed yet isn't in the map — {@link KabooMessageView}\n * renders those roots live beneath the transcript instead.\n */\nexport interface TurnBinding {\n rootsByMessageId: Map<string, GroupEntry[]>;\n}\n\nconst TurnBindingContext = createContext<TurnBinding>({\n rootsByMessageId: new Map(),\n});\n\nexport function TurnBindingProvider({\n value,\n children,\n}: {\n value: TurnBinding;\n children: ReactNode;\n}) {\n return (\n <TurnBindingContext.Provider value={value}>\n {children}\n </TurnBindingContext.Provider>\n );\n}\n\nexport function useTurnBinding(): TurnBinding {\n return useContext(TurnBindingContext);\n}\n","import {\n CopilotChatMessageView,\n CopilotChatAssistantMessage,\n CopilotChatUserMessage,\n useCopilotKit,\n useCopilotChatConfiguration,\n type CopilotChatMessageViewProps,\n} from \"@copilotkit/react-core/v2\";\nimport { useActivity } from \"../hooks/useActivity\";\nimport { AgentCard } from \"../components/AgentCard\";\nimport { chatRootGroups, groupTurnKey, type GroupEntry } from \"../utils/groups\";\nimport { TurnBindingProvider } from \"../context/TurnBinding\";\nimport { KabooAssistantMessage } from \"./KabooAssistantMessage\";\nimport { KabooUserMessage } from \"./KabooUserMessage\";\n\nfunction KabooMessageViewImpl(props: CopilotChatMessageViewProps) {\n const { groups } = useActivity();\n const { copilotkit } = useCopilotKit();\n const config = useCopilotChatConfiguration();\n const agentId = config?.agentId;\n const threadId = config?.threadId;\n\n return (\n <CopilotChatMessageView\n {...props}\n assistantMessage={\n KabooAssistantMessage as unknown as typeof CopilotChatAssistantMessage\n }\n userMessage={KabooUserMessage as unknown as typeof CopilotChatUserMessage}\n >\n {({ messages, messageElements, interruptElement, isRunning }) => {\n const roots = chatRootGroups(groups);\n\n // Bucket this turn's member cards by their stable turn key, and map each\n // AG-UI run to its turn key so a reply (whose run may be the post-resume\n // one) resolves to the whole turn — not just its chat_output member.\n const rootsByTurn = new Map<string, GroupEntry[]>();\n for (const entry of roots) {\n const key = groupTurnKey(entry[1]);\n if (!key) continue;\n const bucket = rootsByTurn.get(key);\n if (bucket) bucket.push(entry);\n else rootsByTurn.set(key, [entry]);\n }\n const runToTurn = new Map<string, string>();\n for (const g of Object.values(groups)) {\n const key = groupTurnKey(g);\n if (g.runId && key) runToTurn.set(g.runId, key);\n }\n\n // Resolve each assistant reply → its run → its turn's roots. A turn\n // whose reply hasn't streamed yet stays unbound and renders live below.\n const rootsByMessageId = new Map<string, GroupEntry[]>();\n const boundTurns = new Set<string>();\n const list = messages as Array<{ id?: string; role?: string }>;\n for (const m of list) {\n if (m?.role !== \"assistant\" || !m.id) continue;\n const runId =\n agentId && threadId\n ? copilotkit.getRunIdForMessage(agentId, threadId, m.id)\n : undefined;\n const key = runId ? runToTurn.get(runId) ?? runId : undefined;\n if (!key) continue;\n const turnRoots = rootsByTurn.get(key);\n if (turnRoots) {\n rootsByMessageId.set(m.id, turnRoots);\n boundTurns.add(key);\n }\n }\n\n const pending = roots.filter(([, g]) => {\n const key = groupTurnKey(g);\n return !key || !boundTurns.has(key);\n });\n const showStartCursor = isRunning && pending.length === 0;\n\n return (\n <TurnBindingProvider value={{ rootsByMessageId }}>\n {messageElements}\n {pending.length > 0 && (\n <div className=\"kaboo-inline-cards\">\n {pending.map(([groupId, group]) => (\n <AgentCard key={groupId} groupId={groupId} group={group} showChildren />\n ))}\n </div>\n )}\n {interruptElement}\n {showStartCursor && <CopilotChatMessageView.Cursor />}\n </TurnBindingProvider>\n );\n }}\n </CopilotChatMessageView>\n );\n}\n\n/**\n * Drop-in replacement for `CopilotChat`'s `messageView` that renders swarm/graph\n * member cards **live, inside the chat, from the moment the first agent starts**\n * — not only once the final answer streams.\n *\n * Why this exists: cards attached purely to the assistant message\n * ({@link KabooAssistantMessage}) can't appear until an assistant bubble exists,\n * which for a swarm/graph is when the `chat_output` node streams — i.e. at the\n * very end. During the earlier nodes (planner, researcher, …) there is no\n * assistant message, so the chat would show only a spinner while real work is\n * happening.\n *\n * This view renders the normal message list (with {@link KabooAssistantMessage}\n * for settled turns) and, beneath it, an \"in-progress\" block for any run whose\n * activity groups have appeared but which has **no assistant bubble yet**. As\n * soon as the run's assistant message mounts, that run becomes \"covered\" and its\n * cards render inside the message instead — so there's a seamless hand-off with\n * no duplication.\n *\n * Wire it via the `messageView` slot of `CopilotChat`:\n *\n * @example\n * ```tsx\n * import { CopilotChat } from \"@copilotkit/react-core/v2\";\n * import { KabooMessageView } from \"@pgege/kaboo-react/copilotkit\";\n *\n * function Chat() {\n * return <CopilotChat messageView={KabooMessageView} />;\n * }\n * ```\n */\nexport const KabooMessageView = Object.assign(KabooMessageViewImpl, {\n /**\n * The streaming cursor slot, re-exported from CopilotKit so `KabooMessageView`\n * is a drop-in `messageView` (the slot expects a component carrying `Cursor`).\n */\n Cursor: CopilotChatMessageView.Cursor,\n});\n","import type { ReactNode } from \"react\";\nimport {\n CopilotChatUserMessage,\n type CopilotChatUserMessageProps,\n} from \"@copilotkit/react-core/v2\";\nimport { useReferences } from \"../references/ReferencesProvider\";\nimport type { PendingReference } from \"../references/types\";\n\n// CopilotKit's own wrapper/bubble classes, replicated so our custom layout\n// (via the children render-prop) matches the native user message exactly.\nconst WRAP_CLASS =\n \"copilotKitMessage copilotKitUserMessage cpk:flex cpk:flex-col cpk:items-end cpk:group cpk:pt-10\";\nconst BUBBLE_CLASS =\n \"cpk:prose cpk:dark:prose-invert cpk:bg-muted cpk:relative cpk:max-w-[80%] cpk:rounded-[18px] cpk:px-4 cpk:py-1.5 cpk:inline-block cpk:whitespace-pre-wrap\";\n\nconst AtIcon = (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"4\" />\n <path d=\"M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-3.92 7.94\" />\n </svg>\n);\nconst FileIcon = (\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n <path d=\"M14 2v6h6\" />\n </svg>\n);\n\n/** A media/document/image content part on a user message. */\ninterface FilePart {\n kind: \"image\" | \"audio\" | \"video\" | \"document\";\n src: string;\n filename: string;\n}\n\n/** Text of a user message (string content, or joined text parts). */\nfunction messageText(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n return content\n .map((p) =>\n p && typeof p === \"object\" && (p as { type?: string }).type === \"text\"\n ? String((p as { text?: string }).text ?? \"\")\n : \"\",\n )\n .filter(Boolean)\n .join(\"\\n\");\n}\n\n/** Extract renderable file parts (with a resolved src) from message content. */\nfunction fileParts(content: unknown): FilePart[] {\n if (!Array.isArray(content)) return [];\n const out: FilePart[] = [];\n for (const part of content) {\n const type = (part as { type?: string })?.type;\n if (type !== \"image\" && type !== \"audio\" && type !== \"video\" && type !== \"document\") continue;\n const source = (part as { source?: { type?: string; value?: string; mimeType?: string } }).source;\n if (!source?.value) continue;\n const src =\n source.type === \"url\" ? source.value : `data:${source.mimeType ?? \"\"};base64,${source.value}`;\n const meta = (part as { metadata?: { filename?: string } }).metadata;\n out.push({ kind: type, src, filename: meta?.filename ?? source.mimeType ?? \"file\" });\n }\n return out;\n}\n\n/** Non-interactive object-reference chip (`@name`). */\nfunction ObjectChip({ reference, inline }: { reference: PendingReference; inline?: boolean }) {\n return (\n <span\n className={`kaboo-chip kaboo-chip-object kaboo-msg-chip${inline ? \" kaboo-msg-chip-inline\" : \"\"}`}\n title={reference.name}\n >\n <span className=\"kaboo-chip-ic\">{AtIcon}</span>\n <span className=\"kaboo-chip-label\">{reference.name}</span>\n </span>\n );\n}\n\n/** Non-interactive file chip: image preview or document icon + filename. */\nfunction FileChip({ file }: { file: FilePart }) {\n return (\n <span className=\"kaboo-chip kaboo-chip-attachment kaboo-msg-chip\" title={file.filename}>\n {file.kind === \"image\" ? (\n <img className=\"kaboo-chip-thumb\" src={file.src} alt={file.filename} />\n ) : (\n <span className=\"kaboo-chip-ic\">{FileIcon}</span>\n )}\n <span className=\"kaboo-chip-label\">{file.filename}</span>\n </span>\n );\n}\n\n/** Split text on inline reference tokens (`@name`), rendering each as a chip. */\nfunction renderInline(text: string, refs: PendingReference[]): ReactNode[] {\n if (refs.length === 0) return [text];\n const tokens = refs\n .map((ref) => ({ ref, token: `@${ref.name}` }))\n .sort((a, b) => b.token.length - a.token.length);\n const out: ReactNode[] = [];\n let i = 0;\n let key = 0;\n while (i < text.length) {\n const hit = tokens.find((t) => text.startsWith(t.token, i));\n if (hit) {\n out.push(<ObjectChip key={key++} reference={hit.ref} inline />);\n i += hit.token.length;\n continue;\n }\n let next = text.length;\n for (const t of tokens) {\n const idx = text.indexOf(t.token, i + 1);\n if (idx !== -1 && idx < next) next = idx;\n }\n out.push(text.slice(i, next));\n i = next;\n }\n return out;\n}\n\n/**\n * Drop-in replacement for `CopilotChatMessageView`'s `userMessage` slot that\n * renders every reference the user sent as a **non-interactive chip**, so a\n * reference reads as a reference rather than plain text:\n *\n * - object references cited inline (`@name`) render as chips *within* the text;\n * - files and objects added via the `+` tray render as a chip row above the\n * bubble (files show a thumbnail/icon + filename).\n *\n * Object references ride `state.kaboo_references` (not the message content), so\n * they come from the per-message registry on {@link useReferences}; files come\n * from the message's media parts.\n */\nexport function KabooUserMessage(props: CopilotChatUserMessageProps) {\n const { messageReferences } = useReferences();\n const message = props.message as { id?: string; content?: unknown } | undefined;\n const id = message?.id;\n const objectRefs = (id ? messageReferences[id] : undefined) ?? [];\n const text = messageText(message?.content);\n const files = fileParts(message?.content);\n\n const inlineRefs = objectRefs.filter((r) => text.includes(`@${r.name}`));\n const trayRefs = objectRefs.filter((r) => !text.includes(`@${r.name}`));\n const hasChipRow = files.length > 0 || trayRefs.length > 0;\n\n const MessageRenderer = ({ content, className }: { content: string; className?: string }) => (\n <div className={className ? `${BUBBLE_CLASS} ${className}` : BUBBLE_CLASS}>\n {renderInline(content, inlineRefs)}\n </div>\n );\n\n return (\n <CopilotChatUserMessage\n {...props}\n messageRenderer={MessageRenderer as unknown as typeof CopilotChatUserMessage.MessageRenderer}\n >\n {({ messageRenderer, toolbar }) => (\n <div data-copilotkit data-message-id={id} className={`${WRAP_CLASS} kaboo-user-message`}>\n {hasChipRow && (\n <div className=\"kaboo-msg-refs\">\n {files.map((f, i) => (\n <FileChip key={`f${i}`} file={f} />\n ))}\n {trayRefs.map((r) => (\n <ObjectChip key={r.id} reference={r} />\n ))}\n </div>\n )}\n {messageRenderer}\n {toolbar}\n </div>\n )}\n </CopilotChatUserMessage>\n );\n}\n"],"mappings":"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","names":["jsx","jsx","jsxs","jsx","jsxs"]}
|