@slipstream-ui/ai 0.0.0-stage → 0.4.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 (111) hide show
  1. package/LICENSE +25 -0
  2. package/dist/index.d.mts +579 -0
  3. package/dist/index.d.ts +579 -0
  4. package/dist/index.js +1778 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/index.mjs +1706 -0
  7. package/dist/index.mjs.map +1 -0
  8. package/dist/manifests/attachment.manifest.json +33 -0
  9. package/dist/manifests/branch.manifest.json +65 -0
  10. package/dist/manifests/chain-thought.manifest.json +39 -0
  11. package/dist/manifests/code-block.manifest.json +50 -0
  12. package/dist/manifests/command-palette.manifest.json +80 -0
  13. package/dist/manifests/confirmation.manifest.json +143 -0
  14. package/dist/manifests/conversation.manifest.json +290 -0
  15. package/dist/manifests/inline-citation.manifest.json +46 -0
  16. package/dist/manifests/message-actions.manifest.json +35 -0
  17. package/dist/manifests/message.manifest.json +235 -0
  18. package/dist/manifests/prompt-input.manifest.json +334 -0
  19. package/dist/manifests/reasoning.manifest.json +177 -0
  20. package/dist/manifests/response.manifest.json +51 -0
  21. package/dist/manifests/source.manifest.json +78 -0
  22. package/dist/manifests/streaming-indicator.manifest.json +39 -0
  23. package/dist/manifests/suggestions.manifest.json +45 -0
  24. package/dist/manifests/tool-call.manifest.json +158 -0
  25. package/package.json +61 -3
  26. package/src/adapter/adapter.test.tsx +83 -0
  27. package/src/adapter/hooks.ts +82 -0
  28. package/src/adapter/index.ts +3 -0
  29. package/src/adapter/messages.ts +49 -0
  30. package/src/adapter/types.ts +24 -0
  31. package/src/components/attachment/Attachment.test.tsx +72 -0
  32. package/src/components/attachment/Attachment.tsx +84 -0
  33. package/src/components/attachment/AttachmentList.tsx +30 -0
  34. package/src/components/attachment/index.ts +5 -0
  35. package/src/components/branch/Branch.test.tsx +52 -0
  36. package/src/components/branch/Branch.tsx +77 -0
  37. package/src/components/branch/index.ts +2 -0
  38. package/src/components/chainthought/ChainThought.test.tsx +34 -0
  39. package/src/components/chainthought/ChainThought.tsx +45 -0
  40. package/src/components/chainthought/index.ts +2 -0
  41. package/src/components/code-block/CodeBlock.test.tsx +46 -0
  42. package/src/components/code-block/CodeBlock.tsx +95 -0
  43. package/src/components/code-block/index.ts +2 -0
  44. package/src/components/command-palette/CommandPalette.test.tsx +74 -0
  45. package/src/components/command-palette/CommandPalette.tsx +156 -0
  46. package/src/components/command-palette/index.ts +2 -0
  47. package/src/components/confirmation/Confirmation.test.tsx +97 -0
  48. package/src/components/confirmation/Confirmation.tsx +146 -0
  49. package/src/components/confirmation/index.ts +2 -0
  50. package/src/components/conversation/Conversation.test.tsx +49 -0
  51. package/src/components/conversation/Conversation.tsx +301 -0
  52. package/src/components/conversation/Conversation.welcome.test.tsx +73 -0
  53. package/src/components/conversation/index.ts +2 -0
  54. package/src/components/inline-citation/InlineCitation.test.tsx +42 -0
  55. package/src/components/inline-citation/InlineCitation.tsx +56 -0
  56. package/src/components/inline-citation/index.ts +2 -0
  57. package/src/components/message/Message.error-edit.test.tsx +60 -0
  58. package/src/components/message/Message.test.tsx +80 -0
  59. package/src/components/message/Message.tsx +205 -0
  60. package/src/components/message/index.ts +2 -0
  61. package/src/components/message-actions/MessageActions.test.tsx +77 -0
  62. package/src/components/message-actions/MessageActions.tsx +134 -0
  63. package/src/components/message-actions/index.ts +2 -0
  64. package/src/components/prompt-input/PromptInput.compound.test.tsx +150 -0
  65. package/src/components/prompt-input/PromptInput.test.tsx +74 -0
  66. package/src/components/prompt-input/PromptInput.tsx +584 -0
  67. package/src/components/prompt-input/index.ts +21 -0
  68. package/src/components/reasoning/Reasoning.duration.test.tsx +35 -0
  69. package/src/components/reasoning/Reasoning.test.tsx +58 -0
  70. package/src/components/reasoning/Reasoning.tsx +85 -0
  71. package/src/components/reasoning/index.ts +2 -0
  72. package/src/components/response/Response.test.tsx +69 -0
  73. package/src/components/response/Response.tsx +75 -0
  74. package/src/components/response/close-incomplete-markdown.ts +47 -0
  75. package/src/components/response/index.ts +3 -0
  76. package/src/components/source/Source.tsx +51 -0
  77. package/src/components/source/Sources.tsx +42 -0
  78. package/src/components/source/index.ts +5 -0
  79. package/src/components/source/source.test.tsx +72 -0
  80. package/src/components/streaming/StreamingIndicator.test.tsx +26 -0
  81. package/src/components/streaming/StreamingIndicator.tsx +46 -0
  82. package/src/components/streaming/index.ts +2 -0
  83. package/src/components/suggestion/Suggestion.test.tsx +43 -0
  84. package/src/components/suggestion/Suggestion.tsx +47 -0
  85. package/src/components/suggestion/index.ts +2 -0
  86. package/src/components/tool-call/ToolCall.test.tsx +45 -0
  87. package/src/components/tool-call/ToolCall.tsx +101 -0
  88. package/src/components/tool-call/index.ts +2 -0
  89. package/src/index.ts +29 -0
  90. package/src/manifests/attachment.manifest.json +33 -0
  91. package/src/manifests/branch.manifest.json +65 -0
  92. package/src/manifests/chain-thought.manifest.json +39 -0
  93. package/src/manifests/code-block.manifest.json +50 -0
  94. package/src/manifests/command-palette.manifest.json +80 -0
  95. package/src/manifests/confirmation.manifest.json +143 -0
  96. package/src/manifests/conversation.manifest.json +290 -0
  97. package/src/manifests/inline-citation.manifest.json +46 -0
  98. package/src/manifests/message-actions.manifest.json +35 -0
  99. package/src/manifests/message.manifest.json +235 -0
  100. package/src/manifests/prompt-input.manifest.json +334 -0
  101. package/src/manifests/reasoning.manifest.json +177 -0
  102. package/src/manifests/response.manifest.json +51 -0
  103. package/src/manifests/source.manifest.json +78 -0
  104. package/src/manifests/streaming-indicator.manifest.json +39 -0
  105. package/src/manifests/suggestions.manifest.json +45 -0
  106. package/src/manifests/tool-call.manifest.json +158 -0
  107. package/src/test/jest-axe.d.ts +16 -0
  108. package/src/test/setup.ts +18 -0
  109. package/src/test/vitest-matchers.d.ts +10 -0
  110. package/src/types/index.ts +40 -0
  111. package/README.md +0 -3
