agentuity-vscode 0.0.86
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/.vscode/launch.json +26 -0
- package/.vscode/tasks.json +22 -0
- package/.vscodeignore +22 -0
- package/LICENSE +21 -0
- package/README.md +156 -0
- package/package.json +476 -0
- package/resources/icon.png +0 -0
- package/resources/icon.svg +1 -0
- package/src/core/auth.ts +128 -0
- package/src/core/baseTreeDataProvider.ts +92 -0
- package/src/core/cliClient.ts +777 -0
- package/src/core/index.ts +5 -0
- package/src/core/project.ts +98 -0
- package/src/core/readonlyDocument.ts +57 -0
- package/src/core/service.ts +208 -0
- package/src/extension.ts +260 -0
- package/src/features/agentExplorer/agentTreeData.ts +149 -0
- package/src/features/agentExplorer/index.ts +105 -0
- package/src/features/chat/agentuityParticipant.ts +838 -0
- package/src/features/chat/cliTool.ts +91 -0
- package/src/features/chat/index.ts +2 -0
- package/src/features/codeLens/agentCodeLensProvider.ts +116 -0
- package/src/features/codeLens/index.ts +132 -0
- package/src/features/dataExplorer/dataTreeData.ts +480 -0
- package/src/features/dataExplorer/index.ts +362 -0
- package/src/features/deploymentExplorer/deploymentTreeData.ts +238 -0
- package/src/features/deploymentExplorer/index.ts +107 -0
- package/src/features/devServer/devServerManager.ts +258 -0
- package/src/features/devServer/index.ts +52 -0
- package/src/features/workbench/index.ts +19 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,838 @@
|
|
|
1
|
+
import * as vscode from 'vscode';
|
|
2
|
+
import { getCliClient } from '../../core/cliClient';
|
|
3
|
+
import { getAuthStatus } from '../../core/auth';
|
|
4
|
+
import { hasProject, getCurrentProject } from '../../core/project';
|
|
5
|
+
import { getDevServerManager } from '../devServer';
|
|
6
|
+
|
|
7
|
+
// Minimal CLI reference as fallback when dynamic help is unavailable
|
|
8
|
+
const CLI_REFERENCE_FALLBACK = `
|
|
9
|
+
# Agentuity CLI Quick Reference
|
|
10
|
+
|
|
11
|
+
## Key Commands
|
|
12
|
+
- \`agentuity auth login\` - Login to Agentuity
|
|
13
|
+
- \`agentuity dev\` - Start the development server
|
|
14
|
+
- \`agentuity cloud deploy\` - Deploy to Agentuity Cloud
|
|
15
|
+
- \`agentuity cloud agent list\` - List deployed agents
|
|
16
|
+
- \`agentuity cloud session list\` - List sessions
|
|
17
|
+
|
|
18
|
+
## JSON Output
|
|
19
|
+
Add \`--json\` before the command: \`agentuity --json cloud agent list\`
|
|
20
|
+
|
|
21
|
+
Use \`/help\` for complete documentation.
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
interface SlashCommand {
|
|
25
|
+
name: string;
|
|
26
|
+
description: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const SLASH_COMMANDS: SlashCommand[] = [
|
|
30
|
+
{ name: 'help', description: 'Show CLI reference and getting started guide' },
|
|
31
|
+
{ name: 'agents', description: 'List agents in this project' },
|
|
32
|
+
{ name: 'deploy', description: 'Deploy to Agentuity Cloud' },
|
|
33
|
+
{ name: 'dev', description: 'Start or stop the dev server' },
|
|
34
|
+
{ name: 'sessions', description: 'Show recent sessions' },
|
|
35
|
+
{ name: 'status', description: 'Show project and auth status' },
|
|
36
|
+
{ name: 'kv', description: 'List KV namespaces or keys in a namespace' },
|
|
37
|
+
{ name: 'db', description: 'List databases with connection info' },
|
|
38
|
+
{ name: 'vector', description: 'Search vectors in a namespace' },
|
|
39
|
+
{ name: 'deployments', description: 'List deployments with details' },
|
|
40
|
+
{ name: 'logs', description: 'View logs for a session' },
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
export function registerChatParticipant(context: vscode.ExtensionContext): void {
|
|
44
|
+
if (!vscode.chat?.createChatParticipant) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
const participant = vscode.chat.createChatParticipant(
|
|
50
|
+
'agentuity.assistant',
|
|
51
|
+
handleChatRequest
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
participant.iconPath = vscode.Uri.joinPath(context.extensionUri, 'resources', 'icon.svg');
|
|
55
|
+
|
|
56
|
+
context.subscriptions.push(participant);
|
|
57
|
+
} catch {
|
|
58
|
+
// Chat API not available in this version of VSCode
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function handleChatRequest(
|
|
63
|
+
request: vscode.ChatRequest,
|
|
64
|
+
context: vscode.ChatContext,
|
|
65
|
+
stream: vscode.ChatResponseStream,
|
|
66
|
+
token: vscode.CancellationToken
|
|
67
|
+
): Promise<vscode.ChatResult> {
|
|
68
|
+
const authStatus = getAuthStatus();
|
|
69
|
+
|
|
70
|
+
if (authStatus.state === 'cli-missing') {
|
|
71
|
+
stream.markdown('## Agentuity CLI Not Found\n\n');
|
|
72
|
+
stream.markdown('The Agentuity CLI is required. Install it with:\n\n');
|
|
73
|
+
stream.markdown('```bash\nbun install -g @agentuity/cli\n```\n\n');
|
|
74
|
+
stream.markdown(
|
|
75
|
+
'Or visit the [Getting Started Guide](https://agentuity.dev/Introduction/getting-started)'
|
|
76
|
+
);
|
|
77
|
+
stream.button({
|
|
78
|
+
title: 'Install CLI',
|
|
79
|
+
command: 'agentuity.installCli',
|
|
80
|
+
});
|
|
81
|
+
return { metadata: { command: 'error' } };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (authStatus.state === 'unauthenticated') {
|
|
85
|
+
stream.markdown('## Login Required\n\n');
|
|
86
|
+
stream.markdown('Please login to Agentuity to continue:\n\n');
|
|
87
|
+
stream.markdown('```bash\nagentuity auth login\n```\n');
|
|
88
|
+
stream.button({
|
|
89
|
+
title: 'Login',
|
|
90
|
+
command: 'agentuity.login',
|
|
91
|
+
});
|
|
92
|
+
return { metadata: { command: 'error' } };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const command = request.command;
|
|
96
|
+
if (command) {
|
|
97
|
+
return handleSlashCommand(command, request.prompt, stream, token);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return handleNaturalLanguage(request, context, stream, token);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function handleSlashCommand(
|
|
104
|
+
command: string,
|
|
105
|
+
args: string,
|
|
106
|
+
stream: vscode.ChatResponseStream,
|
|
107
|
+
_token: vscode.CancellationToken
|
|
108
|
+
): Promise<vscode.ChatResult> {
|
|
109
|
+
switch (command) {
|
|
110
|
+
case 'help':
|
|
111
|
+
return handleHelp(stream);
|
|
112
|
+
case 'agents':
|
|
113
|
+
return handleListAgents(stream);
|
|
114
|
+
case 'deploy':
|
|
115
|
+
return handleDeploy(stream);
|
|
116
|
+
case 'dev':
|
|
117
|
+
return handleDevServer(args, stream);
|
|
118
|
+
case 'sessions':
|
|
119
|
+
return handleSessions(stream);
|
|
120
|
+
case 'status':
|
|
121
|
+
return handleStatus(stream);
|
|
122
|
+
case 'kv':
|
|
123
|
+
return handleKv(args, stream);
|
|
124
|
+
case 'db':
|
|
125
|
+
return handleDb(stream);
|
|
126
|
+
case 'vector':
|
|
127
|
+
return handleVector(args, stream);
|
|
128
|
+
case 'deployments':
|
|
129
|
+
return handleDeployments(stream);
|
|
130
|
+
case 'logs':
|
|
131
|
+
return handleLogs(args, stream);
|
|
132
|
+
default:
|
|
133
|
+
stream.markdown(`Unknown command: /${command}\n\nAvailable commands:\n`);
|
|
134
|
+
for (const cmd of SLASH_COMMANDS) {
|
|
135
|
+
stream.markdown(`- \`/${cmd.name}\` - ${cmd.description}\n`);
|
|
136
|
+
}
|
|
137
|
+
return { metadata: { command: 'unknown' } };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async function handleNaturalLanguage(
|
|
142
|
+
request: vscode.ChatRequest,
|
|
143
|
+
_context: vscode.ChatContext,
|
|
144
|
+
stream: vscode.ChatResponseStream,
|
|
145
|
+
token: vscode.CancellationToken
|
|
146
|
+
): Promise<vscode.ChatResult> {
|
|
147
|
+
const prompt = request.prompt.toLowerCase();
|
|
148
|
+
|
|
149
|
+
if (prompt.includes('agent') && (prompt.includes('list') || prompt.includes('show'))) {
|
|
150
|
+
return handleListAgents(stream);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (prompt.includes('deploy') && !prompt.includes('deployment')) {
|
|
154
|
+
return handleDeploy(stream);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (prompt.includes('session') && (prompt.includes('list') || prompt.includes('show') || prompt.includes('recent'))) {
|
|
158
|
+
return handleSessions(stream);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (prompt.includes('dev') && (prompt.includes('start') || prompt.includes('stop'))) {
|
|
162
|
+
const action = prompt.includes('stop') ? 'stop' : 'start';
|
|
163
|
+
return handleDevServer(action, stream);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (prompt.includes('status') || prompt.includes('whoami')) {
|
|
167
|
+
return handleStatus(stream);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (
|
|
171
|
+
prompt.includes('help') ||
|
|
172
|
+
prompt.includes('command') ||
|
|
173
|
+
prompt.includes('how do i') ||
|
|
174
|
+
prompt.includes('what can')
|
|
175
|
+
) {
|
|
176
|
+
return handleHelp(stream);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// KV storage patterns
|
|
180
|
+
if (
|
|
181
|
+
prompt.includes('kv') ||
|
|
182
|
+
prompt.includes('key value') ||
|
|
183
|
+
prompt.includes('key-value') ||
|
|
184
|
+
(prompt.includes('storage') && prompt.includes('key'))
|
|
185
|
+
) {
|
|
186
|
+
return handleKv('', stream);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Database patterns
|
|
190
|
+
if (
|
|
191
|
+
prompt.includes('database') ||
|
|
192
|
+
prompt.includes('db') ||
|
|
193
|
+
prompt.includes('connection string') ||
|
|
194
|
+
prompt.includes('postgres')
|
|
195
|
+
) {
|
|
196
|
+
return handleDb(stream);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Vector search patterns
|
|
200
|
+
if (
|
|
201
|
+
prompt.includes('vector') ||
|
|
202
|
+
prompt.includes('embedding') ||
|
|
203
|
+
prompt.includes('semantic search')
|
|
204
|
+
) {
|
|
205
|
+
return handleVector('', stream);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Deployment patterns
|
|
209
|
+
if (
|
|
210
|
+
prompt.includes('deployment') ||
|
|
211
|
+
(prompt.includes('list') && prompt.includes('deploy'))
|
|
212
|
+
) {
|
|
213
|
+
return handleDeployments(stream);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Logs patterns
|
|
217
|
+
if (prompt.includes('log') && (prompt.includes('session') || prompt.includes('view') || prompt.includes('show'))) {
|
|
218
|
+
return handleLogs('', stream);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const models = await vscode.lm.selectChatModels({
|
|
222
|
+
vendor: 'copilot',
|
|
223
|
+
family: 'gpt-4o',
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
if (models.length === 0) {
|
|
227
|
+
return handleFallback(request.prompt, stream);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const model = models[0];
|
|
231
|
+
|
|
232
|
+
if (token.isCancellationRequested) {
|
|
233
|
+
return { metadata: { command: 'cancelled' } };
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const projectContext = await gatherProjectContext(token);
|
|
237
|
+
|
|
238
|
+
const systemPrompt = `You are the Agentuity AI assistant, helping developers build and manage AI agents using the Agentuity platform.
|
|
239
|
+
|
|
240
|
+
## Available Slash Commands
|
|
241
|
+
- /help - Show complete CLI documentation
|
|
242
|
+
- /agents - List agents in this project
|
|
243
|
+
- /deploy - Deploy to Agentuity Cloud
|
|
244
|
+
- /dev - Start or stop the dev server
|
|
245
|
+
- /sessions - Show recent sessions
|
|
246
|
+
- /status - Show project and auth status
|
|
247
|
+
|
|
248
|
+
${CLI_REFERENCE_FALLBACK}
|
|
249
|
+
|
|
250
|
+
## Current Project Context
|
|
251
|
+
${projectContext}
|
|
252
|
+
|
|
253
|
+
## Your Role
|
|
254
|
+
- Help users understand and use the Agentuity CLI and SDK
|
|
255
|
+
- Answer questions about building agents with Agentuity
|
|
256
|
+
- Suggest appropriate CLI commands for tasks
|
|
257
|
+
- Explain error messages and troubleshoot issues
|
|
258
|
+
- Suggest slash commands when they would be helpful
|
|
259
|
+
|
|
260
|
+
## Guidelines
|
|
261
|
+
- Be concise and helpful
|
|
262
|
+
- Format CLI commands as code blocks
|
|
263
|
+
- For detailed CLI help, suggest the user type \`/help\`
|
|
264
|
+
- For destructive operations (delete, deploy), always confirm with the user first
|
|
265
|
+
- Link to https://agentuity.dev for documentation`;
|
|
266
|
+
|
|
267
|
+
const messages: vscode.LanguageModelChatMessage[] = [
|
|
268
|
+
vscode.LanguageModelChatMessage.User(systemPrompt),
|
|
269
|
+
vscode.LanguageModelChatMessage.User(request.prompt),
|
|
270
|
+
];
|
|
271
|
+
|
|
272
|
+
try {
|
|
273
|
+
const response = await model.sendRequest(messages, {}, token);
|
|
274
|
+
|
|
275
|
+
for await (const chunk of response.text) {
|
|
276
|
+
if (token.isCancellationRequested) {
|
|
277
|
+
return { metadata: { command: 'cancelled' } };
|
|
278
|
+
}
|
|
279
|
+
stream.markdown(chunk);
|
|
280
|
+
}
|
|
281
|
+
} catch (err) {
|
|
282
|
+
if (token.isCancellationRequested) {
|
|
283
|
+
return { metadata: { command: 'cancelled' } };
|
|
284
|
+
}
|
|
285
|
+
if (err instanceof vscode.LanguageModelError) {
|
|
286
|
+
stream.markdown(`Error: ${err.message}\n\n`);
|
|
287
|
+
stream.markdown('Try asking a simpler question or use a slash command like `/help`.');
|
|
288
|
+
}
|
|
289
|
+
return { metadata: { command: 'error' } };
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return { metadata: { command: 'chat' } };
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
async function gatherProjectContext(token?: vscode.CancellationToken): Promise<string> {
|
|
296
|
+
const lines: string[] = [];
|
|
297
|
+
|
|
298
|
+
const authStatus = getAuthStatus();
|
|
299
|
+
lines.push(`- Authenticated: ${authStatus.state === 'authenticated' ? 'Yes' : 'No'}`);
|
|
300
|
+
if (authStatus.user) {
|
|
301
|
+
lines.push(`- User: ${authStatus.user.email}`);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (token?.isCancellationRequested) {
|
|
305
|
+
return lines.join('\n');
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const project = getCurrentProject();
|
|
309
|
+
if (project) {
|
|
310
|
+
lines.push(`- Project ID: ${project.projectId}`);
|
|
311
|
+
lines.push(`- Org ID: ${project.orgId}`);
|
|
312
|
+
if (project.region) {
|
|
313
|
+
lines.push(`- Region: ${project.region}`);
|
|
314
|
+
}
|
|
315
|
+
} else {
|
|
316
|
+
lines.push('- No Agentuity project detected in workspace');
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const devServer = getDevServerManager();
|
|
320
|
+
lines.push(`- Dev Server: ${devServer.getState()}`);
|
|
321
|
+
|
|
322
|
+
if (hasProject() && !token?.isCancellationRequested) {
|
|
323
|
+
try {
|
|
324
|
+
const cli = getCliClient();
|
|
325
|
+
const agentsResult = await cli.listAgents();
|
|
326
|
+
if (token?.isCancellationRequested) {
|
|
327
|
+
return lines.join('\n');
|
|
328
|
+
}
|
|
329
|
+
if (agentsResult.success && agentsResult.data) {
|
|
330
|
+
lines.push(`- Agents in project: ${agentsResult.data.length}`);
|
|
331
|
+
for (const agent of agentsResult.data.slice(0, 5)) {
|
|
332
|
+
lines.push(` - ${agent.name} (${agent.identifier || agent.id})`);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
} catch {
|
|
336
|
+
// Ignore errors gathering context
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return lines.join('\n');
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
async function handleHelp(stream: vscode.ChatResponseStream): Promise<vscode.ChatResult> {
|
|
344
|
+
stream.progress('Loading documentation from CLI...');
|
|
345
|
+
|
|
346
|
+
const cli = getCliClient();
|
|
347
|
+
const result = await cli.getAiPrompt();
|
|
348
|
+
|
|
349
|
+
if (result.success && result.data) {
|
|
350
|
+
stream.markdown(result.data);
|
|
351
|
+
} else {
|
|
352
|
+
stream.markdown('*Could not load dynamic help from CLI. Showing quick reference:*\n');
|
|
353
|
+
stream.markdown(CLI_REFERENCE_FALLBACK);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
stream.markdown('\n\n## Quick Actions\n\n');
|
|
357
|
+
stream.button({ title: 'Start Dev Server', command: 'agentuity.dev.start' });
|
|
358
|
+
stream.button({ title: 'Deploy', command: 'agentuity.deploy' });
|
|
359
|
+
stream.button({ title: 'Open Workbench', command: 'agentuity.workbench.open' });
|
|
360
|
+
|
|
361
|
+
return { metadata: { command: 'help' } };
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
async function handleListAgents(stream: vscode.ChatResponseStream): Promise<vscode.ChatResult> {
|
|
365
|
+
if (!hasProject()) {
|
|
366
|
+
stream.markdown('## No Project Found\n\n');
|
|
367
|
+
stream.markdown('Open a folder containing `agentuity.json` to see your agents.\n\n');
|
|
368
|
+
stream.button({ title: 'Create Project', command: 'agentuity.createProject' });
|
|
369
|
+
return { metadata: { command: 'agents' } };
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
stream.progress('Fetching agents...');
|
|
373
|
+
|
|
374
|
+
const cli = getCliClient();
|
|
375
|
+
const result = await cli.listAgents();
|
|
376
|
+
|
|
377
|
+
if (!result.success) {
|
|
378
|
+
stream.markdown(`Failed to fetch agents: ${result.error}`);
|
|
379
|
+
return { metadata: { command: 'agents' } };
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const agents = result.data || [];
|
|
383
|
+
|
|
384
|
+
if (agents.length === 0) {
|
|
385
|
+
stream.markdown('## No Agents Found\n\n');
|
|
386
|
+
stream.markdown('Create a new agent by adding a file in `src/agent/`.\n\n');
|
|
387
|
+
stream.markdown(
|
|
388
|
+
'Check the [documentation](https://agentuity.dev/Introduction/getting-started) for examples.'
|
|
389
|
+
);
|
|
390
|
+
return { metadata: { command: 'agents' } };
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
stream.markdown(`## Agents (${agents.length})\n\n`);
|
|
394
|
+
|
|
395
|
+
for (const agent of agents) {
|
|
396
|
+
const identifier = agent.identifier || agent.metadata?.identifier || agent.id;
|
|
397
|
+
stream.markdown(`### ${agent.name}\n`);
|
|
398
|
+
if (agent.description) {
|
|
399
|
+
stream.markdown(`${agent.description}\n\n`);
|
|
400
|
+
}
|
|
401
|
+
stream.markdown(`\`${identifier}\`\n\n`);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
stream.markdown('---\n\n');
|
|
405
|
+
stream.button({ title: 'View in Explorer', command: 'agentuity.agents.refresh' });
|
|
406
|
+
|
|
407
|
+
return { metadata: { command: 'agents' } };
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
async function handleDeploy(stream: vscode.ChatResponseStream): Promise<vscode.ChatResult> {
|
|
411
|
+
if (!hasProject()) {
|
|
412
|
+
stream.markdown('## No Project Found\n\n');
|
|
413
|
+
stream.markdown('You need an Agentuity project to deploy.\n\n');
|
|
414
|
+
stream.button({ title: 'Create Project', command: 'agentuity.createProject' });
|
|
415
|
+
return { metadata: { command: 'deploy' } };
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
stream.markdown('## Deploy to Agentuity Cloud\n\n');
|
|
419
|
+
stream.markdown('This will deploy your agents to Agentuity Cloud.\n\n');
|
|
420
|
+
stream.markdown('```bash\nagentuity cloud deploy\n```\n\n');
|
|
421
|
+
stream.button({ title: 'Deploy Now', command: 'agentuity.deploy' });
|
|
422
|
+
|
|
423
|
+
return { metadata: { command: 'deploy' } };
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
async function handleDevServer(
|
|
427
|
+
args: string,
|
|
428
|
+
stream: vscode.ChatResponseStream
|
|
429
|
+
): Promise<vscode.ChatResult> {
|
|
430
|
+
const devServer = getDevServerManager();
|
|
431
|
+
const currentState = devServer.getState();
|
|
432
|
+
|
|
433
|
+
if (args.includes('stop')) {
|
|
434
|
+
if (currentState === 'stopped') {
|
|
435
|
+
stream.markdown('Dev server is not running.');
|
|
436
|
+
} else {
|
|
437
|
+
stream.markdown('Stopping dev server...\n\n');
|
|
438
|
+
stream.button({ title: 'Stop Dev Server', command: 'agentuity.dev.stop' });
|
|
439
|
+
}
|
|
440
|
+
return { metadata: { command: 'dev' } };
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (args.includes('start') || args.trim() === '') {
|
|
444
|
+
if (currentState === 'running') {
|
|
445
|
+
stream.markdown('Dev server is already running.\n\n');
|
|
446
|
+
stream.button({ title: 'Show Logs', command: 'agentuity.dev.showLogs' });
|
|
447
|
+
stream.button({ title: 'Restart', command: 'agentuity.dev.restart' });
|
|
448
|
+
} else {
|
|
449
|
+
stream.markdown('## Start Dev Server\n\n');
|
|
450
|
+
stream.markdown('This will start the Agentuity dev server for local testing.\n\n');
|
|
451
|
+
stream.markdown('```bash\nagentuity dev\n```\n\n');
|
|
452
|
+
stream.button({ title: 'Start Dev Server', command: 'agentuity.dev.start' });
|
|
453
|
+
}
|
|
454
|
+
return { metadata: { command: 'dev' } };
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
stream.markdown(`## Dev Server Status: ${currentState}\n\n`);
|
|
458
|
+
if (currentState === 'running') {
|
|
459
|
+
stream.button({ title: 'Stop', command: 'agentuity.dev.stop' });
|
|
460
|
+
stream.button({ title: 'Restart', command: 'agentuity.dev.restart' });
|
|
461
|
+
stream.button({ title: 'Show Logs', command: 'agentuity.dev.showLogs' });
|
|
462
|
+
} else {
|
|
463
|
+
stream.button({ title: 'Start', command: 'agentuity.dev.start' });
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
return { metadata: { command: 'dev' } };
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
async function handleSessions(stream: vscode.ChatResponseStream): Promise<vscode.ChatResult> {
|
|
470
|
+
if (!hasProject()) {
|
|
471
|
+
stream.markdown('## No Project Found\n\n');
|
|
472
|
+
stream.markdown('Open an Agentuity project to view sessions.\n\n');
|
|
473
|
+
return { metadata: { command: 'sessions' } };
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
stream.progress('Fetching recent sessions...');
|
|
477
|
+
|
|
478
|
+
const cli = getCliClient();
|
|
479
|
+
const result = await cli.listSessions({ count: 10 });
|
|
480
|
+
|
|
481
|
+
if (!result.success) {
|
|
482
|
+
stream.markdown(`Failed to fetch sessions: ${result.error}`);
|
|
483
|
+
return { metadata: { command: 'sessions' } };
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
const sessions = result.data || [];
|
|
487
|
+
|
|
488
|
+
if (sessions.length === 0) {
|
|
489
|
+
stream.markdown('## No Sessions Found\n\n');
|
|
490
|
+
stream.markdown('Run your agents to see session data here.\n\n');
|
|
491
|
+
stream.button({ title: 'Start Dev Server', command: 'agentuity.dev.start' });
|
|
492
|
+
return { metadata: { command: 'sessions' } };
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
stream.markdown(`## Recent Sessions (${sessions.length})\n\n`);
|
|
496
|
+
stream.markdown('| Status | ID | Time | Duration | Trigger |\n');
|
|
497
|
+
stream.markdown('|--------|-----|------|----------|--------|\n');
|
|
498
|
+
|
|
499
|
+
for (const session of sessions) {
|
|
500
|
+
const status = session.success ? '✓' : '✗';
|
|
501
|
+
const shortId = session.id.substring(0, 8);
|
|
502
|
+
const time = new Date(session.created_at).toLocaleString();
|
|
503
|
+
const duration = session.duration
|
|
504
|
+
? `${(session.duration / 1_000_000).toFixed(0)}ms`
|
|
505
|
+
: '-';
|
|
506
|
+
stream.markdown(`| ${status} | ${shortId} | ${time} | ${duration} | ${session.trigger} |\n`);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
stream.markdown('\n');
|
|
510
|
+
|
|
511
|
+
return { metadata: { command: 'sessions' } };
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
async function handleStatus(stream: vscode.ChatResponseStream): Promise<vscode.ChatResult> {
|
|
515
|
+
const authStatus = getAuthStatus();
|
|
516
|
+
const project = getCurrentProject();
|
|
517
|
+
const devServer = getDevServerManager();
|
|
518
|
+
const cli = getCliClient();
|
|
519
|
+
|
|
520
|
+
stream.markdown('## Agentuity Status\n\n');
|
|
521
|
+
|
|
522
|
+
stream.markdown('### Authentication\n');
|
|
523
|
+
if (authStatus.state === 'authenticated' && authStatus.user) {
|
|
524
|
+
stream.markdown(`✓ Logged in as **${authStatus.user.email}**\n\n`);
|
|
525
|
+
} else {
|
|
526
|
+
stream.markdown(`✗ Not logged in\n\n`);
|
|
527
|
+
stream.button({ title: 'Login', command: 'agentuity.login' });
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
// Show current CLI profile
|
|
531
|
+
const profileResult = await cli.getCurrentProfile();
|
|
532
|
+
if (profileResult.success && profileResult.data) {
|
|
533
|
+
stream.markdown(`### CLI Profile\n`);
|
|
534
|
+
stream.markdown(`Active: \`${profileResult.data}\`\n\n`);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
stream.markdown('### Project\n');
|
|
538
|
+
if (project) {
|
|
539
|
+
stream.markdown(`✓ Project: \`${project.projectId}\`\n`);
|
|
540
|
+
stream.markdown(` Org: \`${project.orgId}\`\n`);
|
|
541
|
+
if (project.region) {
|
|
542
|
+
stream.markdown(` Region: ${project.region}\n`);
|
|
543
|
+
}
|
|
544
|
+
stream.markdown('\n');
|
|
545
|
+
} else {
|
|
546
|
+
stream.markdown('✗ No project detected\n\n');
|
|
547
|
+
stream.button({ title: 'Create Project', command: 'agentuity.createProject' });
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
stream.markdown('### Dev Server\n');
|
|
551
|
+
const state = devServer.getState();
|
|
552
|
+
const stateIcon = state === 'running' ? '✓' : state === 'error' ? '✗' : '○';
|
|
553
|
+
stream.markdown(`${stateIcon} ${state}\n\n`);
|
|
554
|
+
|
|
555
|
+
if (state === 'running') {
|
|
556
|
+
stream.button({ title: 'Stop', command: 'agentuity.dev.stop' });
|
|
557
|
+
stream.button({ title: 'Show Logs', command: 'agentuity.dev.showLogs' });
|
|
558
|
+
} else if (project) {
|
|
559
|
+
stream.button({ title: 'Start', command: 'agentuity.dev.start' });
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
return { metadata: { command: 'status' } };
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
async function handleKv(
|
|
566
|
+
args: string,
|
|
567
|
+
stream: vscode.ChatResponseStream
|
|
568
|
+
): Promise<vscode.ChatResult> {
|
|
569
|
+
if (!hasProject()) {
|
|
570
|
+
stream.markdown('## No Project Found\n\n');
|
|
571
|
+
stream.markdown('Open an Agentuity project to view KV data.\n\n');
|
|
572
|
+
return { metadata: { command: 'kv' } };
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
const cli = getCliClient();
|
|
576
|
+
const namespace = args.trim();
|
|
577
|
+
|
|
578
|
+
if (namespace) {
|
|
579
|
+
stream.progress(`Fetching keys in ${namespace}...`);
|
|
580
|
+
const result = await cli.listKvKeys(namespace);
|
|
581
|
+
|
|
582
|
+
if (!result.success) {
|
|
583
|
+
stream.markdown(`Failed to fetch keys: ${result.error}`);
|
|
584
|
+
return { metadata: { command: 'kv' } };
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
const keys = result.data?.keys || [];
|
|
588
|
+
|
|
589
|
+
if (keys.length === 0) {
|
|
590
|
+
stream.markdown(`## KV Namespace: ${namespace}\n\n`);
|
|
591
|
+
stream.markdown('No keys found in this namespace.\n');
|
|
592
|
+
return { metadata: { command: 'kv' } };
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
stream.markdown(`## KV Namespace: ${namespace} (${keys.length} keys)\n\n`);
|
|
596
|
+
for (const key of keys.slice(0, 20)) {
|
|
597
|
+
stream.markdown(`- \`${key}\`\n`);
|
|
598
|
+
}
|
|
599
|
+
if (keys.length > 20) {
|
|
600
|
+
stream.markdown(`\n*...and ${keys.length - 20} more*\n`);
|
|
601
|
+
}
|
|
602
|
+
} else {
|
|
603
|
+
stream.progress('Fetching KV namespaces...');
|
|
604
|
+
const result = await cli.listKvNamespaces();
|
|
605
|
+
|
|
606
|
+
if (!result.success) {
|
|
607
|
+
stream.markdown(`Failed to fetch namespaces: ${result.error}`);
|
|
608
|
+
return { metadata: { command: 'kv' } };
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
const namespaces = result.data || [];
|
|
612
|
+
|
|
613
|
+
if (namespaces.length === 0) {
|
|
614
|
+
stream.markdown('## KV Namespaces\n\n');
|
|
615
|
+
stream.markdown('No KV namespaces found.\n');
|
|
616
|
+
return { metadata: { command: 'kv' } };
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
stream.markdown(`## KV Namespaces (${namespaces.length})\n\n`);
|
|
620
|
+
for (const ns of namespaces) {
|
|
621
|
+
stream.markdown(`- \`${ns}\` - use \`/kv ${ns}\` to list keys\n`);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
return { metadata: { command: 'kv' } };
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
async function handleDb(stream: vscode.ChatResponseStream): Promise<vscode.ChatResult> {
|
|
629
|
+
if (!hasProject()) {
|
|
630
|
+
stream.markdown('## No Project Found\n\n');
|
|
631
|
+
stream.markdown('Open an Agentuity project to view databases.\n\n');
|
|
632
|
+
return { metadata: { command: 'db' } };
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
stream.progress('Fetching databases...');
|
|
636
|
+
|
|
637
|
+
const cli = getCliClient();
|
|
638
|
+
const result = await cli.listDatabases();
|
|
639
|
+
|
|
640
|
+
if (!result.success) {
|
|
641
|
+
stream.markdown(`Failed to fetch databases: ${result.error}`);
|
|
642
|
+
return { metadata: { command: 'db' } };
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
const databases = result.data?.databases || [];
|
|
646
|
+
|
|
647
|
+
if (databases.length === 0) {
|
|
648
|
+
stream.markdown('## Databases\n\n');
|
|
649
|
+
stream.markdown('No databases found.\n');
|
|
650
|
+
return { metadata: { command: 'db' } };
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
stream.markdown(`## Databases (${databases.length})\n\n`);
|
|
654
|
+
for (const db of databases) {
|
|
655
|
+
stream.markdown(`### ${db.name}\n`);
|
|
656
|
+
stream.markdown(`\`\`\`\n${db.url}\n\`\`\`\n\n`);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
stream.button({ title: 'View in Data Explorer', command: 'agentuity.data.refresh' });
|
|
660
|
+
|
|
661
|
+
return { metadata: { command: 'db' } };
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
async function handleVector(
|
|
665
|
+
args: string,
|
|
666
|
+
stream: vscode.ChatResponseStream
|
|
667
|
+
): Promise<vscode.ChatResult> {
|
|
668
|
+
if (!hasProject()) {
|
|
669
|
+
stream.markdown('## No Project Found\n\n');
|
|
670
|
+
stream.markdown('Open an Agentuity project to search vectors.\n\n');
|
|
671
|
+
return { metadata: { command: 'vector' } };
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
const parts = args.trim().split(/\s+/);
|
|
675
|
+
const namespace = parts[0];
|
|
676
|
+
const query = parts.slice(1).join(' ');
|
|
677
|
+
|
|
678
|
+
if (!namespace || !query) {
|
|
679
|
+
stream.markdown('## Vector Search\n\n');
|
|
680
|
+
stream.markdown('Usage: `/vector <namespace> <query>`\n\n');
|
|
681
|
+
stream.markdown('Example: `/vector my-namespace what is machine learning?`\n');
|
|
682
|
+
return { metadata: { command: 'vector' } };
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
stream.progress(`Searching vectors in ${namespace}...`);
|
|
686
|
+
|
|
687
|
+
const cli = getCliClient();
|
|
688
|
+
const result = await cli.vectorSearch(namespace, query);
|
|
689
|
+
|
|
690
|
+
if (!result.success) {
|
|
691
|
+
stream.markdown(`Failed to search vectors: ${result.error}`);
|
|
692
|
+
return { metadata: { command: 'vector' } };
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
const results = result.data?.results || [];
|
|
696
|
+
|
|
697
|
+
if (results.length === 0) {
|
|
698
|
+
stream.markdown(`## Vector Search: "${query}"\n\n`);
|
|
699
|
+
stream.markdown('No results found.\n');
|
|
700
|
+
return { metadata: { command: 'vector' } };
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
stream.markdown(`## Vector Search: "${query}" (${results.length} results)\n\n`);
|
|
704
|
+
for (const item of results.slice(0, 10)) {
|
|
705
|
+
const similarity = (item.similarity * 100).toFixed(1);
|
|
706
|
+
stream.markdown(`### ${item.key} (${similarity}% match)\n`);
|
|
707
|
+
if (item.metadata) {
|
|
708
|
+
stream.markdown(`\`\`\`json\n${JSON.stringify(item.metadata, null, 2)}\n\`\`\`\n\n`);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
return { metadata: { command: 'vector' } };
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
async function handleDeployments(stream: vscode.ChatResponseStream): Promise<vscode.ChatResult> {
|
|
716
|
+
if (!hasProject()) {
|
|
717
|
+
stream.markdown('## No Project Found\n\n');
|
|
718
|
+
stream.markdown('Open an Agentuity project to view deployments.\n\n');
|
|
719
|
+
return { metadata: { command: 'deployments' } };
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
stream.progress('Fetching deployments...');
|
|
723
|
+
|
|
724
|
+
const cli = getCliClient();
|
|
725
|
+
const result = await cli.listDeployments();
|
|
726
|
+
|
|
727
|
+
if (!result.success) {
|
|
728
|
+
stream.markdown(`Failed to fetch deployments: ${result.error}`);
|
|
729
|
+
return { metadata: { command: 'deployments' } };
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
const deployments = result.data || [];
|
|
733
|
+
|
|
734
|
+
if (deployments.length === 0) {
|
|
735
|
+
stream.markdown('## Deployments\n\n');
|
|
736
|
+
stream.markdown('No deployments found. Deploy your project to see deployments here.\n\n');
|
|
737
|
+
stream.button({ title: 'Deploy Now', command: 'agentuity.deploy' });
|
|
738
|
+
return { metadata: { command: 'deployments' } };
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
stream.markdown(`## Deployments (${deployments.length})\n\n`);
|
|
742
|
+
stream.markdown('| Status | ID | Created | Tags |\n');
|
|
743
|
+
stream.markdown('|--------|-----|---------|------|\n');
|
|
744
|
+
|
|
745
|
+
for (const deployment of deployments.slice(0, 10)) {
|
|
746
|
+
const status = deployment.active ? '✓ Active' : deployment.state || 'Inactive';
|
|
747
|
+
const shortId = deployment.id.substring(0, 8);
|
|
748
|
+
const created = new Date(deployment.createdAt).toLocaleDateString();
|
|
749
|
+
const tags = deployment.tags?.join(', ') || '-';
|
|
750
|
+
stream.markdown(`| ${status} | ${shortId} | ${created} | ${tags} |\n`);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
if (deployments.length > 10) {
|
|
754
|
+
stream.markdown(`\n*...and ${deployments.length - 10} more*\n`);
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
stream.markdown('\n');
|
|
758
|
+
stream.button({ title: 'View in Deployments Explorer', command: 'agentuity.deployments.refresh' });
|
|
759
|
+
|
|
760
|
+
return { metadata: { command: 'deployments' } };
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
async function handleLogs(
|
|
764
|
+
args: string,
|
|
765
|
+
stream: vscode.ChatResponseStream
|
|
766
|
+
): Promise<vscode.ChatResult> {
|
|
767
|
+
if (!hasProject()) {
|
|
768
|
+
stream.markdown('## No Project Found\n\n');
|
|
769
|
+
stream.markdown('Open an Agentuity project to view logs.\n\n');
|
|
770
|
+
return { metadata: { command: 'logs' } };
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
const sessionId = args.trim();
|
|
774
|
+
|
|
775
|
+
if (!sessionId) {
|
|
776
|
+
stream.markdown('## Session Logs\n\n');
|
|
777
|
+
stream.markdown('Usage: `/logs <session-id>`\n\n');
|
|
778
|
+
stream.markdown('Get a session ID from `/sessions` first.\n\n');
|
|
779
|
+
stream.button({ title: 'View Sessions', command: 'workbench.action.chat.open', arguments: [{ query: '@agentuity /sessions' }] });
|
|
780
|
+
return { metadata: { command: 'logs' } };
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
stream.progress(`Fetching logs for session ${sessionId.substring(0, 8)}...`);
|
|
784
|
+
|
|
785
|
+
const cli = getCliClient();
|
|
786
|
+
const result = await cli.getSessionLogs(sessionId);
|
|
787
|
+
|
|
788
|
+
if (!result.success) {
|
|
789
|
+
stream.markdown(`Failed to fetch logs: ${result.error}`);
|
|
790
|
+
return { metadata: { command: 'logs' } };
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
const logs = result.data || [];
|
|
794
|
+
|
|
795
|
+
if (logs.length === 0) {
|
|
796
|
+
stream.markdown(`## Session Logs: ${sessionId.substring(0, 8)}...\n\n`);
|
|
797
|
+
stream.markdown('No logs found for this session.\n');
|
|
798
|
+
return { metadata: { command: 'logs' } };
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
stream.markdown(`## Session Logs (${logs.length} entries)\n\n`);
|
|
802
|
+
stream.markdown('```\n');
|
|
803
|
+
for (const log of logs.slice(0, 50)) {
|
|
804
|
+
const time = new Date(log.timestamp).toLocaleTimeString();
|
|
805
|
+
const severity = log.severity.padEnd(5);
|
|
806
|
+
stream.markdown(`[${time}] ${severity} ${log.body}\n`);
|
|
807
|
+
}
|
|
808
|
+
stream.markdown('```\n');
|
|
809
|
+
|
|
810
|
+
if (logs.length > 50) {
|
|
811
|
+
stream.markdown(`\n*...and ${logs.length - 50} more entries*\n`);
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
return { metadata: { command: 'logs' } };
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
async function handleFallback(
|
|
818
|
+
_prompt: string,
|
|
819
|
+
stream: vscode.ChatResponseStream
|
|
820
|
+
): Promise<vscode.ChatResult> {
|
|
821
|
+
stream.markdown("I can help you with your Agentuity project. Here's what I can do:\n\n");
|
|
822
|
+
|
|
823
|
+
for (const cmd of SLASH_COMMANDS) {
|
|
824
|
+
stream.markdown(`- \`/${cmd.name}\` - ${cmd.description}\n`);
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
stream.markdown('\nOr ask me questions about:\n');
|
|
828
|
+
stream.markdown('- **Agents** - "List my agents", "What agents do I have?"\n');
|
|
829
|
+
stream.markdown('- **Development** - "Start the dev server", "How do I test locally?"\n');
|
|
830
|
+
stream.markdown('- **Deployment** - "Deploy my agents", "How do I deploy?"\n');
|
|
831
|
+
stream.markdown('- **Sessions** - "Show recent sessions", "View session logs"\n');
|
|
832
|
+
stream.markdown('- **CLI** - "What CLI commands are available?"\n\n');
|
|
833
|
+
|
|
834
|
+
stream.markdown('Type `/help` for complete CLI documentation.\n\n');
|
|
835
|
+
stream.button({ title: 'Show Help', command: 'workbench.action.chat.open', arguments: [{ query: '@agentuity /help' }] });
|
|
836
|
+
|
|
837
|
+
return { metadata: { command: 'fallback' } };
|
|
838
|
+
}
|