@lattice-php/lattice 0.51.0 → 0.53.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/index.d.ts +0 -4
- package/dist/index.js +1 -3
- package/dist/layout/components/breadcrumbs.js +13 -10
- package/dist/layout/components/breadcrumbs.js.map +1 -1
- package/dist/layout/components/sidebar-footer.d.ts +3 -0
- package/dist/layout/components/sidebar-footer.js +12 -0
- package/dist/layout/components/sidebar-footer.js.map +1 -0
- package/dist/layout/plugin.js +2 -0
- package/dist/layout/plugin.js.map +1 -1
- package/dist/registry.d.ts +3 -3
- package/dist/registry.js +1 -2
- package/dist/registry.js.map +1 -1
- package/dist/runtime.d.ts +2 -0
- package/dist/runtime.js +3 -3
- package/dist/types/generated.d.ts +6 -43
- package/dist-standalone/chunks/{chart-view-7uSaRy0z.js → chart-view-B0JDdw6X.js} +6 -6
- package/dist-standalone/chunks/{date-picker-field-BhEHDCJ1.js → date-picker-field-BQYBMkGH.js} +1 -1
- package/dist-standalone/chunks/{field-HgRGTmPZ.js → field-DUsnOq--.js} +1 -1
- package/dist-standalone/chunks/{rich-editor-field-D76kQ6Fe.js → rich-editor-field-DB0MCHzF.js} +2 -2
- package/dist-standalone/chunks/{runtime-BxB5Ladg.js → runtime-CqO6aLVU.js} +8 -9
- package/dist-standalone/chunks/{subscriptions-Cr5l3mYJ.js → subscriptions-Cg-Qrt0-.js} +1 -1
- package/dist-standalone/lattice.css +1 -1
- package/dist-standalone/lattice.js +1 -1
- package/dist-standalone/manifest.json +1 -1
- package/dist-standalone/runtime.js +1 -1
- package/package.json +6 -10
- package/dist/chat/components/chat-box.d.ts +0 -3
- package/dist/chat/components/chat-box.js +0 -72
- package/dist/chat/components/chat-box.js.map +0 -1
- package/dist/chat/components/message-list.d.ts +0 -5
- package/dist/chat/components/message-list.js +0 -22
- package/dist/chat/components/message-list.js.map +0 -1
- package/dist/chat/components/message.d.ts +0 -5
- package/dist/chat/components/message.js +0 -20
- package/dist/chat/components/message.js.map +0 -1
- package/dist/chat/components/prompt-input.d.ts +0 -8
- package/dist/chat/components/prompt-input.js +0 -49
- package/dist/chat/components/prompt-input.js.map +0 -1
- package/dist/chat/hooks/use-chat.d.ts +0 -15
- package/dist/chat/hooks/use-chat.js +0 -162
- package/dist/chat/hooks/use-chat.js.map +0 -1
- package/dist/chat/index.d.ts +0 -4
- package/dist/chat/index.js +0 -3
- package/dist/chat/lib/transport.d.ts +0 -4
- package/dist/chat/lib/transport.js +0 -66
- package/dist/chat/lib/transport.js.map +0 -1
- package/dist/chat/parts/text.d.ts +0 -3
- package/dist/chat/parts/text.js +0 -12
- package/dist/chat/parts/text.js.map +0 -1
- package/dist/chat/parts/tool-call.d.ts +0 -3
- package/dist/chat/parts/tool-call.js +0 -20
- package/dist/chat/parts/tool-call.js.map +0 -1
- package/dist/chat/plugin.d.ts +0 -2
- package/dist/chat/plugin.js +0 -17
- package/dist/chat/plugin.js.map +0 -1
- package/dist/chat/types.d.ts +0 -31
- package/dist/chat/types.js +0 -0
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { Message } from "./message.js";
|
|
2
|
-
import { useEffect, useRef } from "react";
|
|
3
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
-
import { testIdentity } from "@lattice-php/core/test-id";
|
|
5
|
-
//#region resources/js/chat/components/message-list.tsx
|
|
6
|
-
function MessageList({ messages }) {
|
|
7
|
-
const bottomRef = useRef(null);
|
|
8
|
-
const lastMessage = messages.at(-1);
|
|
9
|
-
const lastPartLength = lastMessage?.parts.at(-1) !== void 0 ? JSON.stringify(lastMessage.parts.at(-1)).length : 0;
|
|
10
|
-
useEffect(() => {
|
|
11
|
-
if (bottomRef.current && typeof bottomRef.current.scrollIntoView === "function") bottomRef.current.scrollIntoView({ behavior: "smooth" });
|
|
12
|
-
}, [messages.length, lastPartLength]);
|
|
13
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
14
|
-
className: "flex flex-col gap-2 overflow-y-auto p-3",
|
|
15
|
-
"data-test": testIdentity("chat-messages"),
|
|
16
|
-
children: [messages.map((message) => /* @__PURE__ */ jsx(Message, { message }, message.id)), /* @__PURE__ */ jsx("div", { ref: bottomRef })]
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
//#endregion
|
|
20
|
-
export { MessageList };
|
|
21
|
-
|
|
22
|
-
//# sourceMappingURL=message-list.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"message-list.js","names":[],"sources":["../../../resources/js/chat/components/message-list.tsx"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { testIdentity } from \"@lattice-php/core/test-id\";\nimport type { ChatMessage } from \"@lattice-php/lattice/chat/types\";\nimport { Message } from \"./message\";\n\nexport function MessageList({ messages }: { messages: ChatMessage[] }): ReactNode {\n const bottomRef = useRef<HTMLDivElement>(null);\n const lastMessage = messages.at(-1);\n const lastPartLength =\n lastMessage?.parts.at(-1) !== undefined ? JSON.stringify(lastMessage.parts.at(-1)).length : 0;\n\n useEffect(() => {\n if (bottomRef.current && typeof bottomRef.current.scrollIntoView === \"function\") {\n bottomRef.current.scrollIntoView({ behavior: \"smooth\" });\n }\n }, [messages.length, lastPartLength]);\n\n return (\n <div\n className=\"flex flex-col gap-2 overflow-y-auto p-3\"\n data-test={testIdentity(\"chat-messages\")}\n >\n {messages.map((message) => (\n <Message key={message.id} message={message} />\n ))}\n <div ref={bottomRef} />\n </div>\n );\n}\n"],"mappings":";;;;;AAMA,SAAgB,YAAY,EAAE,YAAoD;CAChF,MAAM,YAAY,OAAuB,IAAI;CAC7C,MAAM,cAAc,SAAS,GAAG,EAAE;CAClC,MAAM,iBACJ,aAAa,MAAM,GAAG,EAAE,MAAM,KAAA,IAAY,KAAK,UAAU,YAAY,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS;CAE9F,gBAAgB;EACd,IAAI,UAAU,WAAW,OAAO,UAAU,QAAQ,mBAAmB,YACnE,UAAU,QAAQ,eAAe,EAAE,UAAU,SAAS,CAAC;CAE3D,GAAG,CAAC,SAAS,QAAQ,cAAc,CAAC;CAEpC,OACE,qBAAC,OAAD;EACE,WAAU;EACV,aAAW,aAAa,eAAe;EAFzC,UAAA,CAIG,SAAS,KAAK,YACb,oBAAC,SAAD,EAAmC,QAAU,GAA/B,QAAQ,EAAuB,CAC9C,GACD,oBAAC,OAAD,EAAK,KAAK,UAAY,CAAA,CACnB;;AAET"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { RenderNode } from "@lattice-php/core/renderer";
|
|
2
|
-
import { cn } from "@lattice-php/ui/lib/utils";
|
|
3
|
-
import { jsx } from "react/jsx-runtime";
|
|
4
|
-
import { testIdentity } from "@lattice-php/core/test-id";
|
|
5
|
-
//#region resources/js/chat/components/message.tsx
|
|
6
|
-
function Message({ message }) {
|
|
7
|
-
const isUser = message.role === "user";
|
|
8
|
-
return /* @__PURE__ */ jsx("div", {
|
|
9
|
-
className: cn("flex flex-col gap-1", isUser ? "items-end" : "items-start"),
|
|
10
|
-
"data-test": testIdentity(`chat-message-${message.role}`),
|
|
11
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
12
|
-
className: cn("max-w-[80%] rounded-lt px-3 py-2 text-sm", isUser ? "bg-lt-primary text-lt-primary-fg" : "bg-lt-muted text-lt-fg"),
|
|
13
|
-
children: message.parts.map((part, index) => /* @__PURE__ */ jsx(RenderNode, { node: part }, part.key ?? index))
|
|
14
|
-
})
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
//#endregion
|
|
18
|
-
export { Message };
|
|
19
|
-
|
|
20
|
-
//# sourceMappingURL=message.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"message.js","names":[],"sources":["../../../resources/js/chat/components/message.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport { cn } from \"@lattice-php/ui/lib/utils\";\nimport { testIdentity } from \"@lattice-php/core/test-id\";\nimport { RenderNode } from \"@lattice-php/core/renderer\";\nimport type { ChatMessage } from \"@lattice-php/lattice/chat/types\";\n\nexport function Message({ message }: { message: ChatMessage }): ReactNode {\n const isUser = message.role === \"user\";\n\n return (\n <div\n className={cn(\"flex flex-col gap-1\", isUser ? \"items-end\" : \"items-start\")}\n data-test={testIdentity(`chat-message-${message.role}`)}\n >\n <div\n className={cn(\n \"max-w-[80%] rounded-lt px-3 py-2 text-sm\",\n isUser ? \"bg-lt-primary text-lt-primary-fg\" : \"bg-lt-muted text-lt-fg\",\n )}\n >\n {message.parts.map((part, index) => (\n <RenderNode key={part.key ?? index} node={part} />\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;AAMA,SAAgB,QAAQ,EAAE,WAAgD;CACxE,MAAM,SAAS,QAAQ,SAAS;CAEhC,OACE,oBAAC,OAAD;EACE,WAAW,GAAG,uBAAuB,SAAS,cAAc,aAAa;EACzE,aAAW,aAAa,gBAAgB,QAAQ,MAAM;EAEtD,UAAA,oBAAC,OAAD;GACE,WAAW,GACT,4CACA,SAAS,qCAAqC,wBAChD;GAEC,UAAA,QAAQ,MAAM,KAAK,MAAM,UACxB,oBAAC,YAAD,EAAoC,MAAM,KAAO,GAAhC,KAAK,OAAO,KAAoB,CAClD;EACE,CAAA;CACF,CAAA;AAET"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
2
|
-
type PromptInputProps = {
|
|
3
|
-
onSubmit: (text: string) => void;
|
|
4
|
-
disabled?: boolean;
|
|
5
|
-
placeholder?: string;
|
|
6
|
-
};
|
|
7
|
-
export declare function PromptInput({ onSubmit, disabled, placeholder, }: PromptInputProps): ReactNode;
|
|
8
|
-
export {};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
|
-
import { cn } from "@lattice-php/ui/lib/utils";
|
|
3
|
-
import { useT } from "@lattice-php/ui/i18n";
|
|
4
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
import { testIdentity } from "@lattice-php/core/test-id";
|
|
6
|
-
import { Button } from "@lattice-php/ui/components/button";
|
|
7
|
-
//#region resources/js/chat/components/prompt-input.tsx
|
|
8
|
-
function PromptInput({ onSubmit, disabled = false, placeholder }) {
|
|
9
|
-
const { t } = useT("lattice");
|
|
10
|
-
const [value, setValue] = useState("");
|
|
11
|
-
function submit() {
|
|
12
|
-
const trimmed = value.trim();
|
|
13
|
-
if (trimmed === "" || disabled) return;
|
|
14
|
-
onSubmit(trimmed);
|
|
15
|
-
setValue("");
|
|
16
|
-
}
|
|
17
|
-
function handleKeyDown(event) {
|
|
18
|
-
if (event.key === "Enter" && !event.shiftKey) {
|
|
19
|
-
event.preventDefault();
|
|
20
|
-
submit();
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
24
|
-
className: "flex items-end gap-2 border-t border-lt-border p-3",
|
|
25
|
-
children: [/* @__PURE__ */ jsx("textarea", {
|
|
26
|
-
"aria-label": t("common.chat.input-label", "Message input"),
|
|
27
|
-
className: cn("min-h-[2.5rem] flex-1 resize-none rounded-lt-sm border border-lt-input bg-lt-bg px-3 py-2 text-sm text-lt-fg placeholder:text-lt-muted-fg focus:outline-none focus:ring-[length:var(--lt-ring-width)] focus:ring-lt-ring/50 disabled:bg-lt-disabled disabled:text-lt-disabled-fg"),
|
|
28
|
-
"data-slot": "prompt-input",
|
|
29
|
-
"data-test": testIdentity("chat-input"),
|
|
30
|
-
disabled,
|
|
31
|
-
onChange: (e) => setValue(e.target.value),
|
|
32
|
-
onKeyDown: handleKeyDown,
|
|
33
|
-
placeholder,
|
|
34
|
-
rows: 1,
|
|
35
|
-
value
|
|
36
|
-
}), /* @__PURE__ */ jsx(Button, {
|
|
37
|
-
"data-test": testIdentity("chat-send"),
|
|
38
|
-
disabled,
|
|
39
|
-
onClick: submit,
|
|
40
|
-
size: "sm",
|
|
41
|
-
type: "button",
|
|
42
|
-
children: t("common.chat.send", "Send")
|
|
43
|
-
})]
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
//#endregion
|
|
47
|
-
export { PromptInput };
|
|
48
|
-
|
|
49
|
-
//# sourceMappingURL=prompt-input.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prompt-input.js","names":[],"sources":["../../../resources/js/chat/components/prompt-input.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport type { KeyboardEvent, ReactNode } from \"react\";\nimport { cn } from \"@lattice-php/ui/lib/utils\";\nimport { testIdentity } from \"@lattice-php/core/test-id\";\nimport { Button } from \"@lattice-php/ui/components/button\";\nimport { useT } from \"@lattice-php/ui/i18n\";\n\ntype PromptInputProps = {\n onSubmit: (text: string) => void;\n disabled?: boolean;\n placeholder?: string;\n};\n\nexport function PromptInput({\n onSubmit,\n disabled = false,\n placeholder,\n}: PromptInputProps): ReactNode {\n const { t } = useT(\"lattice\");\n const [value, setValue] = useState(\"\");\n\n function submit(): void {\n const trimmed = value.trim();\n if (trimmed === \"\" || disabled) {\n return;\n }\n\n onSubmit(trimmed);\n setValue(\"\");\n }\n\n function handleKeyDown(event: KeyboardEvent<HTMLTextAreaElement>): void {\n if (event.key === \"Enter\" && !event.shiftKey) {\n event.preventDefault();\n submit();\n }\n }\n\n return (\n <div className=\"flex items-end gap-2 border-t border-lt-border p-3\">\n <textarea\n aria-label={t(\"common.chat.input-label\", \"Message input\")}\n className={cn(\n \"min-h-[2.5rem] flex-1 resize-none rounded-lt-sm border border-lt-input bg-lt-bg px-3 py-2 text-sm text-lt-fg placeholder:text-lt-muted-fg focus:outline-none focus:ring-[length:var(--lt-ring-width)] focus:ring-lt-ring/50 disabled:bg-lt-disabled disabled:text-lt-disabled-fg\",\n )}\n data-slot=\"prompt-input\"\n data-test={testIdentity(\"chat-input\")}\n disabled={disabled}\n onChange={(e) => setValue(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n rows={1}\n value={value}\n />\n <Button\n data-test={testIdentity(\"chat-send\")}\n disabled={disabled}\n onClick={submit}\n size=\"sm\"\n type=\"button\"\n >\n {t(\"common.chat.send\", \"Send\")}\n </Button>\n </div>\n );\n}\n"],"mappings":";;;;;;;AAaA,SAAgB,YAAY,EAC1B,UACA,WAAW,OACX,eAC8B;CAC9B,MAAM,EAAE,MAAM,KAAK,SAAS;CAC5B,MAAM,CAAC,OAAO,YAAY,SAAS,EAAE;CAErC,SAAS,SAAe;EACtB,MAAM,UAAU,MAAM,KAAK;EAC3B,IAAI,YAAY,MAAM,UACpB;EAGF,SAAS,OAAO;EAChB,SAAS,EAAE;CACb;CAEA,SAAS,cAAc,OAAiD;EACtE,IAAI,MAAM,QAAQ,WAAW,CAAC,MAAM,UAAU;GAC5C,MAAM,eAAe;GACrB,OAAO;EACT;CACF;CAEA,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,YAAD;GACE,cAAY,EAAE,2BAA2B,eAAe;GACxD,WAAW,GACT,kRACF;GACA,aAAU;GACV,aAAW,aAAa,YAAY;GAC1B;GACV,WAAW,MAAM,SAAS,EAAE,OAAO,KAAK;GACxC,WAAW;GACE;GACb,MAAM;GACC;EACR,CAAA,GACD,oBAAC,QAAD;GACE,aAAW,aAAa,WAAW;GACzB;GACV,SAAS;GACT,MAAK;GACL,MAAK;GAEJ,UAAA,EAAE,oBAAoB,MAAM;EACvB,CAAA,CACL;;AAET"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { ChatFrame, ChatMessage, ChatTransport, UseChatReturn } from '../types.js';
|
|
2
|
-
export type UseChatOptions = {
|
|
3
|
-
endpoint: string;
|
|
4
|
-
transport?: ChatTransport;
|
|
5
|
-
initialMessages?: ChatMessage[];
|
|
6
|
-
generateId?: () => string;
|
|
7
|
-
};
|
|
8
|
-
/**
|
|
9
|
-
* Pure reducer for a single streamed frame: a `text` frame appends to the open
|
|
10
|
-
* assistant text part (opening one if the last part is not text); a `part` frame
|
|
11
|
-
* pushes a complete part, which closes the open text part. Operates immutably on
|
|
12
|
-
* the last assistant message.
|
|
13
|
-
*/
|
|
14
|
-
export declare function foldFrame(messages: ChatMessage[], frame: ChatFrame): ChatMessage[];
|
|
15
|
-
export declare function useChat({ endpoint, transport, initialMessages, generateId, }: UseChatOptions): UseChatReturn;
|
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import { ndjsonChatTransport } from "../lib/transport.js";
|
|
2
|
-
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
|
-
//#region resources/js/chat/hooks/use-chat.ts
|
|
4
|
-
var idCounter = 0;
|
|
5
|
-
function defaultGenerateId() {
|
|
6
|
-
idCounter += 1;
|
|
7
|
-
return `chat-${idCounter}`;
|
|
8
|
-
}
|
|
9
|
-
function isAbortError(error) {
|
|
10
|
-
return error instanceof DOMException && error.name === "AbortError";
|
|
11
|
-
}
|
|
12
|
-
function errorMessage(error) {
|
|
13
|
-
return error instanceof Error ? error.message : String(error);
|
|
14
|
-
}
|
|
15
|
-
function lastIsAssistant(messages) {
|
|
16
|
-
const last = messages.at(-1);
|
|
17
|
-
return last !== void 0 && last.role === "assistant";
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Pure reducer for a single streamed frame: a `text` frame appends to the open
|
|
21
|
-
* assistant text part (opening one if the last part is not text); a `part` frame
|
|
22
|
-
* pushes a complete part, which closes the open text part. Operates immutably on
|
|
23
|
-
* the last assistant message.
|
|
24
|
-
*/
|
|
25
|
-
function foldFrame(messages, frame) {
|
|
26
|
-
if (!lastIsAssistant(messages)) return messages;
|
|
27
|
-
const index = messages.length - 1;
|
|
28
|
-
const target = messages[index];
|
|
29
|
-
if (frame.type === "text") {
|
|
30
|
-
const parts = [...target.parts];
|
|
31
|
-
const openIndex = parts.length - 1;
|
|
32
|
-
const open = parts[openIndex];
|
|
33
|
-
if (open !== void 0 && open.type === "chat.part.text") parts[openIndex] = {
|
|
34
|
-
type: "chat.part.text",
|
|
35
|
-
props: { text: `${open.props.text}${frame.value}` }
|
|
36
|
-
};
|
|
37
|
-
else parts.push({
|
|
38
|
-
type: "chat.part.text",
|
|
39
|
-
props: { text: frame.value }
|
|
40
|
-
});
|
|
41
|
-
const next = [...messages];
|
|
42
|
-
next[index] = {
|
|
43
|
-
...target,
|
|
44
|
-
parts
|
|
45
|
-
};
|
|
46
|
-
return next;
|
|
47
|
-
}
|
|
48
|
-
if (frame.type === "part") {
|
|
49
|
-
const next = [...messages];
|
|
50
|
-
next[index] = {
|
|
51
|
-
...target,
|
|
52
|
-
parts: [...target.parts, frame.part]
|
|
53
|
-
};
|
|
54
|
-
return next;
|
|
55
|
-
}
|
|
56
|
-
return messages;
|
|
57
|
-
}
|
|
58
|
-
function useChat({ endpoint, transport = ndjsonChatTransport, initialMessages = [], generateId = defaultGenerateId }) {
|
|
59
|
-
const [messages, setMessagesState] = useState(initialMessages);
|
|
60
|
-
const [status, setStatus] = useState("idle");
|
|
61
|
-
const [error, setError] = useState(null);
|
|
62
|
-
const abortRef = useRef(null);
|
|
63
|
-
const lastUserTextRef = useRef(null);
|
|
64
|
-
const messagesRef = useRef(messages);
|
|
65
|
-
messagesRef.current = messages;
|
|
66
|
-
const commitMessages = useCallback((next) => {
|
|
67
|
-
messagesRef.current = next;
|
|
68
|
-
setMessagesState(next);
|
|
69
|
-
}, []);
|
|
70
|
-
const runTurn = useCallback(async (history, userText) => {
|
|
71
|
-
abortRef.current?.abort();
|
|
72
|
-
const controller = new AbortController();
|
|
73
|
-
abortRef.current = controller;
|
|
74
|
-
setError(null);
|
|
75
|
-
setStatus("submitted");
|
|
76
|
-
const userMessage = {
|
|
77
|
-
id: generateId(),
|
|
78
|
-
role: "user",
|
|
79
|
-
parts: [{
|
|
80
|
-
type: "chat.part.text",
|
|
81
|
-
props: { text: userText }
|
|
82
|
-
}]
|
|
83
|
-
};
|
|
84
|
-
const assistantMessage = {
|
|
85
|
-
id: generateId(),
|
|
86
|
-
role: "assistant",
|
|
87
|
-
parts: []
|
|
88
|
-
};
|
|
89
|
-
commitMessages([
|
|
90
|
-
...history,
|
|
91
|
-
userMessage,
|
|
92
|
-
assistantMessage
|
|
93
|
-
]);
|
|
94
|
-
setStatus("streaming");
|
|
95
|
-
try {
|
|
96
|
-
for await (const frame of transport({
|
|
97
|
-
url: endpoint,
|
|
98
|
-
body: { message: userText },
|
|
99
|
-
signal: controller.signal
|
|
100
|
-
})) {
|
|
101
|
-
if (frame.type === "done") {
|
|
102
|
-
setStatus("idle");
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
|
-
if (frame.type === "error") {
|
|
106
|
-
setError(frame.message ?? "Chat failed");
|
|
107
|
-
setStatus("error");
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
commitMessages(foldFrame(messagesRef.current, frame));
|
|
111
|
-
}
|
|
112
|
-
setStatus((current) => current === "streaming" || current === "submitted" ? "idle" : current);
|
|
113
|
-
} catch (caught) {
|
|
114
|
-
if (isAbortError(caught)) {
|
|
115
|
-
setStatus("idle");
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
setError(errorMessage(caught));
|
|
119
|
-
setStatus("error");
|
|
120
|
-
}
|
|
121
|
-
}, [
|
|
122
|
-
commitMessages,
|
|
123
|
-
endpoint,
|
|
124
|
-
generateId,
|
|
125
|
-
transport
|
|
126
|
-
]);
|
|
127
|
-
const sendMessage = useCallback((text) => {
|
|
128
|
-
const trimmed = text.trim();
|
|
129
|
-
if (trimmed === "") return;
|
|
130
|
-
lastUserTextRef.current = trimmed;
|
|
131
|
-
runTurn(messagesRef.current, trimmed);
|
|
132
|
-
}, [runTurn]);
|
|
133
|
-
const stop = useCallback(() => {
|
|
134
|
-
abortRef.current?.abort();
|
|
135
|
-
setStatus("idle");
|
|
136
|
-
}, []);
|
|
137
|
-
const regenerate = useCallback(() => {
|
|
138
|
-
const userText = lastUserTextRef.current;
|
|
139
|
-
if (userText === null) return;
|
|
140
|
-
const current = messagesRef.current;
|
|
141
|
-
const history = lastIsAssistant(current) ? current.slice(0, -2) : current;
|
|
142
|
-
runTurn(history, userText);
|
|
143
|
-
}, [runTurn]);
|
|
144
|
-
useEffect(() => {
|
|
145
|
-
return () => {
|
|
146
|
-
abortRef.current?.abort();
|
|
147
|
-
};
|
|
148
|
-
}, []);
|
|
149
|
-
return {
|
|
150
|
-
messages,
|
|
151
|
-
status,
|
|
152
|
-
error,
|
|
153
|
-
sendMessage,
|
|
154
|
-
setMessages: commitMessages,
|
|
155
|
-
stop,
|
|
156
|
-
regenerate
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
//#endregion
|
|
160
|
-
export { foldFrame, useChat };
|
|
161
|
-
|
|
162
|
-
//# sourceMappingURL=use-chat.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-chat.js","names":[],"sources":["../../../resources/js/chat/hooks/use-chat.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport { ndjsonChatTransport } from \"@lattice-php/lattice/chat/lib/transport\";\nimport type {\n ChatFrame,\n ChatMessage,\n ChatStatus,\n ChatTransport,\n UseChatReturn,\n} from \"@lattice-php/lattice/chat/types\";\n\nexport type UseChatOptions = {\n endpoint: string;\n transport?: ChatTransport;\n initialMessages?: ChatMessage[];\n generateId?: () => string;\n};\n\nlet idCounter = 0;\n\nfunction defaultGenerateId(): string {\n idCounter += 1;\n\n return `chat-${idCounter}`;\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof DOMException && error.name === \"AbortError\";\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction lastIsAssistant(messages: ChatMessage[]): boolean {\n const last = messages.at(-1);\n\n return last !== undefined && last.role === \"assistant\";\n}\n\n/**\n * Pure reducer for a single streamed frame: a `text` frame appends to the open\n * assistant text part (opening one if the last part is not text); a `part` frame\n * pushes a complete part, which closes the open text part. Operates immutably on\n * the last assistant message.\n */\nexport function foldFrame(messages: ChatMessage[], frame: ChatFrame): ChatMessage[] {\n if (!lastIsAssistant(messages)) {\n return messages;\n }\n\n const index = messages.length - 1;\n const target = messages[index];\n\n if (frame.type === \"text\") {\n const parts = [...target.parts];\n const openIndex = parts.length - 1;\n const open = parts[openIndex];\n\n if (open !== undefined && open.type === \"chat.part.text\") {\n const openText = (open.props as { text: string }).text;\n parts[openIndex] = { type: \"chat.part.text\", props: { text: `${openText}${frame.value}` } };\n } else {\n parts.push({ type: \"chat.part.text\", props: { text: frame.value } });\n }\n\n const next = [...messages];\n next[index] = { ...target, parts };\n\n return next;\n }\n\n if (frame.type === \"part\") {\n const next = [...messages];\n next[index] = { ...target, parts: [...target.parts, frame.part] };\n\n return next;\n }\n\n return messages;\n}\n\nexport function useChat({\n endpoint,\n transport = ndjsonChatTransport,\n initialMessages = [],\n generateId = defaultGenerateId,\n}: UseChatOptions): UseChatReturn {\n const [messages, setMessagesState] = useState<ChatMessage[]>(initialMessages);\n const [status, setStatus] = useState<ChatStatus>(\"idle\");\n const [error, setError] = useState<string | null>(null);\n\n const abortRef = useRef<AbortController | null>(null);\n const lastUserTextRef = useRef<string | null>(null);\n const messagesRef = useRef<ChatMessage[]>(messages);\n messagesRef.current = messages;\n\n const commitMessages = useCallback((next: ChatMessage[]): void => {\n messagesRef.current = next;\n setMessagesState(next);\n }, []);\n\n const runTurn = useCallback(\n async (history: ChatMessage[], userText: string): Promise<void> => {\n abortRef.current?.abort();\n const controller = new AbortController();\n abortRef.current = controller;\n\n setError(null);\n setStatus(\"submitted\");\n\n const userMessage: ChatMessage = {\n id: generateId(),\n role: \"user\",\n parts: [{ type: \"chat.part.text\", props: { text: userText } }],\n };\n const assistantMessage: ChatMessage = { id: generateId(), role: \"assistant\", parts: [] };\n commitMessages([...history, userMessage, assistantMessage]);\n setStatus(\"streaming\");\n\n try {\n for await (const frame of transport({\n url: endpoint,\n body: { message: userText },\n signal: controller.signal,\n })) {\n if (frame.type === \"done\") {\n setStatus(\"idle\");\n continue;\n }\n\n if (frame.type === \"error\") {\n setError(frame.message ?? \"Chat failed\");\n setStatus(\"error\");\n continue;\n }\n\n commitMessages(foldFrame(messagesRef.current, frame));\n }\n\n setStatus((current) =>\n current === \"streaming\" || current === \"submitted\" ? \"idle\" : current,\n );\n } catch (caught) {\n if (isAbortError(caught)) {\n setStatus(\"idle\");\n\n return;\n }\n\n setError(errorMessage(caught));\n setStatus(\"error\");\n }\n },\n [commitMessages, endpoint, generateId, transport],\n );\n\n const sendMessage = useCallback(\n (text: string): void => {\n const trimmed = text.trim();\n if (trimmed === \"\") {\n return;\n }\n\n lastUserTextRef.current = trimmed;\n void runTurn(messagesRef.current, trimmed);\n },\n [runTurn],\n );\n\n const stop = useCallback((): void => {\n abortRef.current?.abort();\n setStatus(\"idle\");\n }, []);\n\n const regenerate = useCallback((): void => {\n const userText = lastUserTextRef.current;\n if (userText === null) {\n return;\n }\n\n const current = messagesRef.current;\n const history = lastIsAssistant(current) ? current.slice(0, -2) : current;\n void runTurn(history, userText);\n }, [runTurn]);\n\n useEffect(() => {\n return () => {\n abortRef.current?.abort();\n };\n }, []);\n\n return { messages, status, error, sendMessage, setMessages: commitMessages, stop, regenerate };\n}\n"],"mappings":"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"}
|
package/dist/chat/index.d.ts
DELETED
package/dist/chat/index.js
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { RemoteAccess } from '@lattice-php/core/api';
|
|
2
|
-
import { ChatFrame, ChatTransportRequest } from '../types.js';
|
|
3
|
-
export declare const ndjsonChatTransport: (request: ChatTransportRequest) => AsyncGenerator<ChatFrame>;
|
|
4
|
-
export declare function createRemoteNdjsonChatTransport(remote: RemoteAccess): (request: ChatTransportRequest) => AsyncGenerator<ChatFrame>;
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { apiFetch, remoteFetch } from "@lattice-php/core/api";
|
|
2
|
-
//#region resources/js/chat/lib/transport.ts
|
|
3
|
-
function parseFrame(line) {
|
|
4
|
-
try {
|
|
5
|
-
return JSON.parse(line);
|
|
6
|
-
} catch {
|
|
7
|
-
return null;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
function ndjsonTransport(fetchResponse) {
|
|
11
|
-
return async function* transport(request) {
|
|
12
|
-
const res = await fetchResponse(request);
|
|
13
|
-
if (!res.ok || !res.body) throw new Error(`Chat stream failed (${res.status})`);
|
|
14
|
-
yield* readNdjsonFrames(res.body);
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
var ndjsonChatTransport = ndjsonTransport(({ url, body, signal }) => apiFetch(url, {
|
|
18
|
-
method: "POST",
|
|
19
|
-
signal,
|
|
20
|
-
headers: { Accept: "application/x-ndjson" },
|
|
21
|
-
body: JSON.stringify(body),
|
|
22
|
-
throwOnError: false
|
|
23
|
-
}));
|
|
24
|
-
function createRemoteNdjsonChatTransport(remote) {
|
|
25
|
-
return ndjsonTransport(({ url, body, signal }) => remoteFetch(url, {
|
|
26
|
-
remote,
|
|
27
|
-
method: "POST",
|
|
28
|
-
signal,
|
|
29
|
-
headers: {
|
|
30
|
-
Accept: "application/x-ndjson",
|
|
31
|
-
"Content-Type": "application/json"
|
|
32
|
-
},
|
|
33
|
-
body: JSON.stringify(body),
|
|
34
|
-
throwOnError: false
|
|
35
|
-
}));
|
|
36
|
-
}
|
|
37
|
-
async function* readNdjsonFrames(body) {
|
|
38
|
-
const reader = body.getReader();
|
|
39
|
-
const decoder = new TextDecoder();
|
|
40
|
-
let buffer = "";
|
|
41
|
-
try {
|
|
42
|
-
for (;;) {
|
|
43
|
-
const { done, value } = await reader.read();
|
|
44
|
-
if (done) break;
|
|
45
|
-
buffer += decoder.decode(value, { stream: true });
|
|
46
|
-
const lines = buffer.split("\n");
|
|
47
|
-
buffer = lines.pop() ?? "";
|
|
48
|
-
for (const line of lines) {
|
|
49
|
-
if (line.trim() === "") continue;
|
|
50
|
-
const frame = parseFrame(line);
|
|
51
|
-
if (frame) yield frame;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
buffer += decoder.decode();
|
|
55
|
-
if (buffer.trim() !== "") {
|
|
56
|
-
const frame = parseFrame(buffer);
|
|
57
|
-
if (frame) yield frame;
|
|
58
|
-
}
|
|
59
|
-
} finally {
|
|
60
|
-
await reader.cancel().catch(() => {});
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
//#endregion
|
|
64
|
-
export { createRemoteNdjsonChatTransport, ndjsonChatTransport };
|
|
65
|
-
|
|
66
|
-
//# sourceMappingURL=transport.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"transport.js","names":[],"sources":["../../../resources/js/chat/lib/transport.ts"],"sourcesContent":["import { apiFetch, remoteFetch, type RemoteAccess } from \"@lattice-php/core/api\";\nimport type { ChatFrame, ChatTransportRequest } from \"@lattice-php/lattice/chat/types\";\n\nfunction parseFrame(line: string): ChatFrame | null {\n try {\n return JSON.parse(line) as ChatFrame;\n } catch {\n return null;\n }\n}\n\nfunction ndjsonTransport(fetchResponse: (request: ChatTransportRequest) => Promise<Response>) {\n return async function* transport(request: ChatTransportRequest): AsyncGenerator<ChatFrame> {\n const res = await fetchResponse(request);\n\n if (!res.ok || !res.body) {\n throw new Error(`Chat stream failed (${res.status})`);\n }\n\n yield* readNdjsonFrames(res.body);\n };\n}\n\nexport const ndjsonChatTransport = ndjsonTransport(({ url, body, signal }) =>\n apiFetch(url, {\n method: \"POST\",\n signal,\n headers: { Accept: \"application/x-ndjson\" },\n body: JSON.stringify(body),\n throwOnError: false,\n }),\n);\n\nexport function createRemoteNdjsonChatTransport(remote: RemoteAccess) {\n return ndjsonTransport(({ url, body, signal }) =>\n remoteFetch(url, {\n remote,\n method: \"POST\",\n signal,\n headers: {\n Accept: \"application/x-ndjson\",\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n throwOnError: false,\n }),\n );\n}\n\nasync function* readNdjsonFrames(body: ReadableStream<Uint8Array>): AsyncGenerator<ChatFrame> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) {\n break;\n }\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const line of lines) {\n if (line.trim() === \"\") {\n continue;\n }\n\n const frame = parseFrame(line);\n if (frame) {\n yield frame;\n }\n }\n }\n\n buffer += decoder.decode();\n if (buffer.trim() !== \"\") {\n const frame = parseFrame(buffer);\n if (frame) {\n yield frame;\n }\n }\n } finally {\n await reader.cancel().catch(() => {});\n }\n}\n"],"mappings":";;AAGA,SAAS,WAAW,MAAgC;CAClD,IAAI;EACF,OAAO,KAAK,MAAM,IAAI;CACxB,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,gBAAgB,eAAqE;CAC5F,OAAO,gBAAgB,UAAU,SAA0D;EACzF,MAAM,MAAM,MAAM,cAAc,OAAO;EAEvC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,MAClB,MAAM,IAAI,MAAM,uBAAuB,IAAI,OAAO,EAAE;EAGtD,OAAO,iBAAiB,IAAI,IAAI;CAClC;AACF;AAEA,IAAa,sBAAsB,iBAAiB,EAAE,KAAK,MAAM,aAC/D,SAAS,KAAK;CACZ,QAAQ;CACR;CACA,SAAS,EAAE,QAAQ,uBAAuB;CAC1C,MAAM,KAAK,UAAU,IAAI;CACzB,cAAc;AAChB,CAAC,CACH;AAEA,SAAgB,gCAAgC,QAAsB;CACpE,OAAO,iBAAiB,EAAE,KAAK,MAAM,aACnC,YAAY,KAAK;EACf;EACA,QAAQ;EACR;EACA,SAAS;GACP,QAAQ;GACR,gBAAgB;EAClB;EACA,MAAM,KAAK,UAAU,IAAI;EACzB,cAAc;CAChB,CAAC,CACH;AACF;AAEA,gBAAgB,iBAAiB,MAA6D;CAC5F,MAAM,SAAS,KAAK,UAAU;CAC9B,MAAM,UAAU,IAAI,YAAY;CAChC,IAAI,SAAS;CAEb,IAAI;EACF,SAAS;GACP,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,KAAK;GAC1C,IAAI,MACF;GAGF,UAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;GAChD,MAAM,QAAQ,OAAO,MAAM,IAAI;GAC/B,SAAS,MAAM,IAAI,KAAK;GAExB,KAAK,MAAM,QAAQ,OAAO;IACxB,IAAI,KAAK,KAAK,MAAM,IAClB;IAGF,MAAM,QAAQ,WAAW,IAAI;IAC7B,IAAI,OACF,MAAM;GAEV;EACF;EAEA,UAAU,QAAQ,OAAO;EACzB,IAAI,OAAO,KAAK,MAAM,IAAI;GACxB,MAAM,QAAQ,WAAW,MAAM;GAC/B,IAAI,OACF,MAAM;EAEV;CACF,UAAU;EACR,MAAM,OAAO,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC;CACtC;AACF"}
|
package/dist/chat/parts/text.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
//#region resources/js/chat/parts/text.tsx
|
|
3
|
-
var TextPart = ({ node }) => {
|
|
4
|
-
return /* @__PURE__ */ jsx("div", {
|
|
5
|
-
className: "whitespace-pre-wrap text-sm",
|
|
6
|
-
children: node.props.text
|
|
7
|
-
});
|
|
8
|
-
};
|
|
9
|
-
//#endregion
|
|
10
|
-
export { TextPart, TextPart as default };
|
|
11
|
-
|
|
12
|
-
//# sourceMappingURL=text.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","names":[],"sources":["../../../resources/js/chat/parts/text.tsx"],"sourcesContent":["import type { RendererComponent } from \"@lattice-php/core/types\";\n\nexport const TextPart: RendererComponent<\"chat.part.text\"> = ({ node }) => {\n return <div className=\"whitespace-pre-wrap text-sm\">{node.props.text}</div>;\n};\n\nexport default TextPart;\n"],"mappings":";;AAEA,IAAa,YAAiD,EAAE,WAAW;CACzE,OAAO,oBAAC,OAAD;EAAK,WAAU;EAA+B,UAAA,KAAK,MAAM;CAAU,CAAA;AAC5E"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { testIdentity } from "@lattice-php/core/test-id";
|
|
3
|
-
//#region resources/js/chat/parts/tool-call.tsx
|
|
4
|
-
var ToolCallPart = ({ node }) => {
|
|
5
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
6
|
-
className: "mt-1 inline-flex items-center gap-1 rounded-lt-sm bg-lt-muted px-2 py-0.5 font-mono text-xs text-lt-muted-fg",
|
|
7
|
-
"data-test": testIdentity("chat-tool-call"),
|
|
8
|
-
children: [
|
|
9
|
-
"🔧 ",
|
|
10
|
-
node.props.name,
|
|
11
|
-
"(",
|
|
12
|
-
JSON.stringify(node.props.args),
|
|
13
|
-
")"
|
|
14
|
-
]
|
|
15
|
-
});
|
|
16
|
-
};
|
|
17
|
-
//#endregion
|
|
18
|
-
export { ToolCallPart, ToolCallPart as default };
|
|
19
|
-
|
|
20
|
-
//# sourceMappingURL=tool-call.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tool-call.js","names":[],"sources":["../../../resources/js/chat/parts/tool-call.tsx"],"sourcesContent":["import { testIdentity } from \"@lattice-php/core/test-id\";\nimport type { RendererComponent } from \"@lattice-php/core/types\";\n\nexport const ToolCallPart: RendererComponent<\"chat.part.tool-call\"> = ({ node }) => {\n return (\n <div\n className=\"mt-1 inline-flex items-center gap-1 rounded-lt-sm bg-lt-muted px-2 py-0.5 font-mono text-xs text-lt-muted-fg\"\n data-test={testIdentity(\"chat-tool-call\")}\n >\n 🔧 {node.props.name}({JSON.stringify(node.props.args)})\n </div>\n );\n};\n\nexport default ToolCallPart;\n"],"mappings":";;;AAGA,IAAa,gBAA0D,EAAE,WAAW;CAClF,OACE,qBAAC,OAAD;EACE,WAAU;EACV,aAAW,aAAa,gBAAgB;EAF1C,UAAA;GAGC;GACK,KAAK,MAAM;GAAK;GAAE,KAAK,UAAU,KAAK,MAAM,IAAI;GAAE;EACnD;;AAET"}
|
package/dist/chat/plugin.d.ts
DELETED
package/dist/chat/plugin.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { ChatBox } from "./components/chat-box.js";
|
|
2
|
-
import { TextPart } from "./parts/text.js";
|
|
3
|
-
import { ToolCallPart } from "./parts/tool-call.js";
|
|
4
|
-
import { eagerComponent } from "@lattice-php/core/registry";
|
|
5
|
-
//#region resources/js/chat/plugin.ts
|
|
6
|
-
var chatComponents = {
|
|
7
|
-
name: "lattice/chat",
|
|
8
|
-
components: {
|
|
9
|
-
"chat.box": eagerComponent(ChatBox),
|
|
10
|
-
"chat.part.text": eagerComponent(TextPart),
|
|
11
|
-
"chat.part.tool-call": eagerComponent(ToolCallPart)
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
//#endregion
|
|
15
|
-
export { chatComponents };
|
|
16
|
-
|
|
17
|
-
//# sourceMappingURL=plugin.js.map
|
package/dist/chat/plugin.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","names":[],"sources":["../../resources/js/chat/plugin.ts"],"sourcesContent":["import { eagerComponent, type ComponentRegistryFor, type Plugin } from \"@lattice-php/core/registry\";\nimport ChatBoxComponent from \"./components/chat-box\";\nimport { TextPart } from \"./parts/text\";\nimport type { ChatNodeType } from \"@lattice-php/lattice/types/generated\";\nimport { ToolCallPart } from \"./parts/tool-call\";\n\nexport const chatComponents: Plugin = {\n name: \"lattice/chat\",\n components: {\n \"chat.box\": eagerComponent(ChatBoxComponent),\n \"chat.part.text\": eagerComponent(TextPart),\n \"chat.part.tool-call\": eagerComponent(ToolCallPart),\n } satisfies ComponentRegistryFor<ChatNodeType>,\n};\n"],"mappings":";;;;;AAMA,IAAa,iBAAyB;CACpC,MAAM;CACN,YAAY;EACV,YAAY,eAAe,OAAgB;EAC3C,kBAAkB,eAAe,QAAQ;EACzC,uBAAuB,eAAe,YAAY;CACpD;AACF"}
|
package/dist/chat/types.d.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { Node } from '@lattice-php/core/types';
|
|
2
|
-
import { ChatMessage, ChatRole } from '../types/generated.js';
|
|
3
|
-
export type { ChatMessage, ChatRole };
|
|
4
|
-
export type ChatStatus = "idle" | "submitted" | "streaming" | "error";
|
|
5
|
-
export type ChatFrame = {
|
|
6
|
-
type: "text";
|
|
7
|
-
value: string;
|
|
8
|
-
} | {
|
|
9
|
-
type: "part";
|
|
10
|
-
part: Node;
|
|
11
|
-
} | {
|
|
12
|
-
type: "done";
|
|
13
|
-
} | {
|
|
14
|
-
type: "error";
|
|
15
|
-
message?: string;
|
|
16
|
-
};
|
|
17
|
-
export type ChatTransportRequest = {
|
|
18
|
-
url: string;
|
|
19
|
-
body: unknown;
|
|
20
|
-
signal: AbortSignal;
|
|
21
|
-
};
|
|
22
|
-
export type ChatTransport = (request: ChatTransportRequest) => AsyncGenerator<ChatFrame>;
|
|
23
|
-
export type UseChatReturn = {
|
|
24
|
-
messages: ChatMessage[];
|
|
25
|
-
status: ChatStatus;
|
|
26
|
-
error: string | null;
|
|
27
|
-
sendMessage: (text: string) => void;
|
|
28
|
-
setMessages: (messages: ChatMessage[]) => void;
|
|
29
|
-
stop: () => void;
|
|
30
|
-
regenerate: () => void;
|
|
31
|
-
};
|
package/dist/chat/types.js
DELETED
|
File without changes
|