@itechchoice/prime-chatkit 0.1.0-alpha.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.
Files changed (45) hide show
  1. package/dist/index.js +10017 -0
  2. package/dist/style.css +1 -0
  3. package/dist/types/adapters/bff/client.d.ts +189 -0
  4. package/dist/types/adapters/bff/controller.d.ts +70 -0
  5. package/dist/types/components/ui/agent-trail-clean.d.ts +63 -0
  6. package/dist/types/components/ui/ai-answer-clean.d.ts +76 -0
  7. package/dist/types/components/ui/approval-card-clean.d.ts +54 -0
  8. package/dist/types/components/ui/button-clean.d.ts +13 -0
  9. package/dist/types/components/ui/chat-composer-clean.d.ts +115 -0
  10. package/dist/types/components/ui/collaboration-stream-clean.d.ts +98 -0
  11. package/dist/types/components/ui/command-menu-clean.d.ts +57 -0
  12. package/dist/types/components/ui/decision-card-clean.d.ts +87 -0
  13. package/dist/types/components/ui/dropzone-clean.d.ts +70 -0
  14. package/dist/types/components/ui/tool-call-card-clean.d.ts +76 -0
  15. package/dist/types/core/history.d.ts +3 -0
  16. package/dist/types/core/run.d.ts +34 -0
  17. package/dist/types/core/scope.d.ts +16 -0
  18. package/dist/types/core/sse.d.ts +12 -0
  19. package/dist/types/core/suspension.d.ts +83 -0
  20. package/dist/types/core/tools.d.ts +15 -0
  21. package/dist/types/core/types.d.ts +152 -0
  22. package/dist/types/index.d.ts +6 -0
  23. package/dist/types/layout/DockShell.d.ts +19 -0
  24. package/dist/types/layout/constants.d.ts +22 -0
  25. package/dist/types/layout/index.d.ts +3 -0
  26. package/dist/types/layout/useLayout.d.ts +52 -0
  27. package/dist/types/provider/PrimeViaChat.d.ts +2 -0
  28. package/dist/types/provider/PrimeViaChatProvider.d.ts +2 -0
  29. package/dist/types/provider/PrimeViaChatShell.d.ts +5 -0
  30. package/dist/types/provider/config.d.ts +92 -0
  31. package/dist/types/provider/context.d.ts +53 -0
  32. package/dist/types/provider/hooks.d.ts +82 -0
  33. package/dist/types/ui/HistoryPanel.d.ts +11 -0
  34. package/dist/types/ui/blocks/BlocksPanel.d.ts +70 -0
  35. package/dist/types/ui/blocks/Process.d.ts +7 -0
  36. package/dist/types/ui/blocks/Questions.d.ts +25 -0
  37. package/dist/types/ui/blocks/SentAttachments.d.ts +11 -0
  38. package/dist/types/ui/blocks/useAttachmentDownload.d.ts +9 -0
  39. package/dist/types/ui/blocks/useAttachments.d.ts +15 -0
  40. package/dist/types/ui/blocks/useFollowLatest.d.ts +20 -0
  41. package/dist/types/ui/history.d.ts +10 -0
  42. package/dist/types/ui/i18n.d.ts +203 -0
  43. package/dist/types/ui/start-icons.d.ts +2 -0
  44. package/dist/types/ui/thread.d.ts +71 -0
  45. package/package.json +52 -0
