@genui/a3-create 0.1.36 → 0.1.37

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genui/a3-create",
3
- "version": "0.1.36",
3
+ "version": "0.1.37",
4
4
  "description": "CLI scaffolding tool for A3 agentic apps",
5
5
  "keywords": [
6
6
  "genui",
@@ -24,26 +24,14 @@ interface ExamplePageLayoutProps {
24
24
  initialState?: Record<string, unknown>
25
25
  }
26
26
 
27
- export function ExamplePageLayout({
28
- title,
29
- description,
30
- sessionId,
31
- initialMessages,
32
- variant,
33
- agents,
34
- initialActiveAgentId,
35
- initialState,
36
- }: ExamplePageLayoutProps) {
27
+ export function ExamplePageLayout({ title, description, sessionId, initialMessages, variant, agents, initialActiveAgentId, initialState }: ExamplePageLayoutProps) {
37
28
  const [activeAgentId, setActiveAgentId] = useState<string | null>(initialActiveAgentId ?? null)
38
29
  const [state, setState] = useState<Record<string, unknown>>(initialState ?? {})
39
30
 
40
- const handleSessionUpdate = useCallback(
41
- (update: { activeAgentId: string | null; state: Record<string, unknown> }) => {
42
- setActiveAgentId(update.activeAgentId)
43
- setState(update.state)
44
- },
45
- [],
46
- )
31
+ const handleSessionUpdate = useCallback((update: { activeAgentId: string | null; state: Record<string, unknown> }) => {
32
+ setActiveAgentId(update.activeAgentId)
33
+ setState(update.state)
34
+ }, [])
47
35
 
48
36
  const handleRestart = useCallback(async () => {
49
37
  const fresh = await restartSession(sessionId)
@@ -55,17 +43,7 @@ export function ExamplePageLayout({
55
43
  }, [sessionId])
56
44
 
57
45
  return (
58
- <Box
59
- sx={{
60
- display: 'flex',
61
- flexDirection: 'column',
62
- height: '100%',
63
- px: { xs: 2, sm: 3, md: 5, lg: 8 },
64
- maxWidth: 1600,
65
- width: '100%',
66
- mx: 'auto',
67
- }}
68
- >
46
+ <Box sx={{ display: 'flex', flexDirection: 'column', height: '100%', px: { xs: 2, sm: 3, md: 5, lg: 8 }, maxWidth: 1600, width: '100%', mx: 'auto' }}>
69
47
  <Typography variant="h5" fontWeight="bold" sx={{ pt: 3 }}>
70
48
  {title}
71
49
  </Typography>
@@ -83,30 +61,9 @@ export function ExamplePageLayout({
83
61
  }}
84
62
  >
85
63
  <Box sx={{ minHeight: 0, display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
86
- {variant === 'blocking' && (
87
- <Chat
88
- sessionId={sessionId}
89
- initialMessages={initialMessages}
90
- onSessionUpdate={handleSessionUpdate}
91
- onRestart={handleRestart}
92
- />
93
- )}
94
- {variant === 'stream' && (
95
- <StreamChat
96
- sessionId={sessionId}
97
- initialMessages={initialMessages}
98
- onSessionUpdate={handleSessionUpdate}
99
- onRestart={handleRestart}
100
- />
101
- )}
102
- {variant === 'agui' && (
103
- <AguiChat
104
- sessionId={sessionId}
105
- initialMessages={initialMessages}
106
- onSessionUpdate={handleSessionUpdate}
107
- onRestart={handleRestart}
108
- />
109
- )}
64
+ {variant === 'blocking' && <Chat sessionId={sessionId} initialMessages={initialMessages} onSessionUpdate={handleSessionUpdate} onRestart={handleRestart} />}
65
+ {variant === 'stream' && <StreamChat sessionId={sessionId} initialMessages={initialMessages} onSessionUpdate={handleSessionUpdate} onRestart={handleRestart} />}
66
+ {variant === 'agui' && <AguiChat sessionId={sessionId} initialMessages={initialMessages} onSessionUpdate={handleSessionUpdate} onRestart={handleRestart} />}
110
67
  </Box>
111
68
  <Box sx={{ minHeight: 0, display: 'flex', flexDirection: 'column', gap: 3, overflow: 'auto' }}>
112
69
  <AgentGraph agents={agents} activeAgentId={activeAgentId} />
@@ -36,127 +36,120 @@ export function StreamChat({ sessionId, initialMessages, onSessionUpdate, onRest
36
36
  const assistantIdRef = useRef<string>('')
37
37
  const { isRestarting, handleRestart } = useRestart({ onRestart, setMessages, onSessionUpdate })
38
38
 
39
- const handleSubmit = useCallback(
40
- async (text: string) => {
41
- const userMsg: Message = {
42
- messageId: crypto.randomUUID(),
43
- text,
44
- metadata: { source: MessageSender.USER },
39
+ const handleSubmit = useCallback(async (text: string) => {
40
+ const userMsg: Message = {
41
+ messageId: crypto.randomUUID(),
42
+ text,
43
+ metadata: { source: MessageSender.USER },
44
+ }
45
+ setMessages((prev) => [...prev, userMsg])
46
+ setIsLoading(true)
47
+
48
+ // Create a placeholder assistant message for streaming into
49
+ let assistantId = crypto.randomUUID()
50
+ assistantIdRef.current = assistantId
51
+
52
+ const streamingMsg: Message = {
53
+ messageId: assistantId,
54
+ text: '',
55
+ metadata: { source: MessageSender.ASSISTANT },
56
+ isStreaming: true,
57
+ }
58
+ setMessages((prev) => [...prev, streamingMsg])
59
+
60
+ try {
61
+ const response = await fetch('/api/stream', {
62
+ method: 'POST',
63
+ headers: { 'Content-Type': 'application/json' },
64
+ body: JSON.stringify({ message: text, sessionId }),
65
+ })
66
+
67
+ if (!response.ok) {
68
+ throw new Error(`HTTP error: ${response.status}`)
45
69
  }
46
- setMessages((prev) => [...prev, userMsg])
47
- setIsLoading(true)
48
-
49
- // Create a placeholder assistant message for streaming into
50
- let assistantId = crypto.randomUUID()
51
- assistantIdRef.current = assistantId
52
-
53
- const streamingMsg: Message = {
54
- messageId: assistantId,
55
- text: '',
56
- metadata: { source: MessageSender.ASSISTANT },
57
- isStreaming: true,
58
- }
59
- setMessages((prev) => [...prev, streamingMsg])
60
70
 
61
- try {
62
- const response = await fetch('/api/stream', {
63
- method: 'POST',
64
- headers: { 'Content-Type': 'application/json' },
65
- body: JSON.stringify({ message: text, sessionId }),
66
- })
71
+ const reader = response.body?.getReader()
72
+ if (!reader) throw new Error('No response body')
67
73
 
68
- if (!response.ok) {
69
- throw new Error(`HTTP error: ${response.status}`)
70
- }
74
+ const decoder = new TextDecoder()
75
+ let buffer = ''
76
+
77
+ while (true) {
78
+ const { done, value } = await reader.read()
79
+ if (done) break
80
+
81
+ buffer += decoder.decode(value, { stream: true })
82
+
83
+ // Process complete SSE lines
84
+ const lines = buffer.split('\n')
85
+ buffer = lines.pop() ?? ''
71
86
 
72
- const reader = response.body?.getReader()
73
- if (!reader) throw new Error('No response body')
74
-
75
- const decoder = new TextDecoder()
76
- let buffer = ''
77
-
78
- while (true) {
79
- const { done, value } = await reader.read()
80
- if (done) break
81
-
82
- buffer += decoder.decode(value, { stream: true })
83
-
84
- // Process complete SSE lines
85
- const lines = buffer.split('\n')
86
- buffer = lines.pop() ?? ''
87
-
88
- for (const line of lines) {
89
- if (!line.startsWith('data: ')) continue
90
- const data = line.slice(6)
91
- if (data === '[DONE]') continue
92
-
93
- try {
94
- const event = JSON.parse(data) as StreamEvent
95
-
96
- if (event.type === EventType.TEXT_MESSAGE_CONTENT && event.delta) {
97
- setIsTransitioning(false)
98
- setMessages((prev) =>
99
- prev.map((m) => (m.messageId === assistantId ? { ...m, text: m.text + event.delta } : m)),
100
- )
101
- } else if (event.type === EventType.CUSTOM && event.name === 'AgentTransition') {
102
- const transitionEvent = event as StreamEvent & {
103
- value?: { toAgentId?: string; state?: Record<string, unknown> }
104
- }
105
- onSessionUpdate?.({
106
- activeAgentId: transitionEvent.value?.toAgentId ?? null,
107
- state: transitionEvent.value?.state ?? {},
108
- })
109
- const prevAssistantId = assistantId
110
- assistantId = crypto.randomUUID()
111
- assistantIdRef.current = assistantId
112
- setIsTransitioning(true)
113
- setMessages((prev) => {
114
- const updated = prev.map((m) => (m.messageId === prevAssistantId ? { ...m, isStreaming: false } : m))
115
- return [
116
- ...updated,
117
- {
118
- messageId: assistantId,
119
- text: '',
120
- metadata: { source: MessageSender.ASSISTANT },
121
- isStreaming: true,
122
- },
123
- ]
124
- })
125
- } else if (event.type === EventType.RUN_FINISHED) {
126
- setIsTransitioning(false)
127
- const result = event.result
128
- onSessionUpdate?.({
129
- activeAgentId: (result?.activeAgentId as string) ?? null,
130
- state: (result?.state as Record<string, unknown>) ?? {},
131
- })
132
- setMessages((prev) => prev.map((m) => (m.messageId === assistantId ? { ...m, isStreaming: false } : m)))
133
- } else if (event.type === EventType.RUN_ERROR) {
134
- setIsTransitioning(false)
135
- setMessages((prev) =>
136
- prev.map((m) =>
137
- m.messageId === assistantId ? { ...m, text: m.text || CHAT_ERROR_SHORT, isStreaming: false } : m,
138
- ),
139
- )
87
+ for (const line of lines) {
88
+ if (!line.startsWith('data: ')) continue
89
+ const data = line.slice(6)
90
+ if (data === '[DONE]') continue
91
+
92
+ try {
93
+ const event = JSON.parse(data) as StreamEvent
94
+
95
+ if (event.type === EventType.TEXT_MESSAGE_CONTENT && event.delta) {
96
+ setIsTransitioning(false)
97
+ setMessages((prev) => prev.map((m) => (m.messageId === assistantId ? { ...m, text: m.text + event.delta } : m)))
98
+ } else if (event.type === EventType.CUSTOM && event.name === 'AgentTransition') {
99
+ const transitionEvent = event as StreamEvent & {
100
+ value?: { toAgentId?: string; state?: Record<string, unknown> }
140
101
  }
141
- } catch {
142
- // Skip malformed JSON lines
102
+ onSessionUpdate?.({
103
+ activeAgentId: transitionEvent.value?.toAgentId ?? null,
104
+ state: transitionEvent.value?.state ?? {},
105
+ })
106
+ const prevAssistantId = assistantId
107
+ assistantId = crypto.randomUUID()
108
+ assistantIdRef.current = assistantId
109
+ setIsTransitioning(true)
110
+ setMessages((prev) => {
111
+ const updated = prev.map((m) => (m.messageId === prevAssistantId ? { ...m, isStreaming: false } : m))
112
+ return [...updated, { messageId: assistantId, text: '', metadata: { source: MessageSender.ASSISTANT }, isStreaming: true }]
113
+ })
114
+ } else if (event.type === EventType.RUN_FINISHED) {
115
+ setIsTransitioning(false)
116
+ const result = event.result
117
+ onSessionUpdate?.({
118
+ activeAgentId: (result?.activeAgentId as string) ?? null,
119
+ state: (result?.state as Record<string, unknown>) ?? {},
120
+ })
121
+ setMessages((prev) => prev.map((m) => (m.messageId === assistantId ? { ...m, isStreaming: false } : m)))
122
+ } else if (event.type === EventType.RUN_ERROR) {
123
+ setIsTransitioning(false)
124
+ setMessages((prev) =>
125
+ prev.map((m) =>
126
+ m.messageId === assistantId
127
+ ? { ...m, text: m.text || CHAT_ERROR_SHORT, isStreaming: false }
128
+ : m,
129
+ ),
130
+ )
143
131
  }
132
+ } catch {
133
+ // Skip malformed JSON lines
144
134
  }
145
135
  }
146
-
147
- // Ensure streaming flag is cleared
148
- setMessages((prev) => prev.map((m) => (m.messageId === assistantId ? { ...m, isStreaming: false } : m)))
149
- } catch (error) {
150
- console.error('Chat stream error:', error)
151
- setMessages((prev) =>
152
- prev.map((m) => (m.messageId === assistantId ? { ...m, text: m.text || CHAT_ERROR, isStreaming: false } : m)),
153
- )
154
- } finally {
155
- setIsLoading(false)
156
136
  }
157
- },
158
- [onSessionUpdate, sessionId],
159
- )
137
+
138
+ // Ensure streaming flag is cleared
139
+ setMessages((prev) => prev.map((m) => (m.messageId === assistantId ? { ...m, isStreaming: false } : m)))
140
+ } catch (error) {
141
+ console.error('Chat stream error:', error)
142
+ setMessages((prev) =>
143
+ prev.map((m) =>
144
+ m.messageId === assistantId
145
+ ? { ...m, text: m.text || CHAT_ERROR, isStreaming: false }
146
+ : m,
147
+ ),
148
+ )
149
+ } finally {
150
+ setIsLoading(false)
151
+ }
152
+ }, [onSessionUpdate, sessionId])
160
153
 
161
154
  return (
162
155
  <ChatContainer elevation={0}>
@@ -1,6 +1,6 @@
1
1
  # @genui/a3
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/@genui)](https://www.npmjs.com/package/@genui/a3)
3
+ [![npm version](https://img.shields.io/npm/v/@genui/a3)](https://www.npmjs.com/package/@genui/a3)
4
4
  [![license](https://img.shields.io/npm/l/@genui/a3)](https://github.com/generalui/a3/blob/main/LICENSE)
5
5
 
6
6
  **Predictable, governable multi-agent orchestration for TypeScript.**
@@ -11,10 +11,10 @@
11
11
  "@ag-ui/encoder": "0.0.45",
12
12
  "@emotion/react": "11.14.0",
13
13
  "@emotion/styled": "11.14.1",
14
- "@genui/a3": "latest",
15
- "@genui/a3-anthropic": "latest",
16
- "@genui/a3-bedrock": "latest",
17
- "@genui/a3-openai": "latest",
14
+ "@genui/a3": "^0.1.36",
15
+ "@genui/a3-anthropic": "^0.1.36",
16
+ "@genui/a3-bedrock": "^0.1.36",
17
+ "@genui/a3-openai": "^0.1.36",
18
18
  "@mui/icons-material": "7.3.7",
19
19
  "@mui/material": "7.3.7",
20
20
  "next": "16.1.7",
@@ -1,6 +0,0 @@
1
- /// <reference types="next" />
2
- /// <reference types="next/image-types/global" />
3
- import "./.next/types/routes.d.ts";
4
-
5
- // NOTE: This file should not be edited
6
- // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.