@vistagenic/vista 0.2.16 → 0.3.2

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 (153) hide show
  1. package/bin/vista.js +184 -177
  2. package/dist/ai/agent.d.ts +37 -0
  3. package/dist/ai/agent.js +385 -0
  4. package/dist/ai/embeddings.d.ts +11 -0
  5. package/dist/ai/embeddings.js +71 -0
  6. package/dist/ai/index.d.ts +10 -0
  7. package/dist/ai/index.js +26 -0
  8. package/dist/ai/memory.d.ts +16 -0
  9. package/dist/ai/memory.js +39 -0
  10. package/dist/ai/observability.d.ts +21 -0
  11. package/dist/ai/observability.js +69 -0
  12. package/dist/ai/providers/anthropic.d.ts +2 -0
  13. package/dist/ai/providers/anthropic.js +190 -0
  14. package/dist/ai/providers/base.d.ts +7 -0
  15. package/dist/ai/providers/base.js +85 -0
  16. package/dist/ai/providers/gemini.d.ts +2 -0
  17. package/dist/ai/providers/gemini.js +194 -0
  18. package/dist/ai/providers/index.d.ts +5 -0
  19. package/dist/ai/providers/index.js +21 -0
  20. package/dist/ai/providers/mock.d.ts +8 -0
  21. package/dist/ai/providers/mock.js +77 -0
  22. package/dist/ai/providers/openai.d.ts +2 -0
  23. package/dist/ai/providers/openai.js +211 -0
  24. package/dist/ai/rag.d.ts +35 -0
  25. package/dist/ai/rag.js +110 -0
  26. package/dist/ai/react/index.d.ts +1 -0
  27. package/dist/ai/react/index.js +17 -0
  28. package/dist/ai/react/react-server.d.ts +1 -0
  29. package/dist/ai/react/react-server.js +17 -0
  30. package/dist/ai/react/use-agent.d.ts +23 -0
  31. package/dist/ai/react/use-agent.js +138 -0
  32. package/dist/ai/stream.d.ts +24 -0
  33. package/dist/ai/stream.js +109 -0
  34. package/dist/ai/tool.d.ts +11 -0
  35. package/dist/ai/tool.js +47 -0
  36. package/dist/ai/types.d.ts +117 -0
  37. package/dist/ai/types.js +5 -0
  38. package/dist/auth/core.d.ts +140 -0
  39. package/dist/auth/core.js +165 -0
  40. package/dist/auth/index.d.ts +20 -8
  41. package/dist/auth/index.js +369 -16
  42. package/dist/auth/react-server.d.ts +1 -0
  43. package/dist/auth/react-server.js +10 -0
  44. package/dist/auth/react.d.ts +18 -0
  45. package/dist/auth/react.js +71 -0
  46. package/dist/bin/build-rsc.js +602 -604
  47. package/dist/bin/build.js +389 -388
  48. package/dist/bin/deploy-output.d.ts +2 -7
  49. package/dist/bin/deploy-output.js +3 -76
  50. package/dist/bin/deploy.d.ts +7 -0
  51. package/dist/bin/deploy.js +102 -0
  52. package/dist/bin/dev-error-overlay-snippet.js +778 -552
  53. package/dist/bin/devtools-indicator-snippet.js +387 -387
  54. package/dist/bin/generate.js +510 -248
  55. package/dist/build/manifest.d.ts +169 -139
  56. package/dist/build/manifest.js +423 -367
  57. package/dist/build/rsc/client-manifest.d.ts +62 -52
  58. package/dist/build/rsc/client-manifest.js +295 -193
  59. package/dist/build/rsc/client-reference-plugin.d.ts +37 -37
  60. package/dist/build/rsc/client-reference-plugin.js +160 -160
  61. package/dist/build/rsc/native-scanner.d.ts +135 -123
  62. package/dist/build/rsc/native-scanner.js +203 -170
  63. package/dist/build/rsc/react-client-reference-manifest.d.ts +28 -22
  64. package/dist/build/rsc/react-client-reference-manifest.js +240 -219
  65. package/dist/build/rsc/rsc-renderer.d.ts +99 -99
  66. package/dist/build/rsc/rsc-renderer.js +263 -263
  67. package/dist/build/rsc/server-component-loader.d.ts +19 -19
  68. package/dist/build/rsc/server-component-loader.js +91 -91
  69. package/dist/build/rsc/server-manifest.d.ts +17 -0
  70. package/dist/build/rsc/server-manifest.js +20 -0
  71. package/dist/build/standalone.js +337 -334
  72. package/dist/build/webpack/plugins/vista-flight-plugin.js +5 -5
  73. package/dist/client/dynamic.react-server.d.ts +2 -0
  74. package/dist/client/dynamic.react-server.js +23 -0
  75. package/dist/client/link.react-server.d.ts +2 -0
  76. package/dist/client/link.react-server.js +11 -0
  77. package/dist/client/navigation.react-server.d.ts +1 -0
  78. package/dist/client/navigation.react-server.js +17 -0
  79. package/dist/client/router.react-server.d.ts +1 -0
  80. package/dist/client/router.react-server.js +17 -0
  81. package/dist/client/rsc-router.react-server.d.ts +1 -0
  82. package/dist/client/rsc-router.react-server.js +17 -0
  83. package/dist/client/script.react-server.d.ts +2 -0
  84. package/dist/client/script.react-server.js +23 -0
  85. package/dist/components/client-island.d.ts +34 -34
  86. package/dist/components/client-island.js +75 -75
  87. package/dist/config.d.ts +17 -0
  88. package/dist/config.js +60 -1
  89. package/dist/deploy/adapters/cloudflare.d.ts +2 -0
  90. package/dist/deploy/adapters/cloudflare.js +124 -0
  91. package/dist/deploy/adapters/docker.d.ts +2 -0
  92. package/dist/deploy/adapters/docker.js +112 -0
  93. package/dist/deploy/adapters/index.d.ts +15 -0
  94. package/dist/deploy/adapters/index.js +24 -0
  95. package/dist/deploy/adapters/netlify.d.ts +2 -0
  96. package/dist/deploy/adapters/netlify.js +115 -0
  97. package/dist/deploy/adapters/render.d.ts +2 -0
  98. package/dist/deploy/adapters/render.js +95 -0
  99. package/dist/deploy/adapters/vercel.d.ts +7 -0
  100. package/dist/deploy/adapters/vercel.js +164 -0
  101. package/dist/deploy/cli-runner.d.ts +8 -0
  102. package/dist/deploy/cli-runner.js +58 -0
  103. package/dist/deploy/detect.d.ts +6 -0
  104. package/dist/deploy/detect.js +77 -0
  105. package/dist/deploy/index.d.ts +24 -0
  106. package/dist/deploy/index.js +112 -0
  107. package/dist/deploy/preflight.d.ts +8 -0
  108. package/dist/deploy/preflight.js +80 -0
  109. package/dist/deploy/types.d.ts +48 -0
  110. package/dist/deploy/types.js +2 -0
  111. package/dist/deploy/utils.d.ts +18 -0
  112. package/dist/deploy/utils.js +70 -0
  113. package/dist/dev-error.d.ts +14 -0
  114. package/dist/dev-error.js +1763 -705
  115. package/dist/index.d.ts +23 -21
  116. package/dist/index.js +61 -57
  117. package/dist/server/cookie-parse.d.ts +4 -0
  118. package/dist/server/cookie-parse.js +14 -0
  119. package/dist/server/engine.js +7 -26
  120. package/dist/server/index.d.ts +109 -102
  121. package/dist/server/index.js +315 -286
  122. package/dist/server/middleware-runner.d.ts +125 -57
  123. package/dist/server/middleware-runner.js +615 -218
  124. package/dist/server/middleware-security.d.ts +36 -0
  125. package/dist/server/middleware-security.js +183 -0
  126. package/dist/server/module-compile-hook.js +695 -662
  127. package/dist/server/route-handler-registry.d.ts +65 -0
  128. package/dist/server/route-handler-registry.js +195 -0
  129. package/dist/server/route-patterns.d.ts +67 -0
  130. package/dist/server/route-patterns.js +186 -0
  131. package/dist/server/rsc-engine.js +75 -92
  132. package/dist/server/rsc-module-system.d.ts +33 -33
  133. package/dist/server/rsc-module-system.js +87 -87
  134. package/dist/server/rsc-upstream.js +892 -888
  135. package/dist/server/static-generator.js +10 -10
  136. package/dist/server/typed-api-runtime.d.ts +18 -0
  137. package/dist/server/typed-api-runtime.js +635 -507
  138. package/dist/server/vista-import-map.js +134 -123
  139. package/dist/stack/index.d.ts +34 -32
  140. package/dist/stack/index.js +49 -45
  141. package/dist/stack/server/caller.d.ts +13 -0
  142. package/dist/stack/server/caller.js +42 -0
  143. package/dist/stack/server/executor.d.ts +40 -36
  144. package/dist/stack/server/executor.js +222 -174
  145. package/dist/stack/server/index.d.ts +11 -10
  146. package/dist/stack/server/index.js +24 -23
  147. package/dist/stack/server/procedure.d.ts +20 -18
  148. package/dist/stack/server/procedure.js +66 -58
  149. package/dist/stack/server/types.d.ts +113 -100
  150. package/dist/theme/react-server.d.ts +10 -0
  151. package/dist/theme/react-server.js +16 -0
  152. package/package.json +28 -3
  153. package/LICENSE +0 -21
