mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-12 01:02:39 +02:00
229 lines
8.1 KiB
TypeScript
229 lines
8.1 KiB
TypeScript
"use client";
|
|
|
|
import dynamic from "next/dynamic";
|
|
import type { TimelineToolComponent } from "./types";
|
|
|
|
// Dynamic imports keep the per-tool UI bundles out of the main chunk —
|
|
// each component only loads when an assistant turn references it. Mirrors
|
|
// the existing ``components/assistant-ui/assistant-message.tsx`` pattern.
|
|
//
|
|
// Phase A note: the imported components are still typed as
|
|
// ``ToolCallMessagePartComponent`` from assistant-ui; the cast at the
|
|
// bottom of this file bridges the contract until the cutover commit
|
|
// retypes them to ``TimelineToolComponent``. The cast is a structural
|
|
// no-op — every consumed prop overlaps.
|
|
|
|
const UpdateMemoryToolUI = dynamic(
|
|
() => import("@/components/tool-ui/user-memory").then((m) => ({ default: m.UpdateMemoryToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const SandboxExecuteToolUI = dynamic(
|
|
() =>
|
|
import("@/components/tool-ui/sandbox-execute").then((m) => ({
|
|
default: m.SandboxExecuteToolUI,
|
|
})),
|
|
{ ssr: false }
|
|
);
|
|
const CreateNotionPageToolUI = dynamic(
|
|
() => import("@/components/tool-ui/notion").then((m) => ({ default: m.CreateNotionPageToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const UpdateNotionPageToolUI = dynamic(
|
|
() => import("@/components/tool-ui/notion").then((m) => ({ default: m.UpdateNotionPageToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const DeleteNotionPageToolUI = dynamic(
|
|
() => import("@/components/tool-ui/notion").then((m) => ({ default: m.DeleteNotionPageToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const CreateLinearIssueToolUI = dynamic(
|
|
() => import("@/components/tool-ui/linear").then((m) => ({ default: m.CreateLinearIssueToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const UpdateLinearIssueToolUI = dynamic(
|
|
() => import("@/components/tool-ui/linear").then((m) => ({ default: m.UpdateLinearIssueToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const DeleteLinearIssueToolUI = dynamic(
|
|
() => import("@/components/tool-ui/linear").then((m) => ({ default: m.DeleteLinearIssueToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const CreateGoogleDriveFileToolUI = dynamic(
|
|
() =>
|
|
import("@/components/tool-ui/google-drive").then((m) => ({
|
|
default: m.CreateGoogleDriveFileToolUI,
|
|
})),
|
|
{ ssr: false }
|
|
);
|
|
const DeleteGoogleDriveFileToolUI = dynamic(
|
|
() =>
|
|
import("@/components/tool-ui/google-drive").then((m) => ({
|
|
default: m.DeleteGoogleDriveFileToolUI,
|
|
})),
|
|
{ ssr: false }
|
|
);
|
|
const CreateOneDriveFileToolUI = dynamic(
|
|
() =>
|
|
import("@/components/tool-ui/onedrive").then((m) => ({ default: m.CreateOneDriveFileToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const DeleteOneDriveFileToolUI = dynamic(
|
|
() =>
|
|
import("@/components/tool-ui/onedrive").then((m) => ({ default: m.DeleteOneDriveFileToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const CreateDropboxFileToolUI = dynamic(
|
|
() =>
|
|
import("@/components/tool-ui/dropbox").then((m) => ({ default: m.CreateDropboxFileToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const DeleteDropboxFileToolUI = dynamic(
|
|
() =>
|
|
import("@/components/tool-ui/dropbox").then((m) => ({ default: m.DeleteDropboxFileToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const CreateCalendarEventToolUI = dynamic(
|
|
() =>
|
|
import("@/components/tool-ui/google-calendar").then((m) => ({
|
|
default: m.CreateCalendarEventToolUI,
|
|
})),
|
|
{ ssr: false }
|
|
);
|
|
const UpdateCalendarEventToolUI = dynamic(
|
|
() =>
|
|
import("@/components/tool-ui/google-calendar").then((m) => ({
|
|
default: m.UpdateCalendarEventToolUI,
|
|
})),
|
|
{ ssr: false }
|
|
);
|
|
const DeleteCalendarEventToolUI = dynamic(
|
|
() =>
|
|
import("@/components/tool-ui/google-calendar").then((m) => ({
|
|
default: m.DeleteCalendarEventToolUI,
|
|
})),
|
|
{ ssr: false }
|
|
);
|
|
const CreateGmailDraftToolUI = dynamic(
|
|
() => import("@/components/tool-ui/gmail").then((m) => ({ default: m.CreateGmailDraftToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const UpdateGmailDraftToolUI = dynamic(
|
|
() => import("@/components/tool-ui/gmail").then((m) => ({ default: m.UpdateGmailDraftToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const SendGmailEmailToolUI = dynamic(
|
|
() => import("@/components/tool-ui/gmail").then((m) => ({ default: m.SendGmailEmailToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const TrashGmailEmailToolUI = dynamic(
|
|
() => import("@/components/tool-ui/gmail").then((m) => ({ default: m.TrashGmailEmailToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const CreateJiraIssueToolUI = dynamic(
|
|
() => import("@/components/tool-ui/jira").then((m) => ({ default: m.CreateJiraIssueToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const UpdateJiraIssueToolUI = dynamic(
|
|
() => import("@/components/tool-ui/jira").then((m) => ({ default: m.UpdateJiraIssueToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const DeleteJiraIssueToolUI = dynamic(
|
|
() => import("@/components/tool-ui/jira").then((m) => ({ default: m.DeleteJiraIssueToolUI })),
|
|
{ ssr: false }
|
|
);
|
|
const CreateConfluencePageToolUI = dynamic(
|
|
() =>
|
|
import("@/components/tool-ui/confluence").then((m) => ({
|
|
default: m.CreateConfluencePageToolUI,
|
|
})),
|
|
{ ssr: false }
|
|
);
|
|
const UpdateConfluencePageToolUI = dynamic(
|
|
() =>
|
|
import("@/components/tool-ui/confluence").then((m) => ({
|
|
default: m.UpdateConfluencePageToolUI,
|
|
})),
|
|
{ ssr: false }
|
|
);
|
|
const DeleteConfluencePageToolUI = dynamic(
|
|
() =>
|
|
import("@/components/tool-ui/confluence").then((m) => ({
|
|
default: m.DeleteConfluencePageToolUI,
|
|
})),
|
|
{ ssr: false }
|
|
);
|
|
|
|
/**
|
|
* Headers-only tools — the timeline shows their ``ItemHeader`` (title +
|
|
* sub-bullets) but mounts no tool body beneath. Two reasons to use
|
|
* this:
|
|
* - **Structural primitives** (``task``): the row IS the parent of a
|
|
* delegation span; its job is to label the group. Children render
|
|
* as their own indented entries.
|
|
* - **Suppressed connectors** (``web_search``, ``link_preview``,
|
|
* ``multi_link_preview``, ``scrape_webpage``): citations they
|
|
* produce render inline in markdown; a separate card would be
|
|
* redundant noise.
|
|
*/
|
|
const NullTimelineBody: TimelineToolComponent = () => null;
|
|
|
|
/**
|
|
* The timeline's tool-name → component map. Mounted by
|
|
* ``timeline/items/tool-call-item.tsx`` via ``getToolComponent(name)``.
|
|
*
|
|
* Includes only "process" tools (connector CRUD, sandbox execute,
|
|
* memory updates) and the 4 invisible tools mapped to a null component.
|
|
* Deliverables (``generate_report``, ``generate_resume``,
|
|
* ``generate_podcast``, ``generate_video_presentation``,
|
|
* ``display_image``, ``generate_image``) live in ``BODY_TOOLS`` in
|
|
* ``assistant-message.tsx`` — they're product, not process.
|
|
*
|
|
* Tools NOT in this map fall through to ``FallbackToolBody`` (which
|
|
* itself dispatches between HITL approval cards and
|
|
* ``DefaultFallbackCard`` based on result discrimination).
|
|
*/
|
|
const TOOLS_BY_NAME = {
|
|
task: NullTimelineBody,
|
|
update_memory: UpdateMemoryToolUI,
|
|
execute: SandboxExecuteToolUI,
|
|
execute_code: SandboxExecuteToolUI,
|
|
create_notion_page: CreateNotionPageToolUI,
|
|
update_notion_page: UpdateNotionPageToolUI,
|
|
delete_notion_page: DeleteNotionPageToolUI,
|
|
create_linear_issue: CreateLinearIssueToolUI,
|
|
update_linear_issue: UpdateLinearIssueToolUI,
|
|
delete_linear_issue: DeleteLinearIssueToolUI,
|
|
create_google_drive_file: CreateGoogleDriveFileToolUI,
|
|
delete_google_drive_file: DeleteGoogleDriveFileToolUI,
|
|
create_onedrive_file: CreateOneDriveFileToolUI,
|
|
delete_onedrive_file: DeleteOneDriveFileToolUI,
|
|
create_dropbox_file: CreateDropboxFileToolUI,
|
|
delete_dropbox_file: DeleteDropboxFileToolUI,
|
|
create_calendar_event: CreateCalendarEventToolUI,
|
|
update_calendar_event: UpdateCalendarEventToolUI,
|
|
delete_calendar_event: DeleteCalendarEventToolUI,
|
|
create_gmail_draft: CreateGmailDraftToolUI,
|
|
update_gmail_draft: UpdateGmailDraftToolUI,
|
|
send_gmail_email: SendGmailEmailToolUI,
|
|
trash_gmail_email: TrashGmailEmailToolUI,
|
|
create_jira_issue: CreateJiraIssueToolUI,
|
|
update_jira_issue: UpdateJiraIssueToolUI,
|
|
delete_jira_issue: DeleteJiraIssueToolUI,
|
|
create_confluence_page: CreateConfluencePageToolUI,
|
|
update_confluence_page: UpdateConfluencePageToolUI,
|
|
delete_confluence_page: DeleteConfluencePageToolUI,
|
|
web_search: NullTimelineBody,
|
|
link_preview: NullTimelineBody,
|
|
multi_link_preview: NullTimelineBody,
|
|
scrape_webpage: NullTimelineBody,
|
|
} as unknown as Record<string, TimelineToolComponent>;
|
|
|
|
/**
|
|
* Lookup a tool component by name. Returns ``undefined`` for unknown
|
|
* tools so the caller can mount ``FallbackToolBody`` instead.
|
|
*/
|
|
export function getToolComponent(toolName: string): TimelineToolComponent | undefined {
|
|
return TOOLS_BY_NAME[toolName];
|
|
}
|
|
|
|
export const TIMELINE_TOOL_NAMES = Object.keys(TOOLS_BY_NAME) as readonly string[];
|