@steerable/agent-ui 0.2.3 → 0.2.5

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 (184) hide show
  1. package/dist/cards/ActionSegmentCard.d.ts +18 -0
  2. package/dist/cards/ActionSegmentCard.d.ts.map +1 -0
  3. package/dist/cards/ActionSegmentCard.js +26 -0
  4. package/dist/cards/ActionSegmentCard.js.map +1 -0
  5. package/dist/cards/AnalysisDocumentCard.d.ts +33 -0
  6. package/dist/cards/AnalysisDocumentCard.d.ts.map +1 -0
  7. package/dist/cards/AnalysisDocumentCard.js +11 -0
  8. package/dist/cards/AnalysisDocumentCard.js.map +1 -0
  9. package/dist/cards/AskUserQuestionsCard.d.ts +43 -0
  10. package/dist/cards/AskUserQuestionsCard.d.ts.map +1 -0
  11. package/dist/cards/AskUserQuestionsCard.js +171 -0
  12. package/dist/cards/AskUserQuestionsCard.js.map +1 -0
  13. package/dist/cards/CoverageReportCard.d.ts +41 -0
  14. package/dist/cards/CoverageReportCard.d.ts.map +1 -0
  15. package/dist/cards/CoverageReportCard.js +55 -0
  16. package/dist/cards/CoverageReportCard.js.map +1 -0
  17. package/dist/cards/OrchestrationPlanCard.d.ts +60 -0
  18. package/dist/cards/OrchestrationPlanCard.d.ts.map +1 -0
  19. package/dist/cards/OrchestrationPlanCard.js +103 -0
  20. package/dist/cards/OrchestrationPlanCard.js.map +1 -0
  21. package/dist/cards/PlanSelectorCard.d.ts +40 -0
  22. package/dist/cards/PlanSelectorCard.d.ts.map +1 -0
  23. package/dist/cards/PlanSelectorCard.js +106 -0
  24. package/dist/cards/PlanSelectorCard.js.map +1 -0
  25. package/dist/cards/PlanStepsCard.d.ts +18 -0
  26. package/dist/cards/PlanStepsCard.d.ts.map +1 -0
  27. package/dist/cards/PlanStepsCard.js +25 -0
  28. package/dist/cards/PlanStepsCard.js.map +1 -0
  29. package/dist/cards/QuizCard.d.ts +44 -0
  30. package/dist/cards/QuizCard.d.ts.map +1 -0
  31. package/dist/cards/QuizCard.js +113 -0
  32. package/dist/cards/QuizCard.js.map +1 -0
  33. package/dist/cards/ResearchPlanCard.d.ts +23 -0
  34. package/dist/cards/ResearchPlanCard.d.ts.map +1 -0
  35. package/dist/cards/ResearchPlanCard.js +50 -0
  36. package/dist/cards/ResearchPlanCard.js.map +1 -0
  37. package/dist/cards/SearchSourcesCard.d.ts +29 -0
  38. package/dist/cards/SearchSourcesCard.d.ts.map +1 -0
  39. package/dist/cards/SearchSourcesCard.js +83 -0
  40. package/dist/cards/SearchSourcesCard.js.map +1 -0
  41. package/dist/cards/SuggestedRepliesCard.d.ts +18 -0
  42. package/dist/cards/SuggestedRepliesCard.d.ts.map +1 -0
  43. package/dist/cards/SuggestedRepliesCard.js +14 -0
  44. package/dist/cards/SuggestedRepliesCard.js.map +1 -0
  45. package/dist/cards/SummaryMessageCard.d.ts +40 -0
  46. package/dist/cards/SummaryMessageCard.d.ts.map +1 -0
  47. package/dist/cards/SummaryMessageCard.js +56 -0
  48. package/dist/cards/SummaryMessageCard.js.map +1 -0
  49. package/dist/cards/ThinkingProcessCard.d.ts +46 -0
  50. package/dist/cards/ThinkingProcessCard.d.ts.map +1 -0
  51. package/dist/cards/ThinkingProcessCard.js +79 -0
  52. package/dist/cards/ThinkingProcessCard.js.map +1 -0
  53. package/dist/cards/ToolExecutionCard.d.ts +21 -0
  54. package/dist/cards/ToolExecutionCard.d.ts.map +1 -0
  55. package/dist/cards/ToolExecutionCard.js +65 -0
  56. package/dist/cards/ToolExecutionCard.js.map +1 -0
  57. package/dist/cards/icons.d.ts +38 -0
  58. package/dist/cards/icons.d.ts.map +1 -0
  59. package/dist/cards/icons.js +87 -0
  60. package/dist/cards/icons.js.map +1 -0
  61. package/dist/cards/index.d.ts +38 -0
  62. package/dist/cards/index.d.ts.map +1 -0
  63. package/dist/cards/index.js +24 -0
  64. package/dist/cards/index.js.map +1 -0
  65. package/dist/cards/types.d.ts +24 -0
  66. package/dist/cards/types.d.ts.map +1 -0
  67. package/dist/cards/types.js +7 -0
  68. package/dist/cards/types.js.map +1 -0
  69. package/dist/components/AgentSelector.d.ts +23 -0
  70. package/dist/components/AgentSelector.d.ts.map +1 -0
  71. package/dist/components/AgentSelector.js +63 -0
  72. package/dist/components/AgentSelector.js.map +1 -0
  73. package/dist/components/AgentSelector.stories.d.ts +12 -0
  74. package/dist/components/AgentSelector.stories.d.ts.map +1 -0
  75. package/dist/components/AgentSelector.stories.js +95 -0
  76. package/dist/components/AgentSelector.stories.js.map +1 -0
  77. package/dist/components/ChatPanel.d.ts +138 -21
  78. package/dist/components/ChatPanel.d.ts.map +1 -1
  79. package/dist/components/ChatPanel.js +181 -26
  80. package/dist/components/ChatPanel.js.map +1 -1
  81. package/dist/components/index.d.ts +3 -1
  82. package/dist/components/index.d.ts.map +1 -1
  83. package/dist/components/index.js +1 -0
  84. package/dist/components/index.js.map +1 -1
  85. package/dist/hooks/useChatStream.d.ts +15 -0
  86. package/dist/hooks/useChatStream.d.ts.map +1 -1
  87. package/dist/hooks/useChatStream.js +13 -1
  88. package/dist/hooks/useChatStream.js.map +1 -1
  89. package/dist/index.d.ts +2 -0
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.js +5 -0
  92. package/dist/index.js.map +1 -1
  93. package/dist/state/ChatSessionProvider.d.ts +59 -0
  94. package/dist/state/ChatSessionProvider.d.ts.map +1 -0
  95. package/dist/state/ChatSessionProvider.js +71 -0
  96. package/dist/state/ChatSessionProvider.js.map +1 -0
  97. package/dist/state/MockChatStreamTransport.d.ts +54 -0
  98. package/dist/state/MockChatStreamTransport.d.ts.map +1 -0
  99. package/dist/state/MockChatStreamTransport.js +86 -0
  100. package/dist/state/MockChatStreamTransport.js.map +1 -0
  101. package/dist/state/MockChatStreamTransport.stories.d.ts +13 -0
  102. package/dist/state/MockChatStreamTransport.stories.d.ts.map +1 -0
  103. package/dist/state/MockChatStreamTransport.stories.js +60 -0
  104. package/dist/state/MockChatStreamTransport.stories.js.map +1 -0
  105. package/dist/state/bridgeLegacySSE.d.ts +42 -0
  106. package/dist/state/bridgeLegacySSE.d.ts.map +1 -0
  107. package/dist/state/bridgeLegacySSE.js +102 -0
  108. package/dist/state/bridgeLegacySSE.js.map +1 -0
  109. package/dist/state/index.d.ts +32 -0
  110. package/dist/state/index.d.ts.map +1 -0
  111. package/dist/state/index.js +24 -0
  112. package/dist/state/index.js.map +1 -0
  113. package/dist/state/parseSSE.d.ts +50 -0
  114. package/dist/state/parseSSE.d.ts.map +1 -0
  115. package/dist/state/parseSSE.js +112 -0
  116. package/dist/state/parseSSE.js.map +1 -0
  117. package/dist/state/useChatComposer.d.ts +51 -0
  118. package/dist/state/useChatComposer.d.ts.map +1 -0
  119. package/dist/state/useChatComposer.js +82 -0
  120. package/dist/state/useChatComposer.js.map +1 -0
  121. package/dist/state/useChatList.d.ts +73 -0
  122. package/dist/state/useChatList.d.ts.map +1 -0
  123. package/dist/state/useChatList.js +161 -0
  124. package/dist/state/useChatList.js.map +1 -0
  125. package/dist/state/useChatSession.d.ts +29 -0
  126. package/dist/state/useChatSession.d.ts.map +1 -0
  127. package/dist/state/useChatSession.js +37 -0
  128. package/dist/state/useChatSession.js.map +1 -0
  129. package/dist/state/useScrollLock.d.ts +35 -0
  130. package/dist/state/useScrollLock.d.ts.map +1 -0
  131. package/dist/state/useScrollLock.js +74 -0
  132. package/dist/state/useScrollLock.js.map +1 -0
  133. package/dist/state/useToolCallStream.d.ts +38 -0
  134. package/dist/state/useToolCallStream.d.ts.map +1 -0
  135. package/dist/state/useToolCallStream.js +74 -0
  136. package/dist/state/useToolCallStream.js.map +1 -0
  137. package/package.json +11 -3
  138. package/src/cards/ActionSegmentCard.tsx +60 -0
  139. package/src/cards/AnalysisDocumentCard.tsx +81 -0
  140. package/src/cards/AskUserQuestionsCard.tsx +354 -0
  141. package/src/cards/CoverageReportCard.tsx +215 -0
  142. package/src/cards/OrchestrationPlanCard.tsx +328 -0
  143. package/src/cards/PlanSelectorCard.tsx +312 -0
  144. package/src/cards/PlanStepsCard.tsx +52 -0
  145. package/src/cards/QuizCard.tsx +309 -0
  146. package/src/cards/ResearchPlanCard.tsx +169 -0
  147. package/src/cards/SearchSourcesCard.tsx +244 -0
  148. package/src/cards/SuggestedRepliesCard.tsx +48 -0
  149. package/src/cards/SummaryMessageCard.tsx +145 -0
  150. package/src/cards/ThinkingProcessCard.tsx +155 -0
  151. package/src/cards/ToolExecutionCard.tsx +152 -0
  152. package/src/cards/cards.test.tsx +492 -0
  153. package/src/cards/icons.tsx +249 -0
  154. package/src/cards/index.ts +53 -0
  155. package/src/cards/types.ts +27 -0
  156. package/src/components/AgentSelector.stories.tsx +113 -0
  157. package/src/components/AgentSelector.test.tsx +70 -0
  158. package/src/components/AgentSelector.tsx +147 -0
  159. package/src/components/ChatPanel.test.tsx +130 -0
  160. package/src/components/ChatPanel.tsx +612 -138
  161. package/src/components/index.ts +13 -1
  162. package/src/hooks/useChatStream.test.ts +78 -0
  163. package/src/hooks/useChatStream.ts +32 -1
  164. package/src/index.ts +43 -0
  165. package/src/state/ChatSessionProvider.test.tsx +85 -0
  166. package/src/state/ChatSessionProvider.tsx +98 -0
  167. package/src/state/MockChatStreamTransport.stories.tsx +95 -0
  168. package/src/state/MockChatStreamTransport.test.ts +163 -0
  169. package/src/state/MockChatStreamTransport.ts +123 -0
  170. package/src/state/bridgeLegacySSE.test.ts +134 -0
  171. package/src/state/bridgeLegacySSE.ts +134 -0
  172. package/src/state/index.ts +82 -0
  173. package/src/state/parseSSE.test.ts +123 -0
  174. package/src/state/parseSSE.ts +123 -0
  175. package/src/state/useChatComposer.test.ts +145 -0
  176. package/src/state/useChatComposer.ts +117 -0
  177. package/src/state/useChatList.test.ts +135 -0
  178. package/src/state/useChatList.ts +220 -0
  179. package/src/state/useChatSession.test.ts +61 -0
  180. package/src/state/useChatSession.ts +64 -0
  181. package/src/state/useScrollLock.test.ts +99 -0
  182. package/src/state/useScrollLock.ts +105 -0
  183. package/src/state/useToolCallStream.test.ts +86 -0
  184. package/src/state/useToolCallStream.ts +110 -0