@@ -0,0 +1,98 @@
1
+ import { type ReactNode } from "react";
2
+ export type StreamKind = "ask" | "reply" | "handoff" | "share" | "question" | "spawn";
3
+ export type StreamAgent = {
4
+ id: string;
5
+ name: string;
6
+ /** The model – shown in the agent's tooltip */
7
+ model?: string;
8
+ /** A small mark instead of its pixel mark, e.g. the model maker's logo */
9
+ avatar?: ReactNode;
10
+ };
11
+ export type StreamAttachment = {
12
+ label: string;
13
+ /** Picks its icon – left out, it's told from the label: "…/" is a folder, ".csv" a table, any other extension a file */
14
+ kind?: "file" | "folder" | "table" | "tool" | "link";
15
+ /** What its preview window shows – a table as CSV, a folder's entries one per line ("…/" for a folder), anything else as text */
16
+ preview?: string;
17
+ /** A short line under its name in the preview, like "4 rows" or "2 KB" */
18
+ meta?: string;
19
+ };
20
+ export type StreamMessage = {
21
+ id: string;
22
+ /** Who speaks – an agent's id, or "you" */
23
+ from: string;
24
+ /** Who it's for – one agent, several, "all" or "you" */
25
+ to: string | string[];
26
+ kind: StreamKind;
27
+ text: string;
28
+ /** When, already formatted – e.g. "14:02" or "2m ago" */
29
+ at?: string;
30
+ /** The message it answers – shown as a quote, a click on it jumps there */
31
+ replyTo?: string;
32
+ /** Still being written – "writing" shimmers and the sender's mark twinkles */
33
+ typing?: boolean;
34
+ attachments?: StreamAttachment[];
35
+ /** What opens under the message when it's clicked: a few facts, and what it used or points to */
36
+ details?: StreamDetails;
37
+ };
38
+ export type StreamDetails = {
39
+ /** Short facts in a row, e.g. { label: "Model", value: "Opus 5.5" }, tokens, cost, time */
40
+ facts?: {
41
+ label: string;
42
+ value: ReactNode;
43
+ }[];
44
+ /** What it used or points to – tools, pages, files – each with an optional logo */
45
+ items?: {
46
+ label: string;
47
+ detail?: string;
48
+ icon?: ReactNode;
49
+ }[];
50
+ };
51
+ export type CollaborationStreamProps = {
52
+ agents: StreamAgent[];
53
+ /** The messages in the order they were sent – a "spawn" message shows as a quiet line */
54
+ messages: StreamMessage[];
55
+ /** What the run is about – shown muted next to the title */
56
+ task?: string;
57
+ /** The run is still going – the stream follows new messages */
58
+ live?: boolean;
59
+ /** Controlled id of the picked message – its details open, the rest fades */
60
+ selected?: string | null;
61
+ onSelectedChange?: (id: string | null) => void;
62
+ /** Controlled id of the agent whose messages are picked out */
63
+ focusAgent?: string | null;
64
+ onFocusAgentChange?: (id: string | null) => void;
65
+ /** The stream scrolls past this height (px) – with a composer it is the stream's fixed height, so the composer never moves */
66
+ maxHeight?: number;
67
+ /** Write into the stream. With it, a composer sits under the stream – "@" names the agents it's for, and a question
68
+ * for you can be answered right from its message */
69
+ onSend?: (message: {
70
+ text: string;
71
+ to: string[];
72
+ replyTo?: string;
73
+ }) => void;
74
+ /** The composer's placeholder */
75
+ placeholder?: string;
76
+ /** Companies or products whose name gets its logo in the text, e.g. { Notion: <NotionLogo />, Stripe: <StripeLogo /> } */
77
+ logos?: Record<string, ReactNode>;
78
+ title?: string;
79
+ className?: string;
80
+ labels?: {
81
+ close?: string;
82
+ noPreview?: (name: string) => string;
83
+ };
84
+ };
85
+ export type PreviewWindowProps = {
86
+ title: string;
87
+ meta?: ReactNode;
88
+ icon?: ReactNode;
89
+ onClose: () => void;
90
+ children: ReactNode;
91
+ placement?: "inside" | "viewport";
92
+ size?: "default" | "large";
93
+ labels?: {
94
+ close?: string;
95
+ };
96
+ };
97
+ export declare function PreviewWindow({ title, meta, icon, onClose, children, placement, size, labels }: PreviewWindowProps): import("react").JSX.Element;
98
+ export declare function CollaborationStream({ agents, messages, task, live, selected: selectedProp, onSelectedChange, focusAgent: focusProp, onFocusAgentChange, maxHeight, logos, onSend, placeholder, title, className, labels, }: CollaborationStreamProps): import("react").JSX.Element;
@@ -0,0 +1,57 @@
1
+ import { type ReactNode } from "react";
2
+ export type Command = {
3
+ id: string;
4
+ label: string;
5
+ /** Lighter text after the label, e.g. a person, a channel or a page */
6
+ hint?: string;
7
+ /** "logo" sits on a small white tile; "icon" is a plain glyph */
8
+ icon?: ReactNode;
9
+ logo?: ReactNode;
10
+ /** Keys shown on the right, e.g. ["G", "I"] – suggestions get ⌘1–⌘5 automatically */
11
+ keys?: string[];
12
+ /** Extra words that should find this command */
13
+ keywords?: string;
14
+ actions?: {
15
+ id: string;
16
+ label: string;
17
+ icon?: ReactNode;
18
+ }[];
19
+ editing?: boolean;
20
+ };
21
+ export type CommandGroup = {
22
+ id: string;
23
+ label: string;
24
+ commands: Command[];
25
+ };
26
+ export type CommandMenuLabels = {
27
+ placeholder: string;
28
+ jumpSections: string;
29
+ open: string;
30
+ assistant: string;
31
+ ask: (query: string) => string;
32
+ asked: (query: string) => string;
33
+ ran: (label: string) => string;
34
+ command: string;
35
+ commands: string;
36
+ };
37
+ export declare const defaultCommandMenuLabels: CommandMenuLabels;
38
+ export type CommandMenuProps = {
39
+ groups?: CommandGroup[];
40
+ placeholder?: string;
41
+ /** Called with the command id; for the assistant fallback with "ask" and the typed text */
42
+ onRun?: (id: string, query?: string) => void;
43
+ /** Runs on Esc in an empty search */
44
+ onClose?: () => void;
45
+ /** Focus the field when the menu appears */
46
+ autoFocus?: boolean;
47
+ className?: string;
48
+ onAction?: (commandId: string, actionId: string) => void;
49
+ onEditSubmit?: (commandId: string, value: string) => void;
50
+ onEditCancel?: (commandId: string) => void;
51
+ ask?: boolean;
52
+ hotkey?: boolean;
53
+ labels?: Partial<CommandMenuLabels>;
54
+ };
55
+ /** Sample commands – replace with your own */
56
+ export declare const defaultGroups: CommandGroup[];
57
+ export declare function CommandMenu({ groups, placeholder, onAction, onEditSubmit, onEditCancel, ask, hotkey, labels: labelOverrides, onRun, onClose, autoFocus, className, }: CommandMenuProps): import("react").JSX.Element;
@@ -0,0 +1,87 @@
1
+ import { type ReactNode } from "react";
2
+ export type DecisionKind = "decision" | "pick" | "approval";
3
+ /** A gray block of a preview tile, on a 120 × 80 grid */
4
+ export type DecisionBlock = {
5
+ x: number;
6
+ y: number;
7
+ w: number;
8
+ h: number;
9
+ r?: number;
10
+ tone?: "ink" | "mid" | "soft";
11
+ };
12
+ export type DecisionOption = {
13
+ id: string;
14
+ title: string;
15
+ /** One line – it ends in … when it doesn't fit */
16
+ summary?: string;
17
+ /** A small gray Recommended tag – the row is also where the focus starts */
18
+ recommended?: boolean;
19
+ /** pick: what the tile shows – your own node, or gray blocks on a 120 × 80 grid */
20
+ preview?: ReactNode;
21
+ blocks?: DecisionBlock[];
22
+ };
23
+ export type Decision = {
24
+ id: string;
25
+ question: string;
26
+ /** The task it belongs to – shown muted in the head */
27
+ task?: string;
28
+ /** decision: rows to pick from · pick: preview tiles · approval: facts, then Approve / Decline (default: decision) */
29
+ kind?: DecisionKind;
30
+ /** decision and pick – all supplied options */
31
+ options?: DecisionOption[];
32
+ own?: boolean;
33
+ multiple?: {
34
+ min?: number;
35
+ max?: number;
36
+ };
37
+ validate?: (text: string) => string | null;
38
+ inputMode?: "text" | "decimal" | "numeric";
39
+ placeholder?: string;
40
+ readOnly?: boolean;
41
+ /** approval – two or three lines of what it will do */
42
+ facts?: {
43
+ label: string;
44
+ value: string;
45
+ }[];
46
+ };
47
+ /** What you answered: an option or your own words – or approve / decline */
48
+ export type DecisionAnswer = {
49
+ option?: string;
50
+ text?: string;
51
+ options?: never;
52
+ } | {
53
+ options: string[];
54
+ option?: never;
55
+ text?: never;
56
+ } | "approve" | "decline";
57
+ export type DecisionCardLabels = {
58
+ needsYou: string;
59
+ later: string;
60
+ show: string;
61
+ recommended: string;
62
+ approve: string;
63
+ decline: string;
64
+ own: string;
65
+ send: string;
66
+ confirm: string;
67
+ answered: string;
68
+ previous: string;
69
+ next: string;
70
+ allDone: string;
71
+ waiting: (n: number) => string;
72
+ of: (i: number, n: number) => string;
73
+ };
74
+ export type DecisionCardProps = {
75
+ /** The open decisions, oldest first – answered ones leave the card at once; drop them from the array in onDecide */
76
+ decisions: Decision[];
77
+ onDecide?: (id: string, answer: DecisionAnswer) => void;
78
+ /** Later or Esc folded the card to one line */
79
+ onLater?: (id: string) => void;
80
+ /** Start folded to "2 decisions waiting · Show" */
81
+ defaultFolded?: boolean;
82
+ /** Change it (e.g. a counter) to bring the card up from elsewhere – it unfolds, pulses gray once and takes the focus */
83
+ reveal?: number;
84
+ labels?: Partial<DecisionCardLabels>;
85
+ className?: string;
86
+ };
87
+ export declare function DecisionCard({ decisions, onDecide, onLater, defaultFolded, reveal, labels, className }: DecisionCardProps): import("react").JSX.Element;
@@ -0,0 +1,70 @@
1
+ export type UploadStatus = "uploading" | "done" | "error";
2
+ export type UploadItem = {
3
+ id: string;
4
+ name: string;
5
+ /** In bytes */
6
+ size: number;
7
+ status: UploadStatus;
8
+ /** 0 to 1 */
9
+ progress: number;
10
+ error?: string;
11
+ /** The real file – missing for the sample files */
12
+ file?: File;
13
+ };
14
+ export type DropzoneProps = {
15
+ labels?: Partial<DropzoneLabels>;
16
+ /** Allowed extensions, e.g. [".pdf", ".png"] – any file when left out */
17
+ accept?: string[];
18
+ /** Largest file in bytes */
19
+ maxSize?: number;
20
+ /** Upload a file and report its progress (0–1); throw to mark it as failed. Simulated when left out */
21
+ onUpload?: (file: File, onProgress: (progress: number) => void) => Promise<void>;
22
+ /** Called whenever the list changes */
23
+ onChange?: (items: UploadItem[]) => void;
24
+ /** Text under the title – defaults to the accepted types and size */
25
+ hint?: string;
26
+ /** Plays a sample drop on its own – nice for previews */
27
+ autoplay?: boolean;
28
+ className?: string;
29
+ };
30
+ export declare const defaultDropzoneLabels: {
31
+ dropFiles: string;
32
+ browse: string;
33
+ tapTo: string;
34
+ chooseFiles: string;
35
+ release: (n: number) => string;
36
+ anyFile: string;
37
+ acceptedTypes: (types: string[]) => string;
38
+ hint: (types: string, size: string) => string;
39
+ unsupportedType: (extension: string) => string;
40
+ tooLarge: (size: string) => string;
41
+ uploadFailed: string;
42
+ connectionLost: string;
43
+ failedAnnouncement: (name: string) => string;
44
+ errorAnnouncement: (name: string, error: string) => string;
45
+ uploadedAnnouncement: (name: string) => string;
46
+ uploading: (n: number, total: number) => string;
47
+ partiallyUploaded: (n: number, total: number) => string;
48
+ allUploaded: (n: number) => string;
49
+ uploads: string;
50
+ uploaded: string;
51
+ noFiles: string;
52
+ clear: string;
53
+ uploadProgress: (name: string) => string;
54
+ retry: (name: string) => string;
55
+ remove: (name: string) => string;
56
+ bytes: string;
57
+ kilobytes: string;
58
+ megabytes: string;
59
+ gigabytes: string;
60
+ sentOf: (sent: string, total: string) => string;
61
+ starting: string;
62
+ almostDone: string;
63
+ secondsLeft: (n: number) => string;
64
+ minutesLeft: (n: number) => string;
65
+ hoursLeft: (n: number) => string;
66
+ daysLeft: (n: number) => string;
67
+ fileBadge: (extension: string) => string;
68
+ };
69
+ export type DropzoneLabels = typeof defaultDropzoneLabels;
70
+ export declare function Dropzone({ labels: labelProp, accept, maxSize, onUpload, onChange, hint, autoplay, className, }: DropzoneProps): import("react").JSX.Element;
@@ -0,0 +1,76 @@
1
+ import { type ReactNode } from "react";
2
+ export type ToolCallStatus = "running" | "success" | "error";
3
+ export declare const defaultToolCallLabels: {
4
+ failed: string;
5
+ error: string;
6
+ retry: string;
7
+ arguments: string;
8
+ result: string;
9
+ waiting: string;
10
+ empty: string;
11
+ showAll: string;
12
+ showLess: string;
13
+ copied: string;
14
+ copyArguments: string;
15
+ copyResult: string;
16
+ running: (name: string) => string;
17
+ finished: (name: string) => string;
18
+ failedAnnouncement: (name: string, error?: string) => string;
19
+ duration: (ms: number, live: boolean) => string;
20
+ usingTools: string;
21
+ usedTools: (n: number) => string;
22
+ failedTools: (n: number) => string;
23
+ groupAnnouncement: (count: string, failed: number) => string;
24
+ };
25
+ export type ToolCallLabels = typeof defaultToolCallLabels;
26
+ export type ToolCallCardLabels = ToolCallLabels;
27
+ export type ToolCallGroupLabels = ToolCallLabels;
28
+ export type ToolCallCardProps = {
29
+ labels?: Partial<ToolCallLabels>;
30
+ /** Tool name as the agent calls it, shown in mono – e.g. "search_web" */
31
+ name: string;
32
+ /** Short human summary – e.g. "Searched the web for 'CRM pricing 2026'" */
33
+ summary?: ReactNode;
34
+ /** Icon in the tile on the left – defaults to a wrench */
35
+ icon?: ReactNode;
36
+ status: ToolCallStatus;
37
+ /** Arguments the tool was called with – objects are pretty-printed, JSON strings parsed */
38
+ args?: unknown;
39
+ /** What the tool returned – objects are pretty-printed, JSON strings parsed, other text shown as is */
40
+ result?: unknown;
41
+ /** Error message, shown when status is "error" */
42
+ error?: string;
43
+ /** When the call started (ms since epoch, e.g. Date.now()) – the live timer counts from here */
44
+ startedAt?: number;
45
+ /** Final duration in ms – otherwise measured while the card shows "running" */
46
+ duration?: number;
47
+ /** Start expanded (uncontrolled) */
48
+ defaultOpen?: boolean;
49
+ /** Expanded state (controlled) */
50
+ open?: boolean;
51
+ onOpenChange?: (open: boolean) => void;
52
+ /** Opens the card when the call fails and closes it again on the next run, unless someone toggled it */
53
+ openOnError?: boolean;
54
+ /** Shows a Retry button next to the error */
55
+ onRetry?: () => void;
56
+ /** Height in px after which arguments and result are capped with a fade and "Show all" */
57
+ maxCodeHeight?: number;
58
+ className?: string;
59
+ };
60
+ export type ToolCallGroupProps = {
61
+ labels?: Partial<ToolCallGroupLabels>;
62
+ /** ToolCallCard elements – the group reads their name, icon, status and duration */
63
+ children: ReactNode;
64
+ /** Label once all calls are done – defaults to "Used 3 tools" */
65
+ label?: string;
66
+ /** Label while any call is running */
67
+ runningLabel?: string;
68
+ /** Total duration in ms – otherwise the sum of the cards' durations, or the time measured while running */
69
+ duration?: number;
70
+ defaultOpen?: boolean;
71
+ open?: boolean;
72
+ onOpenChange?: (open: boolean) => void;
73
+ className?: string;
74
+ };
75
+ export declare function ToolCallCard({ name, summary, icon, status, args, result, error, startedAt, duration, defaultOpen, open: openProp, onOpenChange, openOnError, onRetry, maxCodeHeight, className, labels: labelProp, }: ToolCallCardProps): import("react").JSX.Element;
76
+ export declare function ToolCallGroup({ children, label, runningLabel, duration, defaultOpen, open: openProp, onOpenChange, className, labels: labelProp, }: ToolCallGroupProps): import("react").JSX.Element;
@@ -0,0 +1,3 @@
1
+ import type { ChatMessage } from "./types";
2
+ /** Map a chronological history page without mutating records or consulting the clock. */
3
+ export declare function messagesFromHistory(records: unknown[]): ChatMessage[];
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Pure reducer: prime-chatkit SSE events → Run view model.
3
+ * Event names and fields follow the prime-chatkit SDK 1.0.2 BFF contract (see prime-via docs/abc-prime-chat-frontend-api.md
4
+ * and the captures in demo/fixtures). Unknown events are ignored, never thrown on.
5
+ */
6
+ import type { Run, StreamEvent, Turn } from "./types";
7
+ export declare function num(v: unknown): number | undefined;
8
+ /** Only decimal event ids can participate in replay detection or stream resumption. */
9
+ export declare function eventIdOf(raw: string | undefined): string | undefined;
10
+ /** Decimal-string compare for snowflake ids; never convert to Number */
11
+ export declare function idGreater(a: string, b: string): boolean;
12
+ export declare function createRun(taskId: string, now?: number): Run;
13
+ /** Text the user should read as the answer right now: the confirmed final text, else the newest turn still writing */
14
+ export declare function answerText(run: Run): string;
15
+ export type AnswerSource = {
16
+ label: string;
17
+ href?: string;
18
+ };
19
+ /**
20
+ * The backend appends a "### Sources" section to the final answer (e.g. "### Sources\n\nThaleonmcp").
21
+ * Split it off so the UI can show the sources as badges instead of a heading and a paragraph.
22
+ */
23
+ export declare function splitSources(text: string): {
24
+ body: string;
25
+ sources: AnswerSource[];
26
+ };
27
+ /** Narration of turns that called tools (shown inside the process, not as the answer) */
28
+ export declare function isNarration(run: Run, turn: Turn): boolean;
29
+ export declare function toolCount(run: Run): number;
30
+ export type ApplyResult = {
31
+ run: Run;
32
+ title?: string;
33
+ };
34
+ export declare function applyEvent(run: Run, ev: StreamEvent, now?: number): ApplyResult;
@@ -0,0 +1,16 @@
1
+ export type ChatScopeType = "GLOBAL" | "CLIENT" | "PRODUCT";
2
+ export type ChatScope = {
3
+ scopeType: ChatScopeType;
4
+ scopeId?: string;
5
+ pending?: boolean;
6
+ };
7
+ export declare const CHAT_SCOPE_TYPE: {
8
+ readonly GLOBAL: "GLOBAL";
9
+ readonly CLIENT: "CLIENT";
10
+ readonly PRODUCT: "PRODUCT";
11
+ };
12
+ export declare function scopeKeyOf(scope: ChatScope | null | undefined): string | null;
13
+ export declare function turnIdsOf(scope: ChatScope | null | undefined): {
14
+ clientId?: string;
15
+ productId?: string;
16
+ };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Minimal SSE parser (text/event-stream). Fields may come in any order inside a block; blocks end on a blank line.
3
+ * Used for the live stream and for replaying recorded captures in tests and the demo.
4
+ */
5
+ import type { StreamEvent } from "./types";
6
+ /** Parse a whole recorded stream */
7
+ export declare function parseSse(text: string): StreamEvent[];
8
+ /** Incremental parser: feed chunks, get complete events back */
9
+ export declare function createSseParser(): {
10
+ push(chunk: string): StreamEvent[];
11
+ flush(): StreamEvent[];
12
+ };
@@ -0,0 +1,83 @@
1
+ export type SuspensionIdentity = {
2
+ requestId?: string;
3
+ sessionId?: string;
4
+ checkpointId?: string;
5
+ checkpointDigest?: string;
6
+ };
7
+ export type SuspensionStep = {
8
+ id: string;
9
+ question: string;
10
+ header?: string;
11
+ type: "single" | "multi" | "boolean" | "number" | "text";
12
+ options?: {
13
+ id: string;
14
+ label: string;
15
+ description?: string;
16
+ value?: string | number | boolean;
17
+ }[];
18
+ required: boolean;
19
+ customField?: string;
20
+ integer?: boolean;
21
+ minItems?: number;
22
+ maxItems?: number;
23
+ };
24
+ export type Suspension = {
25
+ kind: "approval";
26
+ id: string;
27
+ taskId: string;
28
+ title?: string;
29
+ toolName?: string;
30
+ capability?: string;
31
+ allowRemember: boolean;
32
+ readOnly?: true;
33
+ actions: string[];
34
+ identity: SuspensionIdentity;
35
+ } | {
36
+ kind: "questions";
37
+ id: string;
38
+ taskId: string;
39
+ title?: string;
40
+ message?: string;
41
+ steps: SuspensionStep[];
42
+ canCancel: boolean;
43
+ actions: string[];
44
+ identity: SuspensionIdentity;
45
+ } | {
46
+ kind: "link";
47
+ id: string;
48
+ taskId: string;
49
+ title?: string;
50
+ message?: string;
51
+ url: string;
52
+ canCancel: boolean;
53
+ actions: string[];
54
+ identity: SuspensionIdentity;
55
+ } | {
56
+ kind: "wait";
57
+ id: string;
58
+ taskId: string;
59
+ title?: string;
60
+ message?: string;
61
+ waitingOn?: string;
62
+ canCancel: boolean;
63
+ actions: string[];
64
+ identity: SuspensionIdentity;
65
+ };
66
+ export type SuspensionAnswer = {
67
+ kind: "approval";
68
+ decision: "approve" | "approve-session" | "reject";
69
+ comment?: string;
70
+ } | {
71
+ kind: "questions";
72
+ values: Record<string, string | string[]>;
73
+ custom?: Record<string, string>;
74
+ };
75
+ /** Read only the active gate; resolved recordings may be explicitly supplied as that gate. */
76
+ export declare function suspensionOf(taskDetail: {
77
+ taskId: string;
78
+ activeSuspension?: unknown;
79
+ }): Suspension | undefined;
80
+ export declare function resumeRequestFor(s: Suspension, a: SuspensionAnswer): {
81
+ action: "APPROVE" | "REJECT" | "SUBMIT";
82
+ payload: Record<string, unknown>;
83
+ };
@@ -0,0 +1,15 @@
1
+ import type { ToolCall } from "./types";
2
+ export declare function toolKind(capabilityType: unknown): ToolCall["kind"];
3
+ export declare function shortName(capability: string, toolName?: unknown): string;
4
+ /** First sentence of an MCP tool description, without the "[MCP:server]" prefix */
5
+ export declare function summaryFromDefinition(def: unknown): string | undefined;
6
+ export declare function parseResult(result: unknown): {
7
+ value?: unknown;
8
+ ok?: boolean;
9
+ error?: string;
10
+ };
11
+ /** History encodes the MCP server in the capability; live events supply explicit identity fields. */
12
+ export declare function toolIdentity(capability: string, capabilityType: unknown, liveIdentity?: {
13
+ name?: unknown;
14
+ server?: unknown;
15
+ }): Pick<ToolCall, "name" | "server" | "kind">;