@@ -0,0 +1,177 @@
1
+ {
2
+ "id": "reasoning",
3
+ "name": "Reasoning",
4
+ "tier": "molecule",
5
+ "description": "A collapsible component for displaying AI reasoning steps and chain-of-thought processes",
6
+ "designIntent": "The Reasoning component displays the step-by-step thought process of an AI agent. It's collapsible to avoid cluttering the interface while still providing transparency into how the AI arrived at its conclusions.",
7
+ "props": [
8
+ {
9
+ "name": "steps",
10
+ "type": "ReasoningStep[]",
11
+ "required": true,
12
+ "description": "Array of reasoning steps to display",
13
+ "examples": [
14
+ "[{ id: '1', content: 'Analyzing the request...' }, { id: '2', content: 'Formulating response...' }]"
15
+ ]
16
+ },
17
+ {
18
+ "name": "collapsible",
19
+ "type": "boolean",
20
+ "defaultValue": "true",
21
+ "required": false,
22
+ "description": "Whether the reasoning can be collapsed/expanded",
23
+ "examples": [
24
+ true,
25
+ false
26
+ ]
27
+ },
28
+ {
29
+ "name": "defaultExpanded",
30
+ "type": "boolean",
31
+ "defaultValue": "false",
32
+ "required": false,
33
+ "description": "Whether the reasoning is expanded by default",
34
+ "examples": [
35
+ true,
36
+ false
37
+ ]
38
+ },
39
+ {
40
+ "name": "className",
41
+ "type": "string",
42
+ "required": false,
43
+ "description": "Additional CSS classes to apply"
44
+ },
45
+ {
46
+ "name": "duration",
47
+ "type": "number",
48
+ "required": false,
49
+ "description": "Elapsed reasoning time in seconds; renders a duration chip"
50
+ },
51
+ {
52
+ "name": "isStreaming",
53
+ "type": "boolean",
54
+ "required": false,
55
+ "description": "Shows a streaming indicator while reasoning is in progress"
56
+ }
57
+ ],
58
+ "examples": [
59
+ {
60
+ "title": "Basic reasoning",
61
+ "code": "<Reasoning \n steps={[\n { id: '1', content: 'I need to analyze the user\\'s request.' },\n { id: '2', content: 'The user wants to know about React components.' },\n { id: '3', content: 'I should provide a comprehensive answer.' }\n ]}\n/>",
62
+ "description": "Collapsible reasoning with multiple steps"
63
+ },
64
+ {
65
+ "title": "Expanded by default",
66
+ "code": "<Reasoning \n steps={steps}\n defaultExpanded={true}\n/>",
67
+ "description": "Reasoning that shows steps immediately"
68
+ },
69
+ {
70
+ "title": "Non-collapsible",
71
+ "code": "<Reasoning \n steps={steps}\n collapsible={false}\n/>",
72
+ "description": "Reasoning that cannot be collapsed"
73
+ },
74
+ {
75
+ "title": "With timestamps",
76
+ "code": "<Reasoning \n steps={[\n { id: '1', content: 'Step 1', timestamp: new Date() },\n { id: '2', content: 'Step 2', timestamp: new Date() }\n ]}\n/>",
77
+ "description": "Reasoning steps with timing information"
78
+ }
79
+ ],
80
+ "antiPatterns": [
81
+ {
82
+ "title": "Don't show reasoning for simple responses",
83
+ "explanation": "Reasoning is valuable for complex tasks but adds noise for simple responses.",
84
+ "example": "// Avoid: Showing reasoning for trivial responses\n<Reasoning steps={[\n { id: '1', content: 'I will say hello' }\n]} />\n<Message message={{ role: 'assistant', content: 'Hello!' }} />\n\n// Prefer: Only show reasoning for complex tasks\n<Reasoning steps={complexReasoning} />\n<Message message={{ role: 'assistant', content: complexResponse }} />"
85
+ },
86
+ {
87
+ "title": "Don't make steps too verbose",
88
+ "explanation": "Reasoning steps should be concise and focused on key decision points.",
89
+ "example": "// Avoid: Overly detailed steps\n{ id: '1', content: 'I am now processing the request by analyzing each word and considering multiple interpretations...' }\n\n// Prefer: Concise, clear steps\n{ id: '1', content: 'Analyzing the request for key terms and intent.' }"
90
+ },
91
+ {
92
+ "title": "Don't show empty reasoning",
93
+ "explanation": "The component returns null for empty arrays, but it's better to not render it at all.",
94
+ "example": "// Avoid: Rendering with no steps\n<Reasoning steps={[]} />\n\n// Prefer: Conditionally render\n{reasoningSteps.length > 0 && <Reasoning steps={reasoningSteps} />"
95
+ }
96
+ ],
97
+ "accessibility": [
98
+ {
99
+ "feature": "Collapsible state",
100
+ "implementation": "Uses aria-expanded to communicate collapsible state to screen readers",
101
+ "userRequirements": "Ensure the expanded/collapsed state is clear to all users"
102
+ },
103
+ {
104
+ "feature": "Keyboard navigation",
105
+ "implementation": "Collapsible button is keyboard accessible with Enter/Space to toggle",
106
+ "userRequirements": "Test keyboard navigation of the collapse/expand functionality"
107
+ },
108
+ {
109
+ "feature": "Visual hierarchy",
110
+ "implementation": "Steps are numbered and visually distinct with clear hierarchy",
111
+ "userRequirements": "Ensure step numbers and content have sufficient contrast"
112
+ }
113
+ ],
114
+ "contentGuidelines": [
115
+ {
116
+ "contentType": "Reasoning step content",
117
+ "guidelines": [
118
+ "Each step should represent a distinct decision or action",
119
+ "Use clear, concise language",
120
+ "Focus on the 'why' and 'how', not just the 'what'",
121
+ "Avoid overly technical jargon unless necessary",
122
+ "Structure steps logically (chronological or hierarchical)"
123
+ ],
124
+ "goodExamples": [
125
+ "Analyzing the user's request for key requirements",
126
+ "Considering multiple approaches to solve the problem",
127
+ "Selecting the most efficient solution based on constraints"
128
+ ],
129
+ "badExamples": [
130
+ "I am thinking about what to do",
131
+ "Processing...",
132
+ "Step 1",
133
+ "Lorem ipsum dolor sit amet"
134
+ ]
135
+ },
136
+ {
137
+ "contentType": "Step count",
138
+ "guidelines": [
139
+ "Show the total number of steps in the header",
140
+ "Number each step sequentially for easy reference",
141
+ "Keep step count reasonable (typically under 10 steps)",
142
+ "If there are many steps, consider grouping them"
143
+ ],
144
+ "goodExamples": [
145
+ "Reasoning (5 steps)",
146
+ "Step 1 of 5"
147
+ ],
148
+ "badExamples": [
149
+ "Reasoning",
150
+ "Step 1",
151
+ "Showing 47 steps"
152
+ ]
153
+ }
154
+ ],
155
+ "compositionRules": [
156
+ {
157
+ "component": "Message",
158
+ "relationship": "Reasoning is typically displayed before or within an assistant's message to show thought process",
159
+ "example": "Message component can contain Reasoning to show the AI's thinking before the final response"
160
+ },
161
+ {
162
+ "component": "ToolCall",
163
+ "relationship": "Reasoning often precedes tool calls to explain why a tool is being used",
164
+ "example": "Reasoning explains the decision to use a tool, ToolCall shows the actual tool invocation"
165
+ }
166
+ ],
167
+ "relatedComponents": [
168
+ "Message",
169
+ "ToolCall",
170
+ "Conversation"
171
+ ],
172
+ "package": "@slipstream-ui/ai",
173
+ "importPath": "@slipstream-ui/ai",
174
+ "version": "0.0.1",
175
+ "sourceDir": "reasoning",
176
+ "exportName": "Reasoning"
177
+ }
@@ -0,0 +1,51 @@
1
+ {
2
+ "id": "response",
3
+ "name": "Response",
4
+ "tier": "molecule",
5
+ "description": "Streaming-optimized markdown renderer for AI responses with GFM support, streaming-safe repair of incomplete syntax, and highlighted code blocks with copy.",
6
+ "designIntent": "Render AI output as rich content without flicker or broken partial syntax while tokens arrive.",
7
+ "props": [
8
+ {
9
+ "name": "children",
10
+ "type": "string",
11
+ "required": true,
12
+ "description": "Markdown content to render."
13
+ },
14
+ {
15
+ "name": "parseIncompleteMarkdown",
16
+ "type": "boolean",
17
+ "defaultValue": true,
18
+ "required": false,
19
+ "description": "Close unclosed emphasis/inline-code/fences during streaming."
20
+ }
21
+ ],
22
+ "examples": [
23
+ {
24
+ "title": "Basic response",
25
+ "code": "<Response>{assistantMessage.content}</Response>"
26
+ },
27
+ {
28
+ "title": "Inside Message",
29
+ "code": "<Message message={m} renderContent={(c) => <Response>{c}</Response>} />"
30
+ }
31
+ ],
32
+ "antiPatterns": [
33
+ {
34
+ "title": "Do not use Response inside a code fence context",
35
+ "explanation": "Response is the top-level renderer; nested Response instances double-parse content."
36
+ }
37
+ ],
38
+ "accessibility": [
39
+ {
40
+ "feature": "Semantic HTML",
41
+ "implementation": "Headings, lists and tables are real elements announced correctly."
42
+ },
43
+ {
44
+ "feature": "Code blocks",
45
+ "implementation": "Routed through CodeBlock with accessible copy button."
46
+ }
47
+ ],
48
+ "package": "@slipstream-ui/ai",
49
+ "importPath": "@slipstream-ui/ai",
50
+ "version": "0.0.1"
51
+ }
@@ -0,0 +1,78 @@
1
+ {
2
+ "id": "source",
3
+ "name": "Source / Sources",
4
+ "tier": "molecule",
5
+ "description": "Displays citations and references for an AI response. `Source` renders a single citation; `Sources` renders a numbered list with an overflow count.",
6
+ "designIntent": "Make generated answers transparent by showing where information came from.",
7
+ "props": [
8
+ {
9
+ "name": "index",
10
+ "type": "number",
11
+ "required": false,
12
+ "description": "1-based citation marker rendered as [n]; omit on Source to hide numbering."
13
+ },
14
+ {
15
+ "name": "source",
16
+ "type": "SourceItem",
17
+ "required": true,
18
+ "description": "The single source to render (Source component)"
19
+ },
20
+ {
21
+ "name": "onSelect",
22
+ "type": "(source: SourceItem) => void",
23
+ "required": false,
24
+ "description": "Called when the source chip is clicked"
25
+ },
26
+ {
27
+ "name": "sources",
28
+ "type": "SourceItem[]",
29
+ "required": true,
30
+ "description": "List of sources to render (Sources component)"
31
+ },
32
+ {
33
+ "name": "maxDisplay",
34
+ "type": "number",
35
+ "defaultValue": "3",
36
+ "required": false,
37
+ "description": "Maximum number of source chips to show before collapsing (Sources component)"
38
+ },
39
+ {
40
+ "name": "label",
41
+ "type": "string",
42
+ "defaultValue": "Sources",
43
+ "required": false,
44
+ "description": "Section label above the source list (Sources component)"
45
+ }
46
+ ],
47
+ "examples": [
48
+ {
49
+ "title": "Citations list",
50
+ "code": "<Sources sources={[{ id: '1', title: 'React docs', url: 'https://react.dev' }, { id: '2', title: 'MDN', url: 'https://developer.mozilla.org' }]} />"
51
+ },
52
+ {
53
+ "title": "Single inline citation",
54
+ "code": "<Source source={{ id: '1', title: 'React docs', url: 'https://react.dev' }} index={1} />"
55
+ }
56
+ ],
57
+ "antiPatterns": [
58
+ {
59
+ "title": "Do not nest Sources inside Sources",
60
+ "explanation": "Sources is a list container; compose individual Source items only when building a custom layout."
61
+ }
62
+ ],
63
+ "accessibility": [
64
+ {
65
+ "feature": "Link semantics",
66
+ "implementation": "References use native links with rel=noopener when URLs are provided."
67
+ },
68
+ {
69
+ "feature": "Decorative markers",
70
+ "implementation": "[n] citation markers are aria-hidden; titles are read as link text."
71
+ }
72
+ ],
73
+ "package": "@slipstream-ui/ai",
74
+ "importPath": "@slipstream-ui/ai",
75
+ "version": "0.0.1",
76
+ "sourceDir": "source",
77
+ "exportName": "Source"
78
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "id": "streaming-indicator",
3
+ "name": "StreamingIndicator",
4
+ "tier": "atom",
5
+ "description": "Shows that an AI response is currently streaming.",
6
+ "designIntent": "Give users immediate feedback while generated content is arriving.",
7
+ "props": [
8
+ {
9
+ "name": "isStreaming",
10
+ "type": "boolean",
11
+ "required": true,
12
+ "description": "Whether the indicator is visible."
13
+ },
14
+ {
15
+ "name": "text",
16
+ "type": "string",
17
+ "defaultValue": "Generating…",
18
+ "required": false,
19
+ "description": "Status text."
20
+ }
21
+ ],
22
+ "examples": [
23
+ {
24
+ "title": "Generating state",
25
+ "code": "<StreamingIndicator isStreaming={true} />"
26
+ }
27
+ ],
28
+ "accessibility": [
29
+ {
30
+ "feature": "Status text",
31
+ "implementation": "The state includes human-readable text in addition to animation."
32
+ }
33
+ ],
34
+ "package": "@slipstream-ui/ai",
35
+ "importPath": "@slipstream-ui/ai",
36
+ "version": "0.0.1",
37
+ "sourceDir": "streaming",
38
+ "exportName": "StreamingIndicator"
39
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "id": "suggestions",
3
+ "name": "Suggestions",
4
+ "tier": "molecule",
5
+ "description": "Displays clickable follow-up prompts for AI interactions.",
6
+ "designIntent": "Help users discover useful next actions without composing every prompt from scratch.",
7
+ "props": [
8
+ {
9
+ "name": "suggestions",
10
+ "type": "Suggestion[]",
11
+ "required": true,
12
+ "description": "Suggestions to display."
13
+ },
14
+ {
15
+ "name": "onSelect",
16
+ "type": "(suggestion: Suggestion) => void",
17
+ "required": false,
18
+ "description": "Called when a suggestion is selected."
19
+ },
20
+ {
21
+ "name": "maxDisplay",
22
+ "required": false,
23
+ "defaultValue": "4",
24
+ "type": "number",
25
+ "description": "Maximum number of suggestions to display before truncating"
26
+ }
27
+ ],
28
+ "examples": [
29
+ {
30
+ "title": "Follow-up prompts",
31
+ "code": "<Suggestions suggestions={[{ id: '1', text: 'Show me an example' }]} />"
32
+ }
33
+ ],
34
+ "accessibility": [
35
+ {
36
+ "feature": "Keyboard activation",
37
+ "implementation": "Suggestions are native buttons."
38
+ }
39
+ ],
40
+ "package": "@slipstream-ui/ai",
41
+ "importPath": "@slipstream-ui/ai",
42
+ "version": "0.0.1",
43
+ "sourceDir": "suggestion",
44
+ "exportName": "Suggestions"
45
+ }
@@ -0,0 +1,158 @@
1
+ {
2
+ "id": "tool-call",
3
+ "name": "ToolCall",
4
+ "tier": "molecule",
5
+ "description": "A component for displaying AI tool/function calls with status, arguments, and results",
6
+ "designIntent": "The ToolCall component visualizes when an AI agent uses tools or functions. It shows the tool name, status (pending, running, completed, failed), arguments passed, and the result returned. This provides transparency into the AI's actions.",
7
+ "props": [
8
+ {
9
+ "name": "toolCall",
10
+ "type": "ToolCall",
11
+ "required": true,
12
+ "description": "The tool call object containing name, arguments, status, and result",
13
+ "examples": [
14
+ "{ id: '1', name: 'search', arguments: { query: 'React' }, status: 'completed' }"
15
+ ]
16
+ },
17
+ {
18
+ "name": "showResult",
19
+ "type": "boolean",
20
+ "defaultValue": "true",
21
+ "required": false,
22
+ "description": "Whether to display the tool result",
23
+ "examples": [
24
+ true,
25
+ false
26
+ ]
27
+ },
28
+ {
29
+ "name": "className",
30
+ "type": "string",
31
+ "required": false,
32
+ "description": "Additional CSS classes to apply"
33
+ }
34
+ ],
35
+ "examples": [
36
+ {
37
+ "title": "Completed tool call",
38
+ "code": "<ToolCall \n toolCall={{\n id: '1',\n name: 'search',\n arguments: { query: 'React components' },\n status: 'completed',\n result: { results: [...] }\n }}\n/>",
39
+ "description": "Tool call that completed successfully with result"
40
+ },
41
+ {
42
+ "title": "Running tool call",
43
+ "code": "<ToolCall \n toolCall={{\n id: '2',\n name: 'calculate',\n arguments: { expression: '2 + 2' },\n status: 'running'\n }}\n/>",
44
+ "description": "Tool call currently in progress"
45
+ },
46
+ {
47
+ "title": "Failed tool call",
48
+ "code": "<ToolCall \n toolCall={{\n id: '3',\n name: 'api_request',\n arguments: { endpoint: '/users' },\n status: 'failed',\n result: { error: 'Timeout' }\n }}\n/>",
49
+ "description": "Tool call that failed with error message"
50
+ },
51
+ {
52
+ "title": "Without result",
53
+ "code": "<ToolCall \n toolCall={toolCall}\n showResult={false}\n/>",
54
+ "description": "Tool call with result hidden"
55
+ }
56
+ ],
57
+ "antiPatterns": [
58
+ {
59
+ "title": "Don't show tool calls for simple operations",
60
+ "explanation": "Tool calls should be shown for meaningful operations, not trivial ones.",
61
+ "example": "// Avoid: Showing trivial tool calls\n<ToolCall toolCall={{ name: 'echo', arguments: { text: 'hello' }, status: 'completed' }} />\n\n// Prefer: Only show meaningful tool usage\n<ToolCall toolCall={{ name: 'search_database', arguments: { query: complexQuery }, status: 'completed' }} />"
62
+ },
63
+ {
64
+ "title": "Don't expose sensitive data in arguments",
65
+ "explanation": "Never display sensitive credentials or personal data in tool call arguments.",
66
+ "example": "// Avoid: Including sensitive data\n<ToolCall toolCall={{ \n name: 'api_call', \n arguments: { apiKey: 'secret-key' }, \n status: 'completed' \n}} />\n\n// Prefer: Redact sensitive information\n<ToolCall toolCall={{ \n name: 'api_call', \n arguments: { apiKey: '[REDACTED]' }, \n status: 'completed' \n}} />"
67
+ },
68
+ {
69
+ "title": "Don't ignore failed tool calls",
70
+ "explanation": "Failed tool calls should be clearly indicated with error information.",
71
+ "example": "// Avoid: Not addressing failures\n<ToolCall toolCall={{ name: 'save', status: 'failed' }} />\n\n// Prefer: Handle and display failures appropriately\n<ToolCall toolCall={{ name: 'save', status: 'failed', result: { error: 'Permission denied' } }} />"
72
+ }
73
+ ],
74
+ "accessibility": [
75
+ {
76
+ "feature": "Status indication",
77
+ "implementation": "Status is shown with both color and text label for clarity",
78
+ "userRequirements": "Ensure status colors have sufficient contrast in both light and dark modes"
79
+ },
80
+ {
81
+ "feature": "Code readability",
82
+ "implementation": "Arguments and results are displayed in pre/code blocks with proper formatting",
83
+ "userRequirements": "Test JSON display with screen readers for complex nested structures"
84
+ },
85
+ {
86
+ "feature": "Structure",
87
+ "implementation": "Tool call information is organized in clear sections (header, arguments, result)",
88
+ "userRequirements": "Use semantic headings for screen reader navigation"
89
+ }
90
+ ],
91
+ "contentGuidelines": [
92
+ {
93
+ "contentType": "Tool names",
94
+ "guidelines": [
95
+ "Use clear, descriptive tool names",
96
+ "Use snake_case or camelCase consistently",
97
+ "Names should indicate what the tool does",
98
+ "Avoid abbreviations unless universally understood",
99
+ "Prefix related tools with a common namespace"
100
+ ],
101
+ "goodExamples": [
102
+ "search_database",
103
+ "calculate_expression",
104
+ "send_email",
105
+ "weather_api.get_current"
106
+ ],
107
+ "badExamples": [
108
+ "tool1",
109
+ "proc",
110
+ "do_it",
111
+ "wthr.get"
112
+ ]
113
+ },
114
+ {
115
+ "contentType": "Status messages",
116
+ "guidelines": [
117
+ "Use standard status terminology (pending, running, completed, failed)",
118
+ "Be consistent with status labels across the application",
119
+ "For failed states, include error information when available",
120
+ "Use color coding to reinforce status meaning"
121
+ ],
122
+ "goodExamples": [
123
+ "Completed",
124
+ "Failed: Timeout",
125
+ "Running",
126
+ "Pending"
127
+ ],
128
+ "badExamples": [
129
+ "Done",
130
+ "Bad",
131
+ "Working",
132
+ "Waiting"
133
+ ]
134
+ }
135
+ ],
136
+ "compositionRules": [
137
+ {
138
+ "component": "Message",
139
+ "relationship": "ToolCall components are typically displayed within assistant messages to show tool usage",
140
+ "example": "Message component can contain ToolCall to show when the AI used tools during its response"
141
+ },
142
+ {
143
+ "component": "Reasoning",
144
+ "relationship": "Reasoning often precedes ToolCall to explain why a tool is being invoked",
145
+ "example": "Reasoning explains the decision to use a tool, ToolCall shows the actual invocation"
146
+ }
147
+ ],
148
+ "relatedComponents": [
149
+ "Message",
150
+ "Reasoning",
151
+ "Conversation"
152
+ ],
153
+ "package": "@slipstream-ui/ai",
154
+ "importPath": "@slipstream-ui/ai",
155
+ "version": "0.0.1",
156
+ "sourceDir": "tool-call",
157
+ "exportName": "ToolCall"
158
+ }
package/package.json CHANGED
@@ -1,6 +1,64 @@
1
1
  {
2
2
  "name": "@slipstream-ui/ai",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.4.0",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/michaelmcshinsky/slipstream-ui.git",
7
+ "directory": "packages/ai"
8
+ },
9
+ "description": "AI interaction components for Slipstream UI",
10
+ "main": "./dist/index.js",
11
+ "module": "./dist/index.mjs",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.mjs",
17
+ "require": "./dist/index.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "src"
23
+ ],
24
+ "publishConfig": {
25
+ "access": "public",
26
+ "provenance": true
27
+ },
28
+ "dependencies": {
29
+ "class-variance-authority": "^0.7.0",
30
+ "clsx": "^2.1.0",
31
+ "prism-react-renderer": "^2.4.1",
32
+ "react-markdown": "^10.1.0",
33
+ "remark-gfm": "^4.0.1",
34
+ "tailwind-merge": "^2.2.0",
35
+ "@slipstream-ui/core": "0.4.0"
36
+ },
37
+ "devDependencies": {
38
+ "@testing-library/jest-dom": "^7.0.1",
39
+ "@testing-library/react": "^16.0.0",
40
+ "@testing-library/user-event": "^14.5.0",
41
+ "@types/react": "^18.2.0",
42
+ "eslint": "^8.56.0",
43
+ "jest-axe": "^9.0.0",
44
+ "jsdom": "^24.0.0",
45
+ "tsup": "^8.0.0",
46
+ "typescript": "^5.3.3",
47
+ "vitest": "^5.0.5",
48
+ "@slipstream-ui/eslint-config": "0.0.1",
49
+ "@slipstream-ui/tailwind-config": "0.0.1",
50
+ "@slipstream-ui/typescript-config": "0.0.1",
51
+ "@slipstream-ui/vitest-config": "0.0.1"
52
+ },
53
+ "peerDependencies": {
54
+ "react": "^18.0.0 || ^19.0.0",
55
+ "react-dom": "^18.0.0 || ^19.0.0"
56
+ },
57
+ "scripts": {
58
+ "build": "tsup && node -e \"require('fs').cpSync('src/manifests','dist/manifests',{recursive:true})\"",
59
+ "dev": "tsup --watch",
60
+ "typecheck": "tsc --noEmit",
61
+ "lint": "eslint src --ext .ts,.tsx",
62
+ "test": "vitest run"
63
+ }
6
64
  }