@steerable/agent-ui 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.
Files changed (104) hide show
  1. package/LICENSE +91 -0
  2. package/README.md +118 -0
  3. package/dist/components/ChatPanel.d.ts +42 -0
  4. package/dist/components/ChatPanel.d.ts.map +1 -0
  5. package/dist/components/ChatPanel.js +46 -0
  6. package/dist/components/ChatPanel.js.map +1 -0
  7. package/dist/components/ChatPanel.stories.d.ts +17 -0
  8. package/dist/components/ChatPanel.stories.d.ts.map +1 -0
  9. package/dist/components/ChatPanel.stories.js +143 -0
  10. package/dist/components/ChatPanel.stories.js.map +1 -0
  11. package/dist/components/MessageList.d.ts +44 -0
  12. package/dist/components/MessageList.d.ts.map +1 -0
  13. package/dist/components/MessageList.js +43 -0
  14. package/dist/components/MessageList.js.map +1 -0
  15. package/dist/components/MessageList.stories.d.ts +12 -0
  16. package/dist/components/MessageList.stories.d.ts.map +1 -0
  17. package/dist/components/MessageList.stories.js +88 -0
  18. package/dist/components/MessageList.stories.js.map +1 -0
  19. package/dist/components/OrchestrationPlanCard.d.ts +32 -0
  20. package/dist/components/OrchestrationPlanCard.d.ts.map +1 -0
  21. package/dist/components/OrchestrationPlanCard.js +48 -0
  22. package/dist/components/OrchestrationPlanCard.js.map +1 -0
  23. package/dist/components/OrchestrationPlanCard.stories.d.ts +12 -0
  24. package/dist/components/OrchestrationPlanCard.stories.d.ts.map +1 -0
  25. package/dist/components/OrchestrationPlanCard.stories.js +84 -0
  26. package/dist/components/OrchestrationPlanCard.stories.js.map +1 -0
  27. package/dist/components/SSEStreamView.d.ts +29 -0
  28. package/dist/components/SSEStreamView.d.ts.map +1 -0
  29. package/dist/components/SSEStreamView.js +78 -0
  30. package/dist/components/SSEStreamView.js.map +1 -0
  31. package/dist/components/SSEStreamView.stories.d.ts +12 -0
  32. package/dist/components/SSEStreamView.stories.d.ts.map +1 -0
  33. package/dist/components/SSEStreamView.stories.js +86 -0
  34. package/dist/components/SSEStreamView.stories.js.map +1 -0
  35. package/dist/components/ToolCallRenderer.d.ts +42 -0
  36. package/dist/components/ToolCallRenderer.d.ts.map +1 -0
  37. package/dist/components/ToolCallRenderer.js +70 -0
  38. package/dist/components/ToolCallRenderer.js.map +1 -0
  39. package/dist/components/ToolCallRenderer.stories.d.ts +13 -0
  40. package/dist/components/ToolCallRenderer.stories.d.ts.map +1 -0
  41. package/dist/components/ToolCallRenderer.stories.js +112 -0
  42. package/dist/components/ToolCallRenderer.stories.js.map +1 -0
  43. package/dist/components/cn.d.ts +7 -0
  44. package/dist/components/cn.d.ts.map +1 -0
  45. package/dist/components/cn.js +9 -0
  46. package/dist/components/cn.js.map +1 -0
  47. package/dist/components/index.d.ts +11 -0
  48. package/dist/components/index.d.ts.map +1 -0
  49. package/dist/components/index.js +6 -0
  50. package/dist/components/index.js.map +1 -0
  51. package/dist/hooks/index.d.ts +7 -0
  52. package/dist/hooks/index.d.ts.map +1 -0
  53. package/dist/hooks/index.js +4 -0
  54. package/dist/hooks/index.js.map +1 -0
  55. package/dist/hooks/useAgentSession.d.ts +56 -0
  56. package/dist/hooks/useAgentSession.d.ts.map +1 -0
  57. package/dist/hooks/useAgentSession.js +128 -0
  58. package/dist/hooks/useAgentSession.js.map +1 -0
  59. package/dist/hooks/useChatStream.d.ts +59 -0
  60. package/dist/hooks/useChatStream.d.ts.map +1 -0
  61. package/dist/hooks/useChatStream.js +251 -0
  62. package/dist/hooks/useChatStream.js.map +1 -0
  63. package/dist/hooks/useToolCallStatus.d.ts +47 -0
  64. package/dist/hooks/useToolCallStatus.d.ts.map +1 -0
  65. package/dist/hooks/useToolCallStatus.js +57 -0
  66. package/dist/hooks/useToolCallStatus.js.map +1 -0
  67. package/dist/index.d.ts +12 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +12 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/tailwind-preset.d.ts +76 -0
  72. package/dist/tailwind-preset.d.ts.map +1 -0
  73. package/dist/tailwind-preset.js +104 -0
  74. package/dist/tailwind-preset.js.map +1 -0
  75. package/package.json +97 -0
  76. package/src/Introduction.mdx +71 -0
  77. package/src/components/ChatPanel.stories.tsx +173 -0
  78. package/src/components/ChatPanel.tsx +188 -0
  79. package/src/components/MessageList.stories.tsx +112 -0
  80. package/src/components/MessageList.test.tsx +57 -0
  81. package/src/components/MessageList.tsx +144 -0
  82. package/src/components/OrchestrationPlanCard.stories.tsx +98 -0
  83. package/src/components/OrchestrationPlanCard.test.tsx +34 -0
  84. package/src/components/OrchestrationPlanCard.tsx +159 -0
  85. package/src/components/SSEStreamView.stories.tsx +99 -0
  86. package/src/components/SSEStreamView.test.tsx +42 -0
  87. package/src/components/SSEStreamView.tsx +155 -0
  88. package/src/components/ToolCallRenderer.stories.tsx +152 -0
  89. package/src/components/ToolCallRenderer.test.tsx +93 -0
  90. package/src/components/ToolCallRenderer.tsx +213 -0
  91. package/src/components/cn.ts +10 -0
  92. package/src/components/index.ts +18 -0
  93. package/src/hooks/index.ts +21 -0
  94. package/src/hooks/useAgentSession.mdx +115 -0
  95. package/src/hooks/useAgentSession.test.ts +127 -0
  96. package/src/hooks/useAgentSession.ts +181 -0
  97. package/src/hooks/useChatStream.mdx +129 -0
  98. package/src/hooks/useChatStream.test.ts +233 -0
  99. package/src/hooks/useChatStream.ts +341 -0
  100. package/src/hooks/useToolCallStatus.mdx +102 -0
  101. package/src/hooks/useToolCallStatus.test.ts +99 -0
  102. package/src/hooks/useToolCallStatus.ts +99 -0
  103. package/src/index.ts +12 -0
  104. package/src/tailwind-preset.ts +109 -0
