///
import {
BuiltInLLMMessage,
Cell,
computed,
Default,
handler,
ifElse,
JSONSchema,
NAME,
navigateTo,
OpaqueRef,
pattern,
UI,
wish,
} from "commontools";
import Chat from "../chatbot.tsx";
import { MentionableCharm } from "../system/backlinks-index.tsx";
type Charm = any;
type OutlinerNode = {
body: Default;
children: Default;
attachments: Default[], []>;
};
type Outliner = {
root: OutlinerNode;
};
type PageResult = {
outline: Default<
Outliner,
{ root: { body: ""; children: []; attachments: [] } }
>;
};
export type PageInput = {
outline: Outliner;
};
const handleCharmLinkClick = handler<
{
detail: {
charm: Cell;
};
},
Record
>(({ detail }, _) => {
return navigateTo(detail.charm);
});
function getMentionable() {
const mentionable = wish("#mentionable");
return computed(() => mentionable);
}
export const Page = pattern(({ outline }) => {
const mentionable = getMentionable();
return {
[NAME]: "Page",
[UI]: (
),
outline,
};
});
type LLMTestInput = {
title?: Cell>;
messages?: Cell, []>>;
expandChat?: Cell>;
outline?: Default<
Outliner,
{ root: { body: "Untitled Page"; children: []; attachments: [] } }
>;
};
type LLMTestResult = {
messages: Default, []>;
};
// put a node at the end of the outline (by appending to root.children)
const appendOutlinerNode = handler<
{
/** The text content/title of the outliner node to be appended */
body: string;
/** A cell to store the result message indicating success or error */
result: Cell;
},
{ outline: Cell }
>(
(args, state) => {
try {
(state.outline.key("root").key("children")).push({
body: args.body,
children: [],
attachments: [],
});
args.result.set(
`${state.outline.key("root").key("children").get().length} nodes`,
);
} catch (error) {
args.result.set(`Error: ${(error as any)?.message || ""}`);
}
},
);
export default pattern(
({ title, expandChat, messages, outline }) => {
const tools = {
appendOutlinerNode: {
description: "Add a new outliner node.",
inputSchema: {
type: "object",
properties: {
body: {
type: "string",
description: "The title of the new node.",
},
},
required: ["body"],
} as JSONSchema,
handler: appendOutlinerNode({ outline }),
},
};
const chat = Chat({ messages, tools });
return {
[NAME]: title,
[UI]: (
Show Chat
{ifElse(
expandChat,
chat,
null,
)}
),
messages,
};
},
);