@@ -0,0 +1,103 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * `<OrchestrationPlanCard />`
4
+ *
5
+ * The visible surface of an otherwise invisible Coordinator agent. Renders
6
+ * one row per worker task with a status dot driven by `taskStatuses` (a map
7
+ * the parent computes off sibling assistant bubbles tagged with the same
8
+ * orchestrationGroupId + orchestrationTaskId).
9
+ *
10
+ * Three top-level shells are supported via mutually-exclusive flags so the
11
+ * Coordinator can express its lifecycle without forcing the caller to render
12
+ * three different components:
13
+ * - `loading` + optional `loadingHint` — Coordinator is still planning.
14
+ * - `failed` + optional `failure` — planning errored.
15
+ * - default — `payload.tasks` are rendered.
16
+ *
17
+ * Slots:
18
+ * - `renderAbove` / `renderBelowHeader` — out-of-flow rails for badges and
19
+ * context-load lines that deeppath wants to ride along.
20
+ * - `renderTaskRow(task, status)` — full row override (deeppath uses
21
+ * it to draw the per-agent colored chip + monospaced task id + right-
22
+ * aligned status label).
23
+ * - `headerLabel`, `headerSecondary` — override the default
24
+ * "编排计划 · N 个子任务" header label/subline.
25
+ * - `hideMode`, `hideHeaderCounts` — drop the optional header chips
26
+ * when the host UI does not want them (deeppath hides both).
27
+ * - controlled `expanded` + `onExpandedChange`.
28
+ */
29
+ import * as React from 'react';
30
+ import { ChevronDownIcon, ChevronRightIcon, GitBranchIcon, LoaderIcon, AlertIcon, } from './icons.js';
31
+ import { asReactNode } from './types.js';
32
+ const STATUS_LABEL = {
33
+ pending: '排队中',
34
+ running: '执行中',
35
+ ok: '已完成',
36
+ skipped: '已跳过',
37
+ failed: '失败',
38
+ ask_user_paused: '等待用户',
39
+ };
40
+ const DOT_CLASS = {
41
+ pending: 'bg-[var(--agent-muted-foreground,#9ca3af)]',
42
+ running: 'bg-amber-500 animate-pulse',
43
+ ok: 'bg-emerald-500',
44
+ skipped: 'bg-[var(--agent-muted-foreground,#d1d5db)]',
45
+ failed: 'bg-rose-500',
46
+ ask_user_paused: 'bg-sky-500',
47
+ };
48
+ export const OrchestrationPlanCard = ({ payload, taskStatuses, agentNameFor, className, defaultExpanded = true, expanded: expandedProp, onExpandedChange, loading, loadingHint, failed, failure, headerLabel, headerSecondary, hideMode, hideHeaderCounts, renderAbove, renderBelowHeader, renderTaskRow, }) => {
49
+ const [expandedState, setExpandedState] = React.useState(defaultExpanded);
50
+ const isControlled = expandedProp !== undefined;
51
+ const expanded = isControlled ? Boolean(expandedProp) : expandedState;
52
+ const setExpanded = (next) => {
53
+ if (!isControlled)
54
+ setExpandedState(next);
55
+ onExpandedChange?.(next);
56
+ };
57
+ const above = renderAbove ? asReactNode(renderAbove()) : null;
58
+ const belowHeader = renderBelowHeader ? asReactNode(renderBelowHeader()) : null;
59
+ // ---------------- loading shell ----------------
60
+ if (loading) {
61
+ return (_jsxs("div", { className: [
62
+ 'steerable-orchestration-plan',
63
+ className,
64
+ ].filter(Boolean).join(' '), children: [above, _jsxs("div", { className: "rounded-lg border border-[var(--agent-border,#e5e7eb)] bg-[var(--agent-card-bg,#fff)] text-sm shadow-sm", children: [_jsxs("div", { className: "flex w-full items-center gap-2 px-3 py-2 text-xs text-[var(--agent-muted-foreground,#6b7280)]", children: [_jsx(LoaderIcon, { size: 14, className: "shrink-0 animate-spin" }), _jsx(GitBranchIcon, { size: 14, className: "shrink-0" }), _jsxs("span", { className: "inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap", children: [headerLabel ?? (_jsx("span", { className: "font-medium text-[var(--agent-foreground,#111827)]", children: "\u534F\u8C03\u5458" })), _jsx("span", { className: "text-[var(--agent-muted-foreground,#9ca3af)]", children: "\u00B7" }), _jsx("span", { children: loadingHint ?? '正在规划' })] })] }), belowHeader] })] }));
65
+ }
66
+ // ---------------- failed shell ----------------
67
+ if (failed) {
68
+ return (_jsxs("div", { className: [
69
+ 'steerable-orchestration-plan',
70
+ className,
71
+ ].filter(Boolean).join(' '), children: [above, _jsxs("div", { className: "rounded-lg border border-rose-500/30 bg-rose-500/5 text-sm shadow-sm", children: [_jsxs("div", { className: "flex w-full items-start gap-2 px-3 py-2 text-xs", children: [_jsx(AlertIcon, { size: 14, className: "mt-0.5 shrink-0 text-rose-500" }), _jsx(GitBranchIcon, { size: 14, className: "mt-0.5 shrink-0 text-[var(--agent-muted-foreground,#6b7280)]" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "inline-flex items-center gap-1.5 whitespace-nowrap", children: [headerLabel ?? (_jsx("span", { className: "font-medium text-[var(--agent-foreground,#111827)]", children: "\u534F\u8C03\u5458" })), _jsx("span", { className: "text-[var(--agent-muted-foreground,#9ca3af)]", children: "\u00B7" }), _jsx("span", { className: "text-rose-500", children: "\u89C4\u5212\u5931\u8D25" })] }), failure && (_jsx("div", { className: "mt-1 break-words leading-relaxed text-[var(--agent-muted-foreground,#6b7280)]", children: failure }))] })] }), belowHeader] })] }));
72
+ }
73
+ // ---------------- default ready shell ----------------
74
+ const tasks = payload.tasks ?? [];
75
+ const counts = React.useMemo(() => {
76
+ const c = { running: 0, ok: 0, failed: 0, paused: 0, total: tasks.length };
77
+ for (const t of tasks) {
78
+ const s = (taskStatuses?.[t.id] ?? 'pending');
79
+ if (s === 'running')
80
+ c.running += 1;
81
+ else if (s === 'ok')
82
+ c.ok += 1;
83
+ else if (s === 'failed')
84
+ c.failed += 1;
85
+ else if (s === 'ask_user_paused')
86
+ c.paused += 1;
87
+ }
88
+ return c;
89
+ }, [tasks, taskStatuses]);
90
+ return (_jsxs("div", { className: [
91
+ 'steerable-orchestration-plan',
92
+ className,
93
+ ].filter(Boolean).join(' '), children: [above, _jsxs("div", { className: "rounded-lg border border-[var(--agent-border,#e5e7eb)] bg-[var(--agent-card-bg,#fff)] text-sm shadow-sm", children: [_jsxs("button", { type: "button", onClick: () => setExpanded(!expanded), className: "flex w-full items-center justify-between gap-2 px-3 py-2 text-left text-xs text-[var(--agent-muted-foreground,#6b7280)] transition-all duration-200 hover:text-[var(--agent-foreground,#111827)]", children: [_jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [expanded ? _jsx(ChevronDownIcon, { size: 14 }) : _jsx(ChevronRightIcon, { size: 14 }), _jsx(GitBranchIcon, { size: 14, className: "shrink-0" }), _jsxs("span", { className: "inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap", children: [headerLabel ?? (_jsx("span", { className: "font-medium text-[var(--agent-foreground,#111827)]", children: "\u7F16\u6392\u8BA1\u5212" })), headerSecondary !== undefined ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-[var(--agent-muted-foreground,#9ca3af)]", children: "\u00B7" }), _jsx("span", { children: headerSecondary })] })) : (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-[var(--agent-muted-foreground,#9ca3af)]", children: "\u00B7" }), _jsxs("span", { children: [tasks.length, " \u4E2A\u5B50\u4EFB\u52A1"] })] })), !hideMode && payload.mode && (_jsx("span", { className: "ml-1 rounded-full bg-[var(--agent-muted,#f3f4f6)] px-2 py-0.5 text-[10px] uppercase tracking-wider text-[var(--agent-muted-foreground,#6b7280)]", children: payload.mode }))] }), payload.rationale && !expanded && (_jsx("span", { className: "min-w-0 flex-1 truncate text-[var(--agent-muted-foreground,#9ca3af)]", children: payload.rationale }))] }), !hideHeaderCounts && (_jsxs("span", { className: "flex shrink-0 items-center gap-2", children: [counts.running > 0 && (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(LoaderIcon, { size: 12, className: "text-amber-500" }), " ", counts.running] })), counts.failed > 0 && (_jsxs("span", { className: "flex items-center gap-1 text-rose-600", children: [_jsx(AlertIcon, { size: 12 }), " ", counts.failed] })), _jsxs("span", { children: [counts.ok, "/", counts.total] })] }))] }), belowHeader, expanded && (_jsxs("div", { className: "px-3 pb-3", children: [payload.rationale && (_jsx("p", { className: "pb-2 text-xs leading-relaxed text-[var(--agent-muted-foreground,#6b7280)]", children: payload.rationale })), _jsx("ul", { className: "space-y-1.5", children: tasks.map((t) => {
94
+ const status = (taskStatuses?.[t.id] ?? 'pending');
95
+ if (renderTaskRow) {
96
+ return (_jsx(React.Fragment, { children: asReactNode(renderTaskRow(t, status)) }, t.id));
97
+ }
98
+ return (_jsxs("li", { className: "flex items-start gap-2 text-sm", children: [_jsx("span", { className: `mt-1.5 h-2 w-2 flex-shrink-0 rounded-full ${DOT_CLASS[status]}`, "aria-hidden": true }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "font-medium text-[var(--agent-foreground,#111827)]", children: agentNameFor ? agentNameFor(t.agentId) : t.agentId }), _jsx("span", { className: "text-xs text-[var(--agent-muted-foreground,#6b7280)]", children: STATUS_LABEL[status] })] }), t.prompt && (_jsx("p", { className: "mt-0.5 line-clamp-2 text-xs text-[var(--agent-muted-foreground,#6b7280)]", children: t.prompt })), (t.dependsOn?.length ?? 0) > 0 && (_jsxs("p", { className: "mt-0.5 text-[10px] uppercase tracking-wider text-[var(--agent-muted-foreground,#9ca3af)]", children: ["\u4F9D\u8D56\uFF1A", t.dependsOn.join(', ')] }))] })] }, t.id));
99
+ }) })] }))] })] }));
100
+ };
101
+ export { STATUS_LABEL as ORCHESTRATION_STATUS_LABEL, DOT_CLASS as ORCHESTRATION_DOT_CLASS };
102
+ export default OrchestrationPlanCard;
103
+ //# sourceMappingURL=OrchestrationPlanCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrchestrationPlanCard.js","sourceRoot":"","sources":["../../src/cards/OrchestrationPlanCard.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * `<PlanSelectorCard />`
3
+ *
4
+ * Two-to-four candidate plans with effort / risk metrics and pros/cons.
5
+ *
6
+ * Calls `onSelect(planId)` once the user picks one. If `payload.selectedPlan`
7
+ * is filled in by the backend the card switches to read-only mode and
8
+ * highlights the chosen plan.
9
+ *
10
+ * Behaviour switches:
11
+ * - `expandableDetails` (default `false`): when on, only the plan summary +
12
+ * metrics + select button are visible by default; approach / pros / cons
13
+ * sit behind a "查看详情" toggle.
14
+ *
15
+ * Slots:
16
+ * - `renderHeader(plansCount)` -- replace the "候选方案 / 为你准备了 N 个方案"
17
+ * label area.
18
+ * - `renderBottomHint({ submitted })` -- swap the hint shown below the list.
19
+ * - `existingGoalPrefix`, `newGoalPrefix` -- localise goal-attribution
20
+ * phrasing.
21
+ */
22
+ import * as React from 'react';
23
+ import type { PlanSelectorPayload } from '@steerable/agent-protocol';
24
+ import { type RenderSlotResult } from './types.js';
25
+ export interface PlanSelectorCardProps {
26
+ payload: PlanSelectorPayload;
27
+ isComplete?: boolean;
28
+ onSelect?: (planId: string) => void;
29
+ className?: string;
30
+ expandableDetails?: boolean;
31
+ existingGoalPrefix?: string;
32
+ newGoalPrefix?: string;
33
+ renderHeader?: (plansCount: number) => RenderSlotResult;
34
+ renderBottomHint?: (args: {
35
+ submitted: boolean;
36
+ }) => RenderSlotResult;
37
+ }
38
+ export declare const PlanSelectorCard: React.FC<PlanSelectorCardProps>;
39
+ export default PlanSelectorCard;
40
+ //# sourceMappingURL=PlanSelectorCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlanSelectorCard.d.ts","sourceRoot":"","sources":["../../src/cards/PlanSelectorCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAarE,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAuChE,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,mBAAmB,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,gBAAgB,CAAC;IACxD,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,OAAO,CAAA;KAAE,KAAK,gBAAgB,CAAC;CACvE;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA+N5D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -0,0 +1,106 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * `<PlanSelectorCard />`
4
+ *
5
+ * Two-to-four candidate plans with effort / risk metrics and pros/cons.
6
+ *
7
+ * Calls `onSelect(planId)` once the user picks one. If `payload.selectedPlan`
8
+ * is filled in by the backend the card switches to read-only mode and
9
+ * highlights the chosen plan.
10
+ *
11
+ * Behaviour switches:
12
+ * - `expandableDetails` (default `false`): when on, only the plan summary +
13
+ * metrics + select button are visible by default; approach / pros / cons
14
+ * sit behind a "查看详情" toggle.
15
+ *
16
+ * Slots:
17
+ * - `renderHeader(plansCount)` -- replace the "候选方案 / 为你准备了 N 个方案"
18
+ * label area.
19
+ * - `renderBottomHint({ submitted })` -- swap the hint shown below the list.
20
+ * - `existingGoalPrefix`, `newGoalPrefix` -- localise goal-attribution
21
+ * phrasing.
22
+ */
23
+ import * as React from 'react';
24
+ import { ClockIcon, FlameIcon, ShieldIcon, CheckIcon, TargetIcon, AlertIcon, ThumbsUpIcon, LoaderIcon, ChevronDownIcon, ChevronUpIcon, } from './icons.js';
25
+ import { asReactNode } from './types.js';
26
+ const EFFORT_CONFIG = {
27
+ low: {
28
+ label: '低投入',
29
+ text: 'text-green-600 dark:text-green-400',
30
+ bg: 'bg-green-50 dark:bg-green-950/30',
31
+ },
32
+ medium: {
33
+ label: '中投入',
34
+ text: 'text-amber-600 dark:text-amber-400',
35
+ bg: 'bg-amber-50 dark:bg-amber-950/30',
36
+ },
37
+ high: {
38
+ label: '高投入',
39
+ text: 'text-red-600 dark:text-red-400',
40
+ bg: 'bg-red-50 dark:bg-red-950/30',
41
+ },
42
+ };
43
+ const RISK_CONFIG = {
44
+ low: {
45
+ label: '低风险',
46
+ text: 'text-green-600 dark:text-green-400',
47
+ bg: 'bg-green-50 dark:bg-green-950/30',
48
+ },
49
+ medium: {
50
+ label: '中风险',
51
+ text: 'text-amber-600 dark:text-amber-400',
52
+ bg: 'bg-amber-50 dark:bg-amber-950/30',
53
+ },
54
+ high: {
55
+ label: '高风险',
56
+ text: 'text-red-600 dark:text-red-400',
57
+ bg: 'bg-red-50 dark:bg-red-950/30',
58
+ },
59
+ };
60
+ export const PlanSelectorCard = ({ payload, isComplete, onSelect, className, expandableDetails = false, existingGoalPrefix = '归属目标:', newGoalPrefix = '新目标:', renderHeader, renderBottomHint, }) => {
61
+ const isReadOnly = Boolean(isComplete || payload.selectedPlan);
62
+ const plans = payload.plans ?? [];
63
+ const [submittingFor, setSubmittingFor] = React.useState(null);
64
+ const [expandedId, setExpandedId] = React.useState(null);
65
+ const goalLabel = (() => {
66
+ const g = payload.goalAttribution;
67
+ if (!g)
68
+ return null;
69
+ if (g.type === 'existing')
70
+ return `${existingGoalPrefix}${g.existingGoalTitle ?? ''}`;
71
+ return `${newGoalPrefix}${g.newGoalTitle ?? ''}`;
72
+ })();
73
+ const handleSelect = (planId) => {
74
+ if (!onSelect || isReadOnly)
75
+ return;
76
+ setSubmittingFor(planId);
77
+ try {
78
+ onSelect(planId);
79
+ }
80
+ finally {
81
+ setSubmittingFor(null);
82
+ }
83
+ };
84
+ return (_jsx("div", { className: [
85
+ 'steerable-plan-selector rounded-lg border border-[var(--agent-border,#e5e7eb)] bg-[var(--agent-card-bg,#fff)] text-sm text-[var(--agent-foreground,#111827)]',
86
+ className,
87
+ ].filter(Boolean).join(' '), children: _jsxs("div", { className: "space-y-3 p-3", children: [renderHeader ? (_jsx("div", { children: asReactNode(renderHeader(plans.length)) })) : (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(TargetIcon, { size: 14, className: "text-blue-500" }), _jsx("span", { className: "text-sm font-medium", children: "\u5019\u9009\u65B9\u6848" }), goalLabel && (_jsxs("span", { className: "text-xs text-[var(--agent-muted-foreground,#6b7280)]", children: ["\u00B7 ", goalLabel] }))] })), renderHeader && goalLabel && (_jsx("p", { className: "text-xs text-[var(--agent-muted-foreground,#6b7280)]", children: goalLabel })), _jsx("div", { className: "space-y-2", children: plans.map((p) => {
88
+ const isSelected = payload.selectedPlan === p.id;
89
+ const effort = EFFORT_CONFIG[p.metrics?.effortLevel || 'medium'];
90
+ const risk = RISK_CONFIG[p.metrics?.riskLevel || 'medium'];
91
+ const isExpanded = expandableDetails ? expandedId === p.id : true;
92
+ return (_jsxs("div", { className: [
93
+ 'rounded-lg border transition-all duration-200',
94
+ isSelected
95
+ ? 'border-blue-400 dark:border-blue-600 bg-blue-50/50 dark:bg-blue-950/20 ring-1 ring-blue-200 dark:ring-blue-800'
96
+ : 'border-[var(--agent-border,#e5e7eb)] bg-[var(--agent-background,#fff)] hover:border-[var(--agent-border,#e5e7eb)]/80',
97
+ isReadOnly && !isSelected ? 'opacity-50' : '',
98
+ ].filter(Boolean).join(' '), children: [_jsxs("div", { className: "p-3", children: [_jsx("div", { className: "flex items-start justify-between gap-2", children: _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("h4", { className: "truncate text-sm font-medium", children: p.name }), isSelected && (_jsxs("span", { className: "inline-flex items-center gap-0.5 rounded-full bg-blue-100 px-1.5 py-0.5 text-[10px] font-medium text-blue-700 dark:bg-blue-900/40 dark:text-blue-300", children: [_jsx(CheckIcon, { size: 10 }), " \u5DF2\u9009\u62E9"] }))] }), _jsx("p", { className: "mt-1 text-xs leading-relaxed text-[var(--agent-muted-foreground,#6b7280)]", children: p.summary })] }) }), _jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-2", children: [p.metrics?.duration && (_jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-[var(--agent-muted,#f3f4f6)] px-2 py-0.5 text-[10px] font-medium text-[var(--agent-muted-foreground,#6b7280)]", children: [_jsx(ClockIcon, { size: 11 }), p.metrics.duration] })), _jsxs("span", { className: `inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-medium ${effort.bg} ${effort.text}`, children: [_jsx(FlameIcon, { size: 11 }), effort.label] }), _jsxs("span", { className: `inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[10px] font-medium ${risk.bg} ${risk.text}`, children: [_jsx(ShieldIcon, { size: 11 }), risk.label] })] }), _jsxs("div", { className: "mt-2 flex items-center justify-between", children: [expandableDetails ? (_jsx("button", { type: "button", onClick: () => setExpandedId(isExpanded ? null : p.id), className: "inline-flex items-center gap-1 text-[11px] text-[var(--agent-muted-foreground,#6b7280)] transition-colors duration-200 hover:text-[var(--agent-foreground,#111827)]", children: isExpanded ? (_jsxs(_Fragment, { children: [_jsx(ChevronUpIcon, { size: 11 }), " \u6536\u8D77\u8BE6\u60C5"] })) : (_jsxs(_Fragment, { children: [_jsx(ChevronDownIcon, { size: 11 }), " \u67E5\u770B\u8BE6\u60C5"] })) })) : (_jsx("span", {})), !isReadOnly && onSelect && (_jsxs("button", { type: "button", onClick: () => handleSelect(p.id), disabled: submittingFor !== null, className: "inline-flex items-center gap-1 rounded-full bg-[var(--agent-primary,#18181b)] px-3 py-1 text-xs font-medium text-[var(--agent-primary-foreground,#fff)] shadow-sm transition-all duration-200 hover:opacity-90 disabled:opacity-50", children: [submittingFor === p.id && _jsx(LoaderIcon, { size: 10 }), "\u9009\u62E9\u6B64\u65B9\u6848"] }))] })] }), isExpanded && (_jsxs("div", { className: "space-y-2 border-t border-[var(--agent-border,#e5e7eb)]/50 px-3 pb-3 pt-2", children: [p.approach && (_jsx("p", { className: "text-xs leading-relaxed", children: p.approach })), _jsxs("div", { className: "grid grid-cols-2 gap-2", children: [(p.pros?.length ?? 0) > 0 && (_jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-1 text-[10px] font-medium text-green-600 dark:text-green-400", children: [_jsx(ThumbsUpIcon, { size: 11 }), "\u4F18\u52BF"] }), p.pros.map((pro, i) => (_jsx("p", { className: "pl-4 text-[11px] text-[var(--agent-muted-foreground,#6b7280)]", children: pro }, `pro-${i}`)))] })), (p.cons?.length ?? 0) > 0 && (_jsxs("div", { className: "space-y-1", children: [_jsxs("div", { className: "flex items-center gap-1 text-[10px] font-medium text-amber-600 dark:text-amber-400", children: [_jsx(AlertIcon, { size: 11 }), "\u6CE8\u610F"] }), p.cons.map((con, i) => (_jsx("p", { className: "pl-4 text-[11px] text-[var(--agent-muted-foreground,#6b7280)]", children: con }, `con-${i}`)))] }))] }), p.bestFor && (_jsxs("p", { className: "text-[11px] italic text-[var(--agent-muted-foreground,#6b7280)]", children: ["\u9002\u5408\uFF1A", p.bestFor] }))] }))] }, p.id));
99
+ }) }), payload.comparison && (_jsx("p", { className: "text-xs text-[var(--agent-muted-foreground,#6b7280)]", children: payload.comparison })), _jsx("div", { className: "flex items-center justify-between pt-1", children: renderBottomHint
100
+ ? asReactNode(renderBottomHint({ submitted: isReadOnly }))
101
+ : !isReadOnly
102
+ ? _jsx("span", { className: "text-xs text-[var(--agent-muted-foreground,#6b7280)]", children: "\u70B9\u51FB\u9009\u62E9\u65B9\u6848" })
103
+ : _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(CheckIcon, { size: 12, className: "text-blue-500" }), _jsx("span", { className: "text-xs text-[var(--agent-muted-foreground,#6b7280)]", children: "\u65B9\u6848\u5DF2\u9009\u62E9" })] }) })] }) }));
104
+ };
105
+ export default PlanSelectorCard;
106
+ //# sourceMappingURL=PlanSelectorCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlanSelectorCard.js","sourceRoot":"","sources":["../../src/cards/PlanSelectorCard.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `<PlanStepsCard />`
3
+ *
4
+ * Compact horizontal checklist of skill names: `step1 / step2 / step3`. Used
5
+ * to show what the agent intends to do this turn. Pure render off
6
+ * `PlanStepsPayload`; the parent passes `isStreaming` if it wants the pulsing
7
+ * cursor dot at the end.
8
+ */
9
+ import * as React from 'react';
10
+ import type { PlanStepsPayload } from '@steerable/agent-protocol';
11
+ export interface PlanStepsCardProps {
12
+ payload: PlanStepsPayload;
13
+ isStreaming?: boolean;
14
+ className?: string;
15
+ }
16
+ export declare const PlanStepsCard: React.FC<PlanStepsCardProps>;
17
+ export default PlanStepsCard;
18
+ //# sourceMappingURL=PlanStepsCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlanStepsCard.d.ts","sourceRoot":"","sources":["../../src/cards/PlanStepsCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAGlE,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA+BtD,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * `<PlanStepsCard />`
4
+ *
5
+ * Compact horizontal checklist of skill names: `step1 / step2 / step3`. Used
6
+ * to show what the agent intends to do this turn. Pure render off
7
+ * `PlanStepsPayload`; the parent passes `isStreaming` if it wants the pulsing
8
+ * cursor dot at the end.
9
+ */
10
+ import * as React from 'react';
11
+ import { ListChecksIcon } from './icons.js';
12
+ export const PlanStepsCard = ({ payload, isStreaming, className }) => {
13
+ const steps = payload.steps ?? [];
14
+ if (steps.length === 0 && !isStreaming)
15
+ return null;
16
+ return (_jsxs("div", { className: [
17
+ 'steerable-plan-steps flex items-start gap-2 rounded-lg border px-3 py-2 transition-all duration-200',
18
+ isStreaming
19
+ ? 'border-[var(--agent-border,#e5e7eb)] bg-[var(--agent-card-bg,#f9fafb)] shadow-sm'
20
+ : 'border-[var(--agent-border,#e5e7eb)] bg-[var(--agent-muted,#f3f4f6)]',
21
+ className,
22
+ ].filter(Boolean).join(' '), children: [_jsx(ListChecksIcon, { size: 14, className: "mt-0.5 flex-shrink-0 text-[var(--agent-muted-foreground,#6b7280)]" }), _jsxs("div", { className: "flex flex-wrap items-center gap-1 text-xs text-[var(--agent-muted-foreground,#6b7280)]", children: [steps.map((step, idx) => (_jsxs(React.Fragment, { children: [idx > 0 && _jsx("span", { "aria-hidden": true, className: "select-none opacity-40", children: "/" }), _jsx("span", { className: "whitespace-nowrap", children: step })] }, `${idx}-${step}`))), isStreaming && (_jsx("span", { "aria-hidden": true, className: "ml-1 inline-block h-1.5 w-1.5 translate-y-[1px] animate-pulse rounded-full bg-current" }))] })] }));
23
+ };
24
+ export default PlanStepsCard;
25
+ //# sourceMappingURL=PlanStepsCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlanStepsCard.js","sourceRoot":"","sources":["../../src/cards/PlanStepsCard.tsx"],"names":[],"mappings":";AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAQ5C,MAAM,CAAC,MAAM,aAAa,GAAiC,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,EAAE;IACjG,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;IAClC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAEpD,OAAO,CACL,eACE,SAAS,EAAE;YACT,qGAAqG;YACrG,WAAW;gBACT,CAAC,CAAC,kFAAkF;gBACpF,CAAC,CAAC,sEAAsE;YAC1E,SAAS;SACV,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,aAE3B,KAAC,cAAc,IAAC,IAAI,EAAE,EAAE,EAAE,SAAS,EAAC,mEAAmE,GAAG,EAC1G,eAAK,SAAS,EAAC,wFAAwF,aACpG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,CACxB,MAAC,KAAK,CAAC,QAAQ,eACZ,GAAG,GAAG,CAAC,IAAI,oCAAkB,SAAS,EAAC,wBAAwB,kBAAS,EACzE,eAAM,SAAS,EAAC,mBAAmB,YAAE,IAAI,GAAQ,KAF9B,GAAG,GAAG,IAAI,IAAI,EAAE,CAGpB,CAClB,CAAC,EACD,WAAW,IAAI,CACd,oCAEE,SAAS,EAAC,uFAAuF,GACjG,CACH,IACG,IACF,CACP,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * `<QuizCard />`
3
+ *
4
+ * Renders a multi-question quiz: choice / fill / judge / short_answer types.
5
+ * The card manages an internal draft, calls `onSubmit(answers)` once, and
6
+ * switches to read-only mode if `isComplete` is true (or the backend re-emits
7
+ * with `payload.submittedAnswers` filled in).
8
+ *
9
+ * Variants:
10
+ * - `choiceVariant`: 'pills' (default; chip-style buttons) | 'radio' (native
11
+ * radio/checkbox inputs in a vertical list).
12
+ * - `questionVariant`: 'flat' (default) | 'card' (each question gets its own
13
+ * bordered inner card).
14
+ *
15
+ * Slots:
16
+ * - `judgeLabels`: tuple for "true"/"false" buttons. Default `['对', '错']`.
17
+ * - `submitHint`, `submittedMessage`, `submittingLabel`: localisable
18
+ * status strings.
19
+ * - `renderQuestionMeta(question)`: append metadata under the stem (e.g.
20
+ * difficulty + points badges).
21
+ */
22
+ import * as React from 'react';
23
+ import type { QuizPayload } from '@steerable/agent-protocol';
24
+ import { type RenderSlotResult } from './types.js';
25
+ type AnswerValue = string | string[];
26
+ type Question = QuizPayload['questions'][number];
27
+ export type QuizChoiceVariant = 'pills' | 'radio';
28
+ export type QuizQuestionVariant = 'flat' | 'card';
29
+ export interface QuizCardProps {
30
+ payload: QuizPayload;
31
+ isComplete?: boolean;
32
+ onSubmit?: (answers: Record<string, AnswerValue>) => void;
33
+ className?: string;
34
+ choiceVariant?: QuizChoiceVariant;
35
+ questionVariant?: QuizQuestionVariant;
36
+ judgeLabels?: [string, string];
37
+ submitHint?: React.ReactNode;
38
+ submittedMessage?: React.ReactNode;
39
+ submittingLabel?: React.ReactNode;
40
+ renderQuestionMeta?: (question: Question) => RenderSlotResult;
41
+ }
42
+ export declare const QuizCard: React.FC<QuizCardProps>;
43
+ export default QuizCard;
44
+ //# sourceMappingURL=QuizCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuizCard.d.ts","sourceRoot":"","sources":["../../src/cards/QuizCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAE7D,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEhE,KAAK,WAAW,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AACrC,KAAK,QAAQ,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,OAAO,CAAC;AAClD,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,CAAC;AAElD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,KAAK,IAAI,CAAC;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,eAAe,CAAC,EAAE,mBAAmB,CAAC;IACtC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,gBAAgB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACnC,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAClC,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,gBAAgB,CAAC;CAC/D;AAOD,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CA+P5C,CAAC;AAEF,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,113 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * `<QuizCard />`
4
+ *
5
+ * Renders a multi-question quiz: choice / fill / judge / short_answer types.
6
+ * The card manages an internal draft, calls `onSubmit(answers)` once, and
7
+ * switches to read-only mode if `isComplete` is true (or the backend re-emits
8
+ * with `payload.submittedAnswers` filled in).
9
+ *
10
+ * Variants:
11
+ * - `choiceVariant`: 'pills' (default; chip-style buttons) | 'radio' (native
12
+ * radio/checkbox inputs in a vertical list).
13
+ * - `questionVariant`: 'flat' (default) | 'card' (each question gets its own
14
+ * bordered inner card).
15
+ *
16
+ * Slots:
17
+ * - `judgeLabels`: tuple for "true"/"false" buttons. Default `['对', '错']`.
18
+ * - `submitHint`, `submittedMessage`, `submittingLabel`: localisable
19
+ * status strings.
20
+ * - `renderQuestionMeta(question)`: append metadata under the stem (e.g.
21
+ * difficulty + points badges).
22
+ */
23
+ import * as React from 'react';
24
+ import { ClipboardIcon, LoaderIcon, CheckIcon } from './icons.js';
25
+ import { asReactNode } from './types.js';
26
+ function emptyAnswer(q) {
27
+ if (q.type === 'choice' && q.allowMultiple)
28
+ return [];
29
+ return '';
30
+ }
31
+ export const QuizCard = ({ payload, isComplete, onSubmit, className, choiceVariant = 'pills', questionVariant = 'flat', judgeLabels = ['对', '错'], submitHint, submittedMessage, submittingLabel = '提交中...', renderQuestionMeta, }) => {
32
+ const isReadOnly = Boolean(isComplete ||
33
+ (payload.submittedAnswers && Object.keys(payload.submittedAnswers).length > 0));
34
+ const initial = React.useMemo(() => {
35
+ const seed = {};
36
+ for (const q of payload.questions ?? []) {
37
+ seed[q.id] = (payload.submittedAnswers?.[q.id] ?? emptyAnswer(q));
38
+ }
39
+ return seed;
40
+ }, [payload.questions, payload.submittedAnswers]);
41
+ const [draft, setDraft] = React.useState(initial);
42
+ const [submitting, setSubmitting] = React.useState(false);
43
+ React.useEffect(() => {
44
+ setDraft(initial);
45
+ }, [initial]);
46
+ const setSingle = (qId, value) => setDraft((p) => ({ ...p, [qId]: value }));
47
+ const toggleMulti = (qId, opt) => setDraft((p) => {
48
+ const cur = (p[qId] ?? []);
49
+ return { ...p, [qId]: cur.includes(opt) ? cur.filter((v) => v !== opt) : [...cur, opt] };
50
+ });
51
+ const handleSubmit = async () => {
52
+ if (!onSubmit)
53
+ return;
54
+ setSubmitting(true);
55
+ try {
56
+ onSubmit(draft);
57
+ }
58
+ finally {
59
+ setSubmitting(false);
60
+ }
61
+ };
62
+ const renderChoice = (q, value) => {
63
+ const options = q.options ?? [];
64
+ if (choiceVariant === 'radio') {
65
+ return (_jsx("div", { className: "space-y-1.5", children: options.map((opt) => {
66
+ const checked = Array.isArray(value) ? value.includes(opt) : value === opt;
67
+ return (_jsxs("label", { className: "flex cursor-pointer items-start gap-2 text-sm", children: [_jsx("input", { type: q.allowMultiple ? 'checkbox' : 'radio', name: q.id, checked: checked, disabled: isReadOnly, className: "mt-[3px] h-4 w-4 shrink-0", onChange: () => (q.allowMultiple ? toggleMulti(q.id, opt) : setSingle(q.id, opt)) }), _jsx("span", { className: "min-w-0 break-words leading-relaxed", children: opt })] }, opt));
68
+ }) }));
69
+ }
70
+ return (_jsx("div", { className: "flex flex-wrap gap-2", children: options.map((opt) => {
71
+ const selected = q.allowMultiple
72
+ ? (Array.isArray(value) ? value : []).includes(opt)
73
+ : value === opt;
74
+ return (_jsx("button", { type: "button", disabled: isReadOnly, onClick: () => (q.allowMultiple ? toggleMulti(q.id, opt) : setSingle(q.id, opt)), className: [
75
+ 'rounded-full border px-3 py-1 text-xs transition-colors duration-150',
76
+ selected
77
+ ? 'border-[var(--agent-primary,#18181b)] bg-[var(--agent-primary,#18181b)] text-[var(--agent-primary-foreground,#fff)]'
78
+ : 'border-[var(--agent-border,#e5e7eb)] bg-[var(--agent-card-bg,#fff)] hover:bg-[var(--agent-accent,#f3f4f6)]',
79
+ isReadOnly ? 'cursor-default opacity-80' : '',
80
+ ].filter(Boolean).join(' '), children: opt }, opt));
81
+ }) }));
82
+ };
83
+ const renderJudge = (q, value) => {
84
+ if (choiceVariant === 'radio') {
85
+ return (_jsx("div", { className: "flex flex-wrap items-center gap-x-4 gap-y-1.5", children: judgeLabels.map((opt) => (_jsxs("label", { className: "flex cursor-pointer items-center gap-2", children: [_jsx("input", { type: "radio", name: q.id, checked: value === opt, disabled: isReadOnly, onChange: () => setSingle(q.id, opt), className: "h-4 w-4 shrink-0" }), _jsx("span", { children: opt })] }, opt))) }));
86
+ }
87
+ return (_jsx("div", { className: "flex gap-2", children: judgeLabels.map((opt) => (_jsx("button", { type: "button", disabled: isReadOnly, onClick: () => setSingle(q.id, opt), className: [
88
+ 'rounded-full border px-3 py-1 text-xs transition-colors duration-150',
89
+ value === opt
90
+ ? 'border-[var(--agent-primary,#18181b)] bg-[var(--agent-primary,#18181b)] text-[var(--agent-primary-foreground,#fff)]'
91
+ : 'border-[var(--agent-border,#e5e7eb)] hover:bg-[var(--agent-accent,#f3f4f6)]',
92
+ ].filter(Boolean).join(' '), children: opt }, opt))) }));
93
+ };
94
+ const renderTextarea = (q, value) => (_jsx("textarea", { rows: q.type === 'short_answer' ? 4 : 2, value: typeof value === 'string' ? value : '', disabled: isReadOnly, placeholder: q.placeholder ?? '请输入你的答案', onChange: (e) => setSingle(q.id, e.target.value), className: "w-full rounded-md border border-[var(--agent-border,#e5e7eb)] bg-[var(--agent-card-bg,#fff)] px-3 py-2 text-sm text-[var(--agent-foreground,#111827)] outline-none transition-all duration-200 focus:border-[var(--agent-primary,#18181b)]" }));
95
+ const defaultMeta = (q) => {
96
+ if (!q.difficulty && !q.points)
97
+ return null;
98
+ return (_jsxs(_Fragment, { children: [q.difficulty ? _jsxs("span", { children: ["\u96BE\u5EA6 ", q.difficulty] }) : null, q.points ? _jsxs("span", { children: [q.points, " \u5206"] }) : null] }));
99
+ };
100
+ return (_jsx("div", { className: [
101
+ 'steerable-quiz overflow-hidden rounded-lg border border-[var(--agent-border,#e5e7eb)] bg-[var(--agent-card-bg,#fff)] text-sm text-[var(--agent-foreground,#111827)]',
102
+ className,
103
+ ].filter(Boolean).join(' '), children: _jsxs("div", { className: "space-y-3 p-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(ClipboardIcon, { size: 14, className: "shrink-0 text-blue-500" }), _jsx("span", { className: "break-words font-medium", children: payload.title }), isReadOnly && _jsx(CheckIcon, { size: 12, className: "text-emerald-600" })] }), payload.description && (_jsx("p", { className: "break-words text-xs leading-relaxed text-[var(--agent-muted-foreground,#6b7280)]", children: payload.description })), _jsx("div", { className: questionVariant === 'card' ? 'space-y-3' : 'space-y-4', children: (payload.questions ?? []).map((q, idx) => {
104
+ const value = draft[q.id] ?? emptyAnswer(q);
105
+ const metaNode = renderQuestionMeta
106
+ ? asReactNode(renderQuestionMeta(q))
107
+ : defaultMeta(q);
108
+ const inner = (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mb-2", children: [_jsxs("p", { className: "break-words text-sm font-medium leading-relaxed", children: [idx + 1, ". ", q.stem] }), metaNode && (_jsx("div", { className: "mt-1 flex flex-wrap items-center gap-x-2 gap-y-0.5 text-[11px] text-[var(--agent-muted-foreground,#6b7280)]", children: metaNode }))] }), q.type === 'choice' && q.options ? renderChoice(q, value) : null, q.type === 'judge' ? renderJudge(q, value) : null, q.type === 'fill' || q.type === 'short_answer' ? renderTextarea(q, value) : null] }));
109
+ return questionVariant === 'card' ? (_jsx("div", { className: "rounded-lg border border-[var(--agent-border,#e5e7eb)] bg-[var(--agent-background,#fff)] p-3", children: inner }, q.id)) : (_jsx("div", { className: "space-y-1.5", children: inner }, q.id));
110
+ }) }), _jsxs("div", { className: "flex flex-wrap items-center justify-between gap-x-3 gap-y-2 pt-1", children: [isReadOnly ? (_jsxs("div", { className: "inline-flex min-w-0 items-center gap-1.5 text-xs text-green-600 dark:text-green-400", children: [_jsx(CheckIcon, { size: 12 }), _jsx("span", { className: "truncate", children: submittedMessage ?? '已提交' })] })) : (submitHint && (_jsx("span", { className: "min-w-0 flex-1 break-words text-xs text-[var(--agent-muted-foreground,#6b7280)]", children: submitHint }))), !isReadOnly && onSubmit && (_jsx("button", { type: "button", onClick: handleSubmit, disabled: submitting || isReadOnly, className: "ml-auto inline-flex h-[28px] shrink-0 items-center gap-1 rounded-full bg-[var(--agent-primary,#18181b)] px-3 text-xs font-medium text-[var(--agent-primary-foreground,#fff)] transition-all duration-200 hover:opacity-90 disabled:opacity-50", children: submitting ? (_jsxs(_Fragment, { children: [_jsx(LoaderIcon, { size: 10, className: "animate-spin" }), submittingLabel] })) : (payload.submitActionLabel || '提交') }))] })] }) }));
111
+ };
112
+ export default QuizCard;
113
+ //# sourceMappingURL=QuizCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"QuizCard.js","sourceRoot":"","sources":["../../src/cards/QuizCard.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * `<ResearchPlanCard />`
3
+ *
4
+ * Snapshot of a research agent's current sub-question tree, with per-question
5
+ * status badges (searching / strong evidence / conflicted / ...) and the
6
+ * coordinator's decision for the next round.
7
+ *
8
+ * Features:
9
+ * - progress bar (round / totalRounds);
10
+ * - sub-question note rendering when `note` is present;
11
+ * - boxed "next decision" footer with the agent's reasoning.
12
+ */
13
+ import * as React from 'react';
14
+ import type { ResearchPlanPayload } from '@steerable/agent-protocol';
15
+ export interface ResearchPlanCardProps {
16
+ payload: ResearchPlanPayload;
17
+ /** Total expected rounds (used to compute the progress bar). Defaults to 3. */
18
+ totalRounds?: number;
19
+ className?: string;
20
+ }
21
+ export declare const ResearchPlanCard: React.FC<ResearchPlanCardProps>;
22
+ export default ResearchPlanCard;
23
+ //# sourceMappingURL=ResearchPlanCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResearchPlanCard.d.ts","sourceRoot":"","sources":["../../src/cards/ResearchPlanCard.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AA8CrE,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,mBAAmB,CAAC;IAC7B,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAoG5D,CAAC;AAEF,eAAe,gBAAgB,CAAC"}