@@ -0,0 +1,211 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createOpenAIModel = createOpenAIModel;
4
+ const tool_1 = require("../tool");
5
+ function formatMessagesForOpenAI(messages, systemPrompt) {
6
+ const result = [];
7
+ if (systemPrompt) {
8
+ result.push({ role: 'system', content: systemPrompt });
9
+ }
10
+ for (const msg of messages) {
11
+ if (msg.role === 'tool') {
12
+ result.push({
13
+ role: 'tool',
14
+ tool_call_id: msg.toolCallId || 'call_default',
15
+ content: msg.content,
16
+ });
17
+ }
18
+ else if (msg.role === 'assistant' && msg.toolCalls && msg.toolCalls.length > 0) {
19
+ result.push({
20
+ role: 'assistant',
21
+ content: msg.content || null,
22
+ tool_calls: msg.toolCalls.map((tc) => ({
23
+ id: tc.id,
24
+ type: 'function',
25
+ function: {
26
+ name: tc.name,
27
+ arguments: typeof tc.arguments === 'string' ? tc.arguments : JSON.stringify(tc.arguments),
28
+ },
29
+ })),
30
+ });
31
+ }
32
+ else {
33
+ result.push({
34
+ role: msg.role,
35
+ content: msg.content,
36
+ });
37
+ }
38
+ }
39
+ return result;
40
+ }
41
+ function createOpenAIModel(options) {
42
+ const baseURL = (options.baseURL ||
43
+ process.env.OPENAI_BASE_URL ||
44
+ 'https://api.openai.com/v1').replace(/\/+$/, '');
45
+ const apiKey = options.apiKey || process.env.OPENAI_API_KEY || '';
46
+ const modelName = options.model || 'gpt-4o';
47
+ return {
48
+ provider: 'openai',
49
+ modelName,
50
+ async generateText(genOptions) {
51
+ const url = `${baseURL}/chat/completions`;
52
+ const messages = formatMessagesForOpenAI(genOptions.messages, genOptions.systemPrompt);
53
+ const body = {
54
+ model: modelName,
55
+ messages,
56
+ temperature: genOptions.temperature ?? options.temperature ?? 0.7,
57
+ };
58
+ if (genOptions.maxTokens || options.maxTokens) {
59
+ body.max_tokens = genOptions.maxTokens || options.maxTokens;
60
+ }
61
+ if (genOptions.tools && genOptions.tools.length > 0) {
62
+ body.tools = genOptions.tools.map(tool_1.formatToolForOpenAI);
63
+ body.tool_choice = 'auto';
64
+ }
65
+ const headers = {
66
+ 'Content-Type': 'application/json',
67
+ ...(options.headers || {}),
68
+ };
69
+ if (apiKey) {
70
+ headers['Authorization'] = `Bearer ${apiKey}`;
71
+ }
72
+ const res = await fetch(url, {
73
+ method: 'POST',
74
+ headers,
75
+ body: JSON.stringify(body),
76
+ signal: genOptions.abortSignal,
77
+ });
78
+ if (!res.ok) {
79
+ const errText = await res.text().catch(() => '');
80
+ throw new Error(`OpenAI API request failed [${res.status}]: ${errText}`);
81
+ }
82
+ const data = await res.json();
83
+ const choice = data.choices?.[0];
84
+ const message = choice?.message;
85
+ let toolCalls;
86
+ if (message?.tool_calls && message.tool_calls.length > 0) {
87
+ toolCalls = message.tool_calls.map((tc) => {
88
+ let parsedArgs = {};
89
+ try {
90
+ parsedArgs = JSON.parse(tc.function?.arguments || '{}');
91
+ }
92
+ catch {
93
+ parsedArgs = { raw: tc.function?.arguments };
94
+ }
95
+ return {
96
+ id: tc.id,
97
+ name: tc.function?.name,
98
+ arguments: parsedArgs,
99
+ };
100
+ });
101
+ }
102
+ return {
103
+ text: message?.content || '',
104
+ toolCalls,
105
+ finishReason: choice?.finish_reason || 'stop',
106
+ usage: data.usage
107
+ ? {
108
+ promptTokens: data.usage.prompt_tokens || 0,
109
+ completionTokens: data.usage.completion_tokens || 0,
110
+ totalTokens: data.usage.total_tokens || 0,
111
+ }
112
+ : undefined,
113
+ raw: data,
114
+ };
115
+ },
116
+ async *streamText(genOptions) {
117
+ const url = `${baseURL}/chat/completions`;
118
+ const messages = formatMessagesForOpenAI(genOptions.messages, genOptions.systemPrompt);
119
+ const body = {
120
+ model: modelName,
121
+ messages,
122
+ temperature: genOptions.temperature ?? options.temperature ?? 0.7,
123
+ stream: true,
124
+ };
125
+ if (genOptions.maxTokens || options.maxTokens) {
126
+ body.max_tokens = genOptions.maxTokens || options.maxTokens;
127
+ }
128
+ if (genOptions.tools && genOptions.tools.length > 0) {
129
+ body.tools = genOptions.tools.map(tool_1.formatToolForOpenAI);
130
+ body.tool_choice = 'auto';
131
+ }
132
+ const headers = {
133
+ 'Content-Type': 'application/json',
134
+ ...(options.headers || {}),
135
+ };
136
+ if (apiKey) {
137
+ headers['Authorization'] = `Bearer ${apiKey}`;
138
+ }
139
+ const res = await fetch(url, {
140
+ method: 'POST',
141
+ headers,
142
+ body: JSON.stringify(body),
143
+ signal: genOptions.abortSignal,
144
+ });
145
+ if (!res.ok) {
146
+ const errText = await res.text().catch(() => '');
147
+ throw new Error(`OpenAI API stream request failed [${res.status}]: ${errText}`);
148
+ }
149
+ if (!res.body) {
150
+ throw new Error('ReadableStream not supported on fetch response');
151
+ }
152
+ const reader = res.body.getReader();
153
+ const decoder = new TextDecoder();
154
+ let buffer = '';
155
+ try {
156
+ while (true) {
157
+ const { done, value } = await reader.read();
158
+ if (done)
159
+ break;
160
+ buffer += decoder.decode(value, { stream: true });
161
+ const lines = buffer.split('\n');
162
+ buffer = lines.pop() || '';
163
+ for (const line of lines) {
164
+ const trimmed = line.trim();
165
+ if (!trimmed || trimmed.startsWith(':'))
166
+ continue;
167
+ if (trimmed === 'data: [DONE]') {
168
+ yield { type: 'done' };
169
+ return;
170
+ }
171
+ if (trimmed.startsWith('data: ')) {
172
+ try {
173
+ const parsed = JSON.parse(trimmed.slice(6));
174
+ const delta = parsed.choices?.[0]?.delta;
175
+ if (delta?.content) {
176
+ yield { type: 'text-delta', textDelta: delta.content };
177
+ }
178
+ if (delta?.tool_calls) {
179
+ for (const tc of delta.tool_calls) {
180
+ let parsedArgs = {};
181
+ try {
182
+ parsedArgs = JSON.parse(tc.function?.arguments || '{}');
183
+ }
184
+ catch {
185
+ parsedArgs = { raw: tc.function?.arguments };
186
+ }
187
+ yield {
188
+ type: 'tool-call',
189
+ toolCall: {
190
+ id: tc.id || `call_${Date.now()}`,
191
+ name: tc.function?.name || '',
192
+ arguments: parsedArgs,
193
+ },
194
+ };
195
+ }
196
+ }
197
+ }
198
+ catch {
199
+ // Ignore parse errors on partial chunks
200
+ }
201
+ }
202
+ }
203
+ }
204
+ }
205
+ finally {
206
+ reader.releaseLock();
207
+ }
208
+ yield { type: 'done' };
209
+ },
210
+ };
211
+ }
@@ -0,0 +1,35 @@
1
+ import type { ToolDefinition } from './types';
2
+ export interface DocumentEntry<TMetadata = any> {
3
+ id: string;
4
+ text: string;
5
+ vector?: number[];
6
+ metadata?: TMetadata;
7
+ }
8
+ export interface DocumentMatch<TMetadata = any> {
9
+ id: string;
10
+ text: string;
11
+ score: number;
12
+ metadata?: TMetadata;
13
+ }
14
+ export declare function cosineSimilarity(a: number[], b: number[]): number;
15
+ export declare class InMemoryVectorStore<TMetadata = any> {
16
+ private documents;
17
+ addDocument(doc: DocumentEntry<TMetadata>): void;
18
+ addDocuments(docs: DocumentEntry<TMetadata>[]): void;
19
+ search(queryVector: number[], topK?: number): DocumentMatch<TMetadata>[];
20
+ searchByKeyword(query: string, topK?: number): DocumentMatch<TMetadata>[];
21
+ clear(): void;
22
+ }
23
+ export interface RetrieverOptions<TMetadata = any> {
24
+ name?: string;
25
+ description?: string;
26
+ store: InMemoryVectorStore<TMetadata>;
27
+ embed?: (text: string) => Promise<number[]> | number[];
28
+ topK?: number;
29
+ }
30
+ /**
31
+ * Creates a knowledge retriever tool that can be provided directly to an AI agent.
32
+ */
33
+ export declare function createRetrieverTool<TMetadata = any>(options: RetrieverOptions<TMetadata>): ToolDefinition<{
34
+ query: string;
35
+ }>;
package/dist/ai/rag.js ADDED
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InMemoryVectorStore = void 0;
4
+ exports.cosineSimilarity = cosineSimilarity;
5
+ exports.createRetrieverTool = createRetrieverTool;
6
+ const tool_1 = require("./tool");
7
+ function cosineSimilarity(a, b) {
8
+ if (a.length !== b.length || a.length === 0)
9
+ return 0;
10
+ let dotProduct = 0;
11
+ let normA = 0;
12
+ let normB = 0;
13
+ for (let i = 0; i < a.length; i++) {
14
+ dotProduct += a[i] * b[i];
15
+ normA += a[i] * a[i];
16
+ normB += b[i] * b[i];
17
+ }
18
+ const denominator = Math.sqrt(normA) * Math.sqrt(normB);
19
+ if (denominator === 0)
20
+ return 0;
21
+ return dotProduct / denominator;
22
+ }
23
+ class InMemoryVectorStore {
24
+ documents = [];
25
+ addDocument(doc) {
26
+ this.documents.push(doc);
27
+ }
28
+ addDocuments(docs) {
29
+ this.documents.push(...docs);
30
+ }
31
+ search(queryVector, topK = 3) {
32
+ const scored = [];
33
+ for (const doc of this.documents) {
34
+ if (!doc.vector)
35
+ continue;
36
+ const score = cosineSimilarity(queryVector, doc.vector);
37
+ scored.push({
38
+ id: doc.id,
39
+ text: doc.text,
40
+ score,
41
+ metadata: doc.metadata,
42
+ });
43
+ }
44
+ scored.sort((a, b) => b.score - a.score);
45
+ return scored.slice(0, topK);
46
+ }
47
+ searchByKeyword(query, topK = 3) {
48
+ const lowerQuery = query.toLowerCase();
49
+ const scored = [];
50
+ for (const doc of this.documents) {
51
+ const lowerText = doc.text.toLowerCase();
52
+ let matchCount = 0;
53
+ const terms = lowerQuery.split(/\s+/).filter(Boolean);
54
+ for (const term of terms) {
55
+ if (lowerText.includes(term))
56
+ matchCount++;
57
+ }
58
+ if (matchCount > 0) {
59
+ scored.push({
60
+ id: doc.id,
61
+ text: doc.text,
62
+ score: matchCount / terms.length,
63
+ metadata: doc.metadata,
64
+ });
65
+ }
66
+ }
67
+ scored.sort((a, b) => b.score - a.score);
68
+ return scored.slice(0, topK);
69
+ }
70
+ clear() {
71
+ this.documents = [];
72
+ }
73
+ }
74
+ exports.InMemoryVectorStore = InMemoryVectorStore;
75
+ /**
76
+ * Creates a knowledge retriever tool that can be provided directly to an AI agent.
77
+ */
78
+ function createRetrieverTool(options) {
79
+ const { name = 'search_knowledge_base', description = 'Search the knowledge base for relevant context, documentation, or domain facts.', store, embed, topK = 3, } = options;
80
+ return (0, tool_1.tool)({
81
+ name,
82
+ description,
83
+ parameters: {
84
+ type: 'object',
85
+ properties: {
86
+ query: {
87
+ type: 'string',
88
+ description: 'The search query or keyword phrase to find context for',
89
+ },
90
+ },
91
+ required: ['query'],
92
+ },
93
+ execute: async ({ query }) => {
94
+ let matches = [];
95
+ if (embed) {
96
+ const queryVector = await embed(query);
97
+ matches = store.search(queryVector, topK);
98
+ }
99
+ else {
100
+ matches = store.searchByKeyword(query, topK);
101
+ }
102
+ return matches.map((m) => ({
103
+ id: m.id,
104
+ content: m.text,
105
+ score: Math.round(m.score * 100) / 100,
106
+ metadata: m.metadata,
107
+ }));
108
+ },
109
+ });
110
+ }
@@ -0,0 +1 @@
1
+ export * from './use-agent';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./use-agent"), exports);
@@ -0,0 +1 @@
1
+ export * from './index';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./index"), exports);
@@ -0,0 +1,23 @@
1
+ import type { Message } from '../types';
2
+ export interface UseAgentOptions {
3
+ api?: string;
4
+ initialMessages?: Message[];
5
+ sessionId?: string;
6
+ onResponse?: (response: Response) => void;
7
+ onFinish?: (message: Message) => void;
8
+ onError?: (error: Error) => void;
9
+ }
10
+ export interface UseAgentResult {
11
+ messages: Message[];
12
+ input: string;
13
+ setInput: (value: string) => void;
14
+ handleInputChange: (e: any) => void;
15
+ handleSubmit: (e?: any, options?: {
16
+ prompt?: string;
17
+ }) => Promise<void>;
18
+ isLoading: boolean;
19
+ error: Error | null;
20
+ stop: () => void;
21
+ reload: () => Promise<void>;
22
+ }
23
+ export declare function useAgent(options?: UseAgentOptions): UseAgentResult;
@@ -0,0 +1,138 @@
1
+ 'use client';
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.useAgent = useAgent;
5
+ const react_1 = require("react");
6
+ function useAgent(options = {}) {
7
+ const { api = '/api/chat', initialMessages = [], sessionId, onResponse, onFinish, onError, } = options;
8
+ const [messages, setMessages] = (0, react_1.useState)(initialMessages);
9
+ const [input, setInput] = (0, react_1.useState)('');
10
+ const [isLoading, setIsLoading] = (0, react_1.useState)(false);
11
+ const [error, setError] = (0, react_1.useState)(null);
12
+ const abortControllerRef = (0, react_1.useRef)(null);
13
+ const handleInputChange = (0, react_1.useCallback)((e) => {
14
+ setInput(e?.target?.value ?? e);
15
+ }, []);
16
+ const stop = (0, react_1.useCallback)(() => {
17
+ if (abortControllerRef.current) {
18
+ abortControllerRef.current.abort();
19
+ abortControllerRef.current = null;
20
+ setIsLoading(false);
21
+ }
22
+ }, []);
23
+ const sendPrompt = (0, react_1.useCallback)(async (promptToSend) => {
24
+ if (!promptToSend.trim())
25
+ return;
26
+ const userMessage = { role: 'user', content: promptToSend };
27
+ const newMessages = [...messages, userMessage];
28
+ setMessages(newMessages);
29
+ setInput('');
30
+ setIsLoading(true);
31
+ setError(null);
32
+ const abortController = new AbortController();
33
+ abortControllerRef.current = abortController;
34
+ try {
35
+ const response = await fetch(api, {
36
+ method: 'POST',
37
+ headers: { 'Content-Type': 'application/json' },
38
+ body: JSON.stringify({
39
+ prompt: promptToSend,
40
+ messages: newMessages,
41
+ sessionId,
42
+ }),
43
+ signal: abortController.signal,
44
+ });
45
+ onResponse?.(response);
46
+ if (!response.ok) {
47
+ const errText = await response.text().catch(() => '');
48
+ throw new Error(errText || `Request failed with status ${response.status}`);
49
+ }
50
+ if (!response.body) {
51
+ throw new Error('Response body is empty or not streamable');
52
+ }
53
+ const reader = response.body.getReader();
54
+ const decoder = new TextDecoder();
55
+ let buffer = '';
56
+ let assistantText = '';
57
+ // Add empty assistant message that will stream
58
+ setMessages((prev) => [...prev, { role: 'assistant', content: '' }]);
59
+ while (true) {
60
+ const { done, value } = await reader.read();
61
+ if (done)
62
+ break;
63
+ buffer += decoder.decode(value, { stream: true });
64
+ const lines = buffer.split('\n');
65
+ buffer = lines.pop() || '';
66
+ for (const line of lines) {
67
+ const trimmed = line.trim();
68
+ if (!trimmed.startsWith('data: '))
69
+ continue;
70
+ const payload = trimmed.slice(6);
71
+ if (payload === '[DONE]')
72
+ break;
73
+ try {
74
+ const chunk = JSON.parse(payload);
75
+ if (chunk.type === 'text-delta' && chunk.textDelta) {
76
+ assistantText += chunk.textDelta;
77
+ setMessages((prev) => {
78
+ const updated = [...prev];
79
+ const lastIdx = updated.length - 1;
80
+ if (lastIdx >= 0 && updated[lastIdx].role === 'assistant') {
81
+ updated[lastIdx] = {
82
+ ...updated[lastIdx],
83
+ content: assistantText,
84
+ };
85
+ }
86
+ return updated;
87
+ });
88
+ }
89
+ else if (chunk.type === 'error' && chunk.error) {
90
+ throw new Error(chunk.error);
91
+ }
92
+ }
93
+ catch {
94
+ // Ignore partial JSON chunks
95
+ }
96
+ }
97
+ }
98
+ const finalAssistantMessage = {
99
+ role: 'assistant',
100
+ content: assistantText,
101
+ };
102
+ onFinish?.(finalAssistantMessage);
103
+ }
104
+ catch (err) {
105
+ if (err?.name === 'AbortError')
106
+ return;
107
+ const e = err instanceof Error ? err : new Error(String(err));
108
+ setError(e);
109
+ onError?.(e);
110
+ }
111
+ finally {
112
+ setIsLoading(false);
113
+ abortControllerRef.current = null;
114
+ }
115
+ }, [api, messages, sessionId, onResponse, onFinish, onError]);
116
+ const handleSubmit = (0, react_1.useCallback)(async (e, submitOptions) => {
117
+ e?.preventDefault?.();
118
+ const promptToSend = submitOptions?.prompt ?? input;
119
+ await sendPrompt(promptToSend);
120
+ }, [input, sendPrompt]);
121
+ const reload = (0, react_1.useCallback)(async () => {
122
+ const lastUserMessage = [...messages].reverse().find((m) => m.role === 'user');
123
+ if (lastUserMessage) {
124
+ await sendPrompt(lastUserMessage.content);
125
+ }
126
+ }, [messages, sendPrompt]);
127
+ return {
128
+ messages,
129
+ input,
130
+ setInput,
131
+ handleInputChange,
132
+ handleSubmit,
133
+ isLoading,
134
+ error,
135
+ stop,
136
+ reload,
137
+ };
138
+ }
@@ -0,0 +1,24 @@
1
+ import type { StreamChunk, TokenUsage, ToolCall } from './types';
2
+ export declare class AgentStream implements AsyncIterable<StreamChunk> {
3
+ private source;
4
+ constructor(source: AsyncIterable<StreamChunk>);
5
+ [Symbol.asyncIterator](): AsyncIterator<StreamChunk>;
6
+ /**
7
+ * Converts the stream into a Server-Sent Events (SSE) Response.
8
+ * Format is compatible with UI clients and standard EventSource.
9
+ */
10
+ toDataStreamResponse(init?: ResponseInit): Response;
11
+ /**
12
+ * Converts the stream into a simple text-only Response stream.
13
+ */
14
+ toTextStreamResponse(init?: ResponseInit): Response;
15
+ /**
16
+ * Collects all text and events from the stream into a single result.
17
+ */
18
+ collect(): Promise<{
19
+ text: string;
20
+ toolCalls: ToolCall[];
21
+ usage?: TokenUsage;
22
+ }>;
23
+ }
24
+ export declare function createAIStreamResponse(stream: AsyncIterable<StreamChunk> | AgentStream, init?: ResponseInit): Response;