@@ -0,0 +1,88 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { MessageList } from './MessageList.js';
3
+ const meta = {
4
+ title: 'Components/MessageList',
5
+ component: MessageList,
6
+ parameters: {
7
+ layout: 'centered',
8
+ docs: {
9
+ description: {
10
+ component: 'Headless message list with auto-scroll-to-bottom. Pass a `renderMessage` prop to swap in your own bubble. The default renderer just shows role + content and is meant for sandbox / debugging only.',
11
+ },
12
+ },
13
+ },
14
+ decorators: [
15
+ (Story) => (_jsx("div", { className: "h-[480px] w-[640px] border border-agent-border bg-agent-canvas", children: _jsx(Story, {}) })),
16
+ ],
17
+ };
18
+ export default meta;
19
+ const NOW = '2026-05-15T00:00:00Z';
20
+ const baseMessages = [
21
+ { id: '1', role: 'user', content: 'Hi! What can you help me with?', createdAt: NOW },
22
+ {
23
+ id: '2',
24
+ role: 'assistant',
25
+ content: 'I can plan trips, draft emails, query your knowledge base and run safe shell commands. What would you like to start with?',
26
+ createdAt: NOW,
27
+ },
28
+ { id: '3', role: 'user', content: 'Plan a 2-day weekend in Kyoto.', createdAt: NOW },
29
+ {
30
+ id: '4',
31
+ role: 'assistant',
32
+ content: "Sure — Day 1: Fushimi Inari at sunrise, then Gion in the afternoon. Day 2: Arashiyama bamboo grove and a kaiseki dinner. I'll add restaurant picks next.",
33
+ createdAt: NOW,
34
+ },
35
+ ];
36
+ export const Default = {
37
+ args: {
38
+ messages: baseMessages,
39
+ },
40
+ };
41
+ export const Empty = {
42
+ args: {
43
+ messages: [],
44
+ },
45
+ };
46
+ export const EmptyWithCustomState = {
47
+ args: {
48
+ messages: [],
49
+ emptyState: (_jsxs("div", { className: "m-auto max-w-xs text-center text-sm text-agent-muted-foreground", children: [_jsx("p", { className: "font-medium text-agent-foreground", children: "Nothing to show yet" }), _jsx("p", { className: "mt-1", children: "Send your first message to start a conversation." })] })),
50
+ },
51
+ };
52
+ export const Streaming = {
53
+ args: {
54
+ messages: [
55
+ ...baseMessages,
56
+ {
57
+ id: '5',
58
+ role: 'assistant',
59
+ content: "Day 2 — Morning: rent a bike near Arashiyama station and",
60
+ createdAt: NOW,
61
+ },
62
+ ],
63
+ isStreaming: true,
64
+ },
65
+ };
66
+ export const StreamingEmptyAssistant = {
67
+ args: {
68
+ messages: [
69
+ ...baseMessages,
70
+ { id: '6', role: 'assistant', content: '', createdAt: NOW },
71
+ ],
72
+ isStreaming: true,
73
+ },
74
+ };
75
+ export const LongConversation = {
76
+ args: {
77
+ messages: Array.from({ length: 30 }, (_, i) => ({
78
+ id: `m-${i}`,
79
+ role: i % 2 === 0 ? 'user' : 'assistant',
80
+ content: i % 2 === 0
81
+ ? `User question #${i / 2 + 1}: tell me about topic ${i}.`
82
+ : `Assistant answer to question #${(i - 1) / 2 + 1}. ` +
83
+ 'This response wraps across multiple lines so we exercise the auto-scroll behaviour and verify the bubble shape under longer content.',
84
+ createdAt: NOW,
85
+ })),
86
+ },
87
+ };
88
+ //# sourceMappingURL=MessageList.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MessageList.stories.js","sourceRoot":"","sources":["../../src/components/MessageList.stories.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * `OrchestrationPlanCard` — render a multi-step plan with per-step status.
3
+ *
4
+ * Maps to the `orchestration` SSE event family: the harness emits a structured
5
+ * plan up-front and updates step status as execution progresses. The card is
6
+ * intentionally read-only; consumers that want inline edit (`deeppath/apps/web`'s
7
+ * "PlanSteps") should compose their own editor using `useChatStream`'s
8
+ * `onUnknownEvent` hook to track plan events and feed updated steps in here.
9
+ */
10
+ export type OrchestrationStepStatus = 'pending' | 'running' | 'done' | 'error' | 'skipped';
11
+ export interface OrchestrationStep {
12
+ id: string;
13
+ title: string;
14
+ description?: string;
15
+ status: OrchestrationStepStatus;
16
+ /** Optional badge (`tool`, `wait`, `decision`, `agent:<name>`, …). */
17
+ kind?: string;
18
+ /** Optional ISO datetime when the step finished, used for the right column. */
19
+ finishedAt?: string;
20
+ }
21
+ export interface OrchestrationPlanCardProps {
22
+ title?: string;
23
+ steps: OrchestrationStep[];
24
+ className?: string;
25
+ /**
26
+ * Optional click handler — useful when you want to open a step's trace
27
+ * timeline in a side panel. Receives the step that was clicked.
28
+ */
29
+ onStepClick?: (step: OrchestrationStep) => void;
30
+ }
31
+ export declare function OrchestrationPlanCard(props: OrchestrationPlanCardProps): import("react/jsx-runtime").JSX.Element;
32
+ //# sourceMappingURL=OrchestrationPlanCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrchestrationPlanCard.d.ts","sourceRoot":"","sources":["../../src/components/OrchestrationPlanCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,MAAM,MAAM,uBAAuB,GAC/B,SAAS,GACT,SAAS,GACT,MAAM,GACN,OAAO,GACP,SAAS,CAAC;AAEd,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,uBAAuB,CAAC;IAChC,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,0BAA0B;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;CACjD;AAkBD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,2CAoGtE"}
@@ -0,0 +1,48 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * `OrchestrationPlanCard` — render a multi-step plan with per-step status.
4
+ *
5
+ * Maps to the `orchestration` SSE event family: the harness emits a structured
6
+ * plan up-front and updates step status as execution progresses. The card is
7
+ * intentionally read-only; consumers that want inline edit (`deeppath/apps/web`'s
8
+ * "PlanSteps") should compose their own editor using `useChatStream`'s
9
+ * `onUnknownEvent` hook to track plan events and feed updated steps in here.
10
+ */
11
+ import { useMemo } from 'react';
12
+ import { cn } from './cn.js';
13
+ const statusToIcon = {
14
+ pending: '○',
15
+ running: '◐',
16
+ done: '●',
17
+ error: '✕',
18
+ skipped: '—',
19
+ };
20
+ const statusToColor = {
21
+ pending: 'text-agent-muted-foreground',
22
+ running: 'text-agent-accent',
23
+ done: 'text-agent-tool-read',
24
+ error: 'text-agent-destructive',
25
+ skipped: 'text-agent-muted-foreground line-through',
26
+ };
27
+ export function OrchestrationPlanCard(props) {
28
+ const { title = 'Plan', steps, className, onStepClick } = props;
29
+ const summary = useMemo(() => {
30
+ const total = steps.length;
31
+ const done = steps.filter((s) => s.status === 'done').length;
32
+ const errored = steps.filter((s) => s.status === 'error').length;
33
+ return { total, done, errored };
34
+ }, [steps]);
35
+ return (_jsxs("div", { className: cn('rounded-agent-lg border border-agent-border bg-agent-canvas p-4', className), "data-testid": "orchestration-plan-card", children: [_jsxs("div", { className: "mb-3 flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm font-semibold text-agent-foreground", children: title }), _jsxs("span", { className: "rounded-full border border-agent-border px-2 py-0.5 text-[10px] uppercase tracking-wide text-agent-muted-foreground", children: [summary.done, "/", summary.total] })] }), summary.errored > 0 ? (_jsxs("span", { className: "text-[11px] font-medium text-agent-destructive", children: [summary.errored, " error", summary.errored === 1 ? '' : 's'] })) : null] }), _jsx("ol", { className: "space-y-1.5", children: steps.map((step, idx) => {
36
+ const interactive = Boolean(onStepClick);
37
+ const Tag = interactive ? 'button' : 'div';
38
+ return (_jsx("li", { children: _jsxs(Tag, { ...(interactive
39
+ ? {
40
+ type: 'button',
41
+ onClick: () => onStepClick?.(step),
42
+ }
43
+ : {}), className: cn('flex w-full items-start gap-2 rounded-agent-sm px-2 py-1.5 text-left', interactive
44
+ ? 'transition-colors hover:bg-agent-muted'
45
+ : ''), "data-status": step.status, children: [_jsx("span", { className: cn('mt-0.5 select-none font-mono text-base leading-none', statusToColor[step.status]), "aria-hidden": true, children: statusToIcon[step.status] }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "truncate text-xs font-mono text-agent-muted-foreground", children: (idx + 1).toString().padStart(2, '0') }), _jsx("span", { className: cn('truncate text-sm font-medium', statusToColor[step.status]), children: step.title }), step.kind ? (_jsx("span", { className: "shrink-0 rounded-full border border-agent-border bg-agent-muted px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-agent-muted-foreground", children: step.kind })) : null] }), step.description ? (_jsx("p", { className: "mt-0.5 text-xs text-agent-muted-foreground", children: step.description })) : null] }), step.finishedAt ? (_jsx("span", { className: "shrink-0 text-[10px] text-agent-muted-foreground", children: step.finishedAt })) : null] }) }, step.id));
46
+ }) })] }));
47
+ }
48
+ //# sourceMappingURL=OrchestrationPlanCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrchestrationPlanCard.js","sourceRoot":"","sources":["../../src/components/OrchestrationPlanCard.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { OrchestrationPlanCard } from './OrchestrationPlanCard.js';
3
+ declare const meta: Meta<typeof OrchestrationPlanCard>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof OrchestrationPlanCard>;
6
+ export declare const InProgress: Story;
7
+ export declare const AllDone: Story;
8
+ export declare const WithError: Story;
9
+ export declare const SkippedBranch: Story;
10
+ export declare const Empty: Story;
11
+ export declare const Interactive: Story;
12
+ //# sourceMappingURL=OrchestrationPlanCard.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrchestrationPlanCard.stories.d.ts","sourceRoot":"","sources":["../../src/components/OrchestrationPlanCard.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAA0B,MAAM,4BAA4B,CAAC;AAE3F,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,qBAAqB,CAuB5C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAqBpD,eAAO,MAAM,UAAU,EAAE,KAIxB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAYvB,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAQ3B,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAInB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAKzB,CAAC"}
@@ -0,0 +1,84 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { OrchestrationPlanCard } from './OrchestrationPlanCard.js';
3
+ const meta = {
4
+ title: 'Components/OrchestrationPlanCard',
5
+ component: OrchestrationPlanCard,
6
+ parameters: {
7
+ layout: 'centered',
8
+ actions: { argTypesRegex: '^on[A-Z].*' },
9
+ docs: {
10
+ description: {
11
+ component: 'Read-only multi-step plan with per-step status icons and a header summary. Status values are `pending` / `running` / `done` / `error` / `skipped`. Pass `onStepClick` to make rows interactive (used in production to open a step\u2019s trace timeline in a side panel).',
12
+ },
13
+ },
14
+ },
15
+ args: {
16
+ title: 'Plan',
17
+ },
18
+ decorators: [
19
+ (Story) => (_jsx("div", { className: "w-[480px]", children: _jsx(Story, {}) })),
20
+ ],
21
+ };
22
+ export default meta;
23
+ const steps = [
24
+ { id: 's1', title: 'Parse user request', status: 'done', kind: 'decision' },
25
+ {
26
+ id: 's2',
27
+ title: 'Look up matching projects',
28
+ status: 'done',
29
+ kind: 'tool',
30
+ description: 'web_search → project_index',
31
+ },
32
+ {
33
+ id: 's3',
34
+ title: 'Draft proposal outline',
35
+ status: 'running',
36
+ kind: 'agent:writer',
37
+ },
38
+ { id: 's4', title: 'Estimate budget', status: 'pending', kind: 'tool' },
39
+ { id: 's5', title: 'Send for review', status: 'pending', kind: 'wait' },
40
+ ];
41
+ export const InProgress = {
42
+ args: {
43
+ steps,
44
+ },
45
+ };
46
+ export const AllDone = {
47
+ args: {
48
+ steps: steps.map((s) => ({ ...s, status: 'done', finishedAt: '15:32' })),
49
+ },
50
+ };
51
+ export const WithError = {
52
+ args: {
53
+ steps: [
54
+ ...steps.slice(0, 2),
55
+ {
56
+ ...steps[2],
57
+ status: 'error',
58
+ description: 'writer_agent rejected: missing required tone parameter',
59
+ },
60
+ ...steps.slice(3),
61
+ ],
62
+ },
63
+ };
64
+ export const SkippedBranch = {
65
+ args: {
66
+ steps: [
67
+ ...steps.slice(0, 3).map((s) => ({ ...s, status: 'done' })),
68
+ { ...steps[3], status: 'skipped', description: 'no budget needed' },
69
+ { ...steps[4], status: 'done', finishedAt: '15:55' },
70
+ ],
71
+ },
72
+ };
73
+ export const Empty = {
74
+ args: {
75
+ steps: [],
76
+ },
77
+ };
78
+ export const Interactive = {
79
+ args: {
80
+ steps,
81
+ onStepClick: () => { },
82
+ },
83
+ };
84
+ //# sourceMappingURL=OrchestrationPlanCard.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrchestrationPlanCard.stories.js","sourceRoot":"","sources":["../../src/components/OrchestrationPlanCard.stories.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * `SSEStreamView` — debug / power-user view that prints the raw SSE event log.
3
+ *
4
+ * Used in two production contexts today:
5
+ * 1. The "Trace" tab in `deeppath/apps/web` admin tooling.
6
+ * 2. The mockCflog log window in `deeppath-agent`, where it doubles as a
7
+ * dev console for the Electron app.
8
+ *
9
+ * The component is intentionally append-only; consumers feed it events via the
10
+ * `events` prop and it auto-scrolls to keep the latest in view.
11
+ */
12
+ import type { SSEEvent } from '@steerable/agent-protocol';
13
+ export interface SSEStreamViewProps {
14
+ events: SSEEvent[];
15
+ className?: string;
16
+ /** Show full JSON payloads instead of a one-line summary. */
17
+ verbose?: boolean;
18
+ autoScroll?: boolean;
19
+ /**
20
+ * Optional filter; only events whose `type` is in the set are rendered.
21
+ * Useful for production debugging where you only care about, e.g.,
22
+ * `tool_call` + `tool_result` chains.
23
+ */
24
+ filterTypes?: SSEEvent['type'][];
25
+ emptyState?: React.ReactNode;
26
+ maxRows?: number;
27
+ }
28
+ export declare function SSEStreamView(props: SSEStreamViewProps): import("react/jsx-runtime").JSX.Element;
29
+ //# sourceMappingURL=SSEStreamView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SSEStreamView.d.ts","sourceRoot":"","sources":["../../src/components/SSEStreamView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAG1D,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;IACjC,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAuCD,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,2CA6EtD"}
@@ -0,0 +1,78 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * `SSEStreamView` — debug / power-user view that prints the raw SSE event log.
4
+ *
5
+ * Used in two production contexts today:
6
+ * 1. The "Trace" tab in `deeppath/apps/web` admin tooling.
7
+ * 2. The mockCflog log window in `deeppath-agent`, where it doubles as a
8
+ * dev console for the Electron app.
9
+ *
10
+ * The component is intentionally append-only; consumers feed it events via the
11
+ * `events` prop and it auto-scrolls to keep the latest in view.
12
+ */
13
+ import { useEffect, useMemo, useRef } from 'react';
14
+ import { cn } from './cn.js';
15
+ const typeColor = {
16
+ content: 'text-agent-foreground',
17
+ error: 'text-agent-destructive',
18
+ agent: 'text-agent-accent',
19
+ orchestration: 'text-agent-tool-write',
20
+ 'loader-hint': 'text-agent-muted-foreground',
21
+ keepalive: 'text-agent-muted-foreground/60',
22
+ done: 'text-agent-tool-read',
23
+ budget_exhausted: 'text-agent-destructive',
24
+ tool_call: 'text-agent-tool-write',
25
+ tool_result: 'text-agent-tool-read',
26
+ };
27
+ function summarize(event) {
28
+ if (event.type === 'content') {
29
+ const c = typeof event.content === 'string' ? event.content : '';
30
+ return c.length > 80 ? c.slice(0, 80) + '…' : c;
31
+ }
32
+ if (event.type === 'error' || event.type === 'budget_exhausted') {
33
+ return event.message ?? '';
34
+ }
35
+ if (event.type === 'tool_call' || event.type === 'tool_result') {
36
+ const payload = event.payload;
37
+ return payload ? JSON.stringify(payload).slice(0, 120) : '';
38
+ }
39
+ if (event.type === 'loader-hint') {
40
+ return event.hint ?? '';
41
+ }
42
+ if (event.type === 'orchestration') {
43
+ return event.orchestrationGroupId ?? '';
44
+ }
45
+ if (event.type === 'agent') {
46
+ return JSON.stringify(event).slice(0, 120);
47
+ }
48
+ return '';
49
+ }
50
+ export function SSEStreamView(props) {
51
+ const { events, className, verbose = false, autoScroll = true, filterTypes, emptyState, maxRows = 1000, } = props;
52
+ const containerRef = useRef(null);
53
+ const visible = useMemo(() => {
54
+ let list = filterTypes ? events.filter((e) => filterTypes.includes(e.type)) : events;
55
+ if (list.length > maxRows) {
56
+ list = list.slice(list.length - maxRows);
57
+ }
58
+ return list;
59
+ }, [events, filterTypes, maxRows]);
60
+ useEffect(() => {
61
+ if (!autoScroll)
62
+ return;
63
+ const el = containerRef.current;
64
+ if (!el)
65
+ return;
66
+ el.scrollTop = el.scrollHeight;
67
+ }, [autoScroll, visible.length]);
68
+ return (_jsx("div", { ref: containerRef, className: cn('h-full overflow-y-auto rounded-agent-md border border-agent-border bg-agent-canvas font-mono text-[11px] leading-relaxed', 'focus:outline-none focus-visible:ring-2 focus-visible:ring-agent-accent', className), role: "log", "aria-live": "polite", "aria-label": "SSE event log", tabIndex: 0, children: visible.length === 0 ? (_jsx("div", { className: "flex h-full items-center justify-center text-agent-muted-foreground", children: emptyState ?? 'No events yet.' })) : (_jsx("ul", { className: "divide-y divide-agent-border", children: visible.map((event, idx) => (_jsxs("li", { className: "flex flex-col gap-0.5 px-3 py-1.5", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: cn('shrink-0 font-semibold uppercase tracking-wide', typeColor[event.type]), children: event.type }), !verbose ? (_jsx("span", { className: "truncate text-agent-muted-foreground", children: summarize(event) })) : null] }), verbose ? (_jsx("pre", { className: "overflow-x-auto whitespace-pre-wrap break-words text-agent-muted-foreground", children: safeStringify(event) })) : null] }, `${idx}_${event.type}`))) })) }));
69
+ }
70
+ function safeStringify(value) {
71
+ try {
72
+ return JSON.stringify(value, null, 2);
73
+ }
74
+ catch {
75
+ return String(value);
76
+ }
77
+ }
78
+ //# sourceMappingURL=SSEStreamView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SSEStreamView.js","sourceRoot":"","sources":["../../src/components/SSEStreamView.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { SSEStreamView } from './SSEStreamView.js';
3
+ declare const meta: Meta<typeof SSEStreamView>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof SSEStreamView>;
6
+ export declare const Empty: Story;
7
+ export declare const Default: Story;
8
+ export declare const Verbose: Story;
9
+ export declare const FilteredToolEvents: Story;
10
+ export declare const ErrorAndBudget: Story;
11
+ export declare const HighVolume: Story;
12
+ //# sourceMappingURL=SSEStreamView.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SSEStreamView.stories.d.ts","sourceRoot":"","sources":["../../src/components/SSEStreamView.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,aAAa,CAmBpC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,aAAa,CAAC,CAAC;AA4B5C,eAAO,MAAM,KAAK,EAAE,KAInB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAKrB,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAKhC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAQ5B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAQxB,CAAC"}
@@ -0,0 +1,86 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { SSEStreamView } from './SSEStreamView.js';
3
+ const meta = {
4
+ title: 'Components/SSEStreamView',
5
+ component: SSEStreamView,
6
+ parameters: {
7
+ layout: 'centered',
8
+ docs: {
9
+ description: {
10
+ component: 'Append-only debug view of the raw SSE event log. Used in production for the "Trace" tab in `deeppath/apps/web` and as a dev console inside `deeppath-agent`. Toggle `verbose` to inspect full JSON payloads, or pass `filterTypes` to narrow to a single event family.',
11
+ },
12
+ },
13
+ },
14
+ decorators: [
15
+ (Story) => (_jsx("div", { className: "h-[400px] w-[640px]", children: _jsx(Story, {}) })),
16
+ ],
17
+ };
18
+ export default meta;
19
+ const events = [
20
+ { type: 'agent', agentId: 'planner', model: 'gpt-4o-mini' },
21
+ {
22
+ type: 'orchestration',
23
+ orchestrationGroupId: 'plan-1',
24
+ payload: { phase: 'plan_started' },
25
+ },
26
+ { type: 'content', content: 'Looking up the latest project status…' },
27
+ {
28
+ type: 'tool_call',
29
+ payload: {
30
+ callId: 'call_1',
31
+ name: 'project_search',
32
+ arguments: { query: 'Q4 roadmap', limit: 5 },
33
+ },
34
+ },
35
+ {
36
+ type: 'tool_result',
37
+ payload: { callId: 'call_1', name: 'project_search', status: 'success', count: 3 },
38
+ },
39
+ { type: 'content', content: 'Found 3 active projects. Drafting summary…' },
40
+ { type: 'loader-hint', hint: 'Composing response…' },
41
+ { type: 'content', content: 'Here are the highlights:\n1. Project Alpha\n2. Project Beta' },
42
+ { type: 'done' },
43
+ ];
44
+ export const Empty = {
45
+ args: {
46
+ events: [],
47
+ },
48
+ };
49
+ export const Default = {
50
+ args: {
51
+ events,
52
+ },
53
+ };
54
+ export const Verbose = {
55
+ args: {
56
+ events,
57
+ verbose: true,
58
+ },
59
+ };
60
+ export const FilteredToolEvents = {
61
+ args: {
62
+ events,
63
+ filterTypes: ['tool_call', 'tool_result'],
64
+ },
65
+ };
66
+ export const ErrorAndBudget = {
67
+ args: {
68
+ events: [
69
+ ...events.slice(0, 5),
70
+ { type: 'budget_exhausted', message: 'token budget reached after 3.2k tokens' },
71
+ { type: 'error', message: 'tool_dispatch failed: timeout after 30s' },
72
+ ],
73
+ },
74
+ };
75
+ export const HighVolume = {
76
+ args: {
77
+ events: Array.from({ length: 200 }, (_, i) => {
78
+ if (i % 13 === 0)
79
+ return { type: 'tool_call', payload: { callId: `c${i}`, name: 'noop' } };
80
+ if (i % 13 === 6)
81
+ return { type: 'tool_result', payload: { callId: `c${i - 6}`, status: 'success' } };
82
+ return { type: 'content', content: `chunk ${i}: ` + 'lorem ipsum dolor sit amet '.repeat(2) };
83
+ }),
84
+ },
85
+ };
86
+ //# sourceMappingURL=SSEStreamView.stories.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SSEStreamView.stories.js","sourceRoot":"","sources":["../../src/components/SSEStreamView.stories.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * `ToolCallRenderer` — display a single tool call + (optional) tool result.
3
+ *
4
+ * Renders three visual rows depending on lifecycle / mode:
5
+ *
6
+ * ┌──────────────────────────────────────────────────┐
7
+ * │ [icon] tool_name [mode-pill] [time] │
8
+ * │ args (collapsed by default) │
9
+ * │ ── result ── │
10
+ * │ message + data (collapsed by default) │
11
+ * └──────────────────────────────────────────────────┘
12
+ *
13
+ * Headless body: callers can override the args / result subtree with
14
+ * `renderArgs` / `renderResult` if they need richer formatting (diffs, code
15
+ * blocks, structured cards). Default body uses pretty-printed JSON.
16
+ */
17
+ import type { ToolCall, ToolResult } from '@steerable/agent-protocol';
18
+ import { type ToolCallMode } from '../hooks/useToolCallStatus.js';
19
+ export interface ToolCallRendererProps {
20
+ call: ToolCall;
21
+ result?: ToolResult;
22
+ /**
23
+ * Optional explicit mode override. Use when the framework's `decide_tool_mode`
24
+ * has already classified the tool (the local `ToolRouter` ships this value
25
+ * alongside the call in production setups).
26
+ */
27
+ mode?: ToolCallMode;
28
+ runningHint?: boolean;
29
+ /**
30
+ * Approval handler. Must be supplied when rendering a `local`-mode call you
31
+ * want the user to confirm before execution. If omitted, the renderer falls
32
+ * back to the read-only "awaiting result" treatment.
33
+ */
34
+ onApprove?: (call: ToolCall) => void;
35
+ onReject?: (call: ToolCall) => void;
36
+ className?: string;
37
+ renderArgs?: (call: ToolCall) => React.ReactNode;
38
+ renderResult?: (result: ToolResult) => React.ReactNode;
39
+ defaultExpanded?: boolean;
40
+ }
41
+ export declare function ToolCallRenderer(props: ToolCallRendererProps): import("react/jsx-runtime").JSX.Element;
42
+ //# sourceMappingURL=ToolCallRenderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToolCallRenderer.d.ts","sourceRoot":"","sources":["../../src/components/ToolCallRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAGrF,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB;;;;OAIG;IACH,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;OAIG;IACH,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,KAAK,CAAC,SAAS,CAAC;IACjD,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,KAAK,CAAC,SAAS,CAAC;IACvD,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AA8ED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,2CA2F5D"}