agentuity-vscode 0.0.95 → 0.0.96
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/README.md +1 -1
- package/package.json +174 -3
- package/src/core/cliClient.ts +17 -4
- package/src/core/index.ts +1 -0
- package/src/core/logger.ts +24 -0
- package/src/extension.ts +16 -10
- package/src/features/chat/agentTools.ts +529 -0
- package/src/features/chat/agentuityParticipant.ts +4 -2
- package/src/features/chat/contextProvider.ts +374 -0
- package/src/features/chat/index.ts +2 -0
- package/src/features/codeLens/index.ts +63 -2
- package/src/features/customAgents/index.ts +252 -0
- package/src/features/devServer/devServerManager.ts +33 -15
- package/src/features/workbench/index.ts +1 -1
- package/src/vscode.proposed.chatContextProvider.d.ts +96 -0
- package/tsconfig.json +6 -4
- package/tsconfig.test.json +19 -0
|
@@ -0,0 +1,374 @@
|
|
|
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
|
+
interface AgentuityContextItem extends vscode.ChatContextItem {
|
|
8
|
+
contextType: 'workspace' | 'agents' | 'deployments' | 'devServer' | 'agent-detail';
|
|
9
|
+
agentId?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const CONTEXT_PROVIDER_ID = 'agentuity.context';
|
|
13
|
+
|
|
14
|
+
export function registerChatContextProvider(context: vscode.ExtensionContext): void {
|
|
15
|
+
if (!vscode.chat?.registerChatContextProvider) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const provider = new AgentuityContextProvider();
|
|
21
|
+
|
|
22
|
+
const disposable = vscode.chat.registerChatContextProvider(
|
|
23
|
+
[
|
|
24
|
+
{ language: 'typescript' },
|
|
25
|
+
{ language: 'javascript' },
|
|
26
|
+
{ pattern: '**/agentuity*.json' },
|
|
27
|
+
],
|
|
28
|
+
CONTEXT_PROVIDER_ID,
|
|
29
|
+
provider
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
context.subscriptions.push(disposable);
|
|
33
|
+
context.subscriptions.push(provider);
|
|
34
|
+
} catch {
|
|
35
|
+
// Chat context provider API not available
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
class AgentuityContextProvider implements vscode.ChatContextProvider<AgentuityContextItem> {
|
|
40
|
+
private readonly _onDidChangeWorkspaceChatContext = new vscode.EventEmitter<void>();
|
|
41
|
+
readonly onDidChangeWorkspaceChatContext = this._onDidChangeWorkspaceChatContext.event;
|
|
42
|
+
|
|
43
|
+
private _disposables: vscode.Disposable[] = [];
|
|
44
|
+
|
|
45
|
+
constructor() {
|
|
46
|
+
const devServer = getDevServerManager();
|
|
47
|
+
this._disposables.push(
|
|
48
|
+
devServer.onStateChanged(() => {
|
|
49
|
+
this._onDidChangeWorkspaceChatContext.fire();
|
|
50
|
+
})
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
dispose(): void {
|
|
55
|
+
this._onDidChangeWorkspaceChatContext.dispose();
|
|
56
|
+
for (const d of this._disposables) {
|
|
57
|
+
d.dispose();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async provideWorkspaceChatContext(
|
|
62
|
+
_token: vscode.CancellationToken
|
|
63
|
+
): Promise<AgentuityContextItem[]> {
|
|
64
|
+
if (!hasProject()) {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const items: AgentuityContextItem[] = [];
|
|
69
|
+
|
|
70
|
+
items.push({
|
|
71
|
+
icon: new vscode.ThemeIcon('rocket'),
|
|
72
|
+
label: 'Agentuity Project',
|
|
73
|
+
modelDescription:
|
|
74
|
+
'Summary of the Agentuity AI agent project including authentication, agents, deployments, and dev server status',
|
|
75
|
+
contextType: 'workspace',
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
return items;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async provideChatContextExplicit(
|
|
82
|
+
token: vscode.CancellationToken
|
|
83
|
+
): Promise<AgentuityContextItem[]> {
|
|
84
|
+
if (!hasProject()) {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const items: AgentuityContextItem[] = [];
|
|
89
|
+
|
|
90
|
+
items.push({
|
|
91
|
+
icon: new vscode.ThemeIcon('rocket'),
|
|
92
|
+
label: 'Agentuity: Full Project Context',
|
|
93
|
+
modelDescription:
|
|
94
|
+
'Complete Agentuity project context including all agents, deployments, data stores, and dev server status',
|
|
95
|
+
contextType: 'workspace',
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
items.push({
|
|
99
|
+
icon: new vscode.ThemeIcon('hubot'),
|
|
100
|
+
label: 'Agentuity: Agents',
|
|
101
|
+
modelDescription: 'List of all agents in this Agentuity project with their configuration',
|
|
102
|
+
contextType: 'agents',
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
items.push({
|
|
106
|
+
icon: new vscode.ThemeIcon('cloud-upload'),
|
|
107
|
+
label: 'Agentuity: Deployments',
|
|
108
|
+
modelDescription: 'Recent deployments and their status for this Agentuity project',
|
|
109
|
+
contextType: 'deployments',
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
items.push({
|
|
113
|
+
icon: new vscode.ThemeIcon('server-process'),
|
|
114
|
+
label: 'Agentuity: Dev Server',
|
|
115
|
+
modelDescription: 'Current dev server status and configuration',
|
|
116
|
+
contextType: 'devServer',
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
if (!token.isCancellationRequested) {
|
|
120
|
+
const cli = getCliClient();
|
|
121
|
+
const agentsResult = await cli.listAgents();
|
|
122
|
+
|
|
123
|
+
if (agentsResult.success && agentsResult.data) {
|
|
124
|
+
for (const agent of agentsResult.data) {
|
|
125
|
+
items.push({
|
|
126
|
+
icon: new vscode.ThemeIcon('hubot'),
|
|
127
|
+
label: `Agentuity Agent: ${agent.name}`,
|
|
128
|
+
modelDescription: `Details for the "${agent.name}" agent including configuration, tools, and recent sessions`,
|
|
129
|
+
contextType: 'agent-detail',
|
|
130
|
+
agentId: agent.id,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return items;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async resolveChatContext(
|
|
140
|
+
item: AgentuityContextItem,
|
|
141
|
+
token: vscode.CancellationToken
|
|
142
|
+
): Promise<vscode.ChatContextItem> {
|
|
143
|
+
let value: string;
|
|
144
|
+
|
|
145
|
+
switch (item.contextType) {
|
|
146
|
+
case 'workspace':
|
|
147
|
+
value = await this.resolveWorkspaceContext(token);
|
|
148
|
+
break;
|
|
149
|
+
case 'agents':
|
|
150
|
+
value = await this.resolveAgentsContext(token);
|
|
151
|
+
break;
|
|
152
|
+
case 'deployments':
|
|
153
|
+
value = await this.resolveDeploymentsContext(token);
|
|
154
|
+
break;
|
|
155
|
+
case 'devServer':
|
|
156
|
+
value = this.resolveDevServerContext();
|
|
157
|
+
break;
|
|
158
|
+
case 'agent-detail':
|
|
159
|
+
value = await this.resolveAgentDetailContext(item.agentId!, token);
|
|
160
|
+
break;
|
|
161
|
+
default:
|
|
162
|
+
value = 'No context available';
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
icon: item.icon,
|
|
167
|
+
label: item.label,
|
|
168
|
+
modelDescription: item.modelDescription,
|
|
169
|
+
value,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
private async resolveWorkspaceContext(token: vscode.CancellationToken): Promise<string> {
|
|
174
|
+
const lines: string[] = ['# Agentuity Project Context', ''];
|
|
175
|
+
|
|
176
|
+
const authStatus = getAuthStatus();
|
|
177
|
+
lines.push('## Authentication');
|
|
178
|
+
if (authStatus.state === 'authenticated' && authStatus.user) {
|
|
179
|
+
lines.push(`- Status: Authenticated`);
|
|
180
|
+
lines.push(`- User: ${authStatus.user.firstName} ${authStatus.user.lastName}`);
|
|
181
|
+
} else {
|
|
182
|
+
lines.push('- Status: Not authenticated');
|
|
183
|
+
}
|
|
184
|
+
lines.push('');
|
|
185
|
+
|
|
186
|
+
const project = getCurrentProject();
|
|
187
|
+
lines.push('## Project');
|
|
188
|
+
if (project) {
|
|
189
|
+
lines.push(`- Project ID: ${project.projectId}`);
|
|
190
|
+
lines.push(`- Organization ID: ${project.orgId}`);
|
|
191
|
+
if (project.region) {
|
|
192
|
+
lines.push(`- Region: ${project.region}`);
|
|
193
|
+
}
|
|
194
|
+
} else {
|
|
195
|
+
lines.push('- No project configuration found');
|
|
196
|
+
}
|
|
197
|
+
lines.push('');
|
|
198
|
+
|
|
199
|
+
lines.push('## Dev Server');
|
|
200
|
+
const devServer = getDevServerManager();
|
|
201
|
+
lines.push(`- Status: ${devServer.getState()}`);
|
|
202
|
+
lines.push('');
|
|
203
|
+
|
|
204
|
+
if (!token.isCancellationRequested && hasProject()) {
|
|
205
|
+
const cli = getCliClient();
|
|
206
|
+
|
|
207
|
+
const agentsResult = await cli.listAgents();
|
|
208
|
+
if (agentsResult.success && agentsResult.data) {
|
|
209
|
+
lines.push(`## Agents (${agentsResult.data.length})`);
|
|
210
|
+
for (const agent of agentsResult.data) {
|
|
211
|
+
lines.push(`- **${agent.name}** (${agent.identifier || agent.id})`);
|
|
212
|
+
if (agent.description) {
|
|
213
|
+
lines.push(` - ${agent.description}`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
lines.push('');
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (!token.isCancellationRequested) {
|
|
220
|
+
const deploymentsResult = await cli.listDeployments();
|
|
221
|
+
if (deploymentsResult.success && deploymentsResult.data) {
|
|
222
|
+
const recent = deploymentsResult.data.slice(0, 5);
|
|
223
|
+
lines.push(
|
|
224
|
+
`## Recent Deployments (${recent.length} of ${deploymentsResult.data.length})`
|
|
225
|
+
);
|
|
226
|
+
for (const dep of recent) {
|
|
227
|
+
const status = dep.active ? 'Active' : dep.state || 'Inactive';
|
|
228
|
+
const date = new Date(dep.createdAt).toLocaleDateString();
|
|
229
|
+
lines.push(`- ${dep.id.substring(0, 8)} - ${status} (${date})`);
|
|
230
|
+
}
|
|
231
|
+
lines.push('');
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return lines.join('\n');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
private async resolveAgentsContext(_token: vscode.CancellationToken): Promise<string> {
|
|
240
|
+
if (!hasProject()) {
|
|
241
|
+
return 'No Agentuity project found in workspace.';
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const cli = getCliClient();
|
|
245
|
+
const result = await cli.listAgents();
|
|
246
|
+
|
|
247
|
+
if (!result.success || !result.data) {
|
|
248
|
+
return `Failed to fetch agents: ${result.error || 'Unknown error'}`;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const lines: string[] = [`# Agentuity Agents (${result.data.length})`, ''];
|
|
252
|
+
|
|
253
|
+
for (const agent of result.data) {
|
|
254
|
+
lines.push(`## ${agent.name}`);
|
|
255
|
+
lines.push(`- ID: ${agent.id}`);
|
|
256
|
+
lines.push(`- Identifier: ${agent.identifier || 'N/A'}`);
|
|
257
|
+
if (agent.description) {
|
|
258
|
+
lines.push(`- Description: ${agent.description}`);
|
|
259
|
+
}
|
|
260
|
+
if (agent.metadata?.filename) {
|
|
261
|
+
lines.push(`- Source File: ${agent.metadata.filename}`);
|
|
262
|
+
}
|
|
263
|
+
lines.push('');
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return lines.join('\n');
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
private async resolveDeploymentsContext(_token: vscode.CancellationToken): Promise<string> {
|
|
270
|
+
if (!hasProject()) {
|
|
271
|
+
return 'No Agentuity project found in workspace.';
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const cli = getCliClient();
|
|
275
|
+
const result = await cli.listDeployments();
|
|
276
|
+
|
|
277
|
+
if (!result.success || !result.data) {
|
|
278
|
+
return `Failed to fetch deployments: ${result.error || 'Unknown error'}`;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const lines: string[] = [`# Agentuity Deployments (${result.data.length})`, ''];
|
|
282
|
+
|
|
283
|
+
for (const dep of result.data.slice(0, 10)) {
|
|
284
|
+
const status = dep.active ? 'Active' : dep.state || 'Inactive';
|
|
285
|
+
const date = new Date(dep.createdAt).toLocaleString();
|
|
286
|
+
lines.push(`## Deployment ${dep.id.substring(0, 8)}`);
|
|
287
|
+
lines.push(`- Full ID: ${dep.id}`);
|
|
288
|
+
lines.push(`- Status: ${status}`);
|
|
289
|
+
lines.push(`- Created: ${date}`);
|
|
290
|
+
if (dep.tags?.length) {
|
|
291
|
+
lines.push(`- Tags: ${dep.tags.join(', ')}`);
|
|
292
|
+
}
|
|
293
|
+
lines.push('');
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (result.data.length > 10) {
|
|
297
|
+
lines.push(`*...and ${result.data.length - 10} more deployments*`);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return lines.join('\n');
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
private resolveDevServerContext(): string {
|
|
304
|
+
const devServer = getDevServerManager();
|
|
305
|
+
const state = devServer.getState();
|
|
306
|
+
|
|
307
|
+
const lines: string[] = ['# Agentuity Dev Server', ''];
|
|
308
|
+
lines.push(`- Status: ${state}`);
|
|
309
|
+
|
|
310
|
+
if (state === 'running') {
|
|
311
|
+
lines.push('- The dev server is currently running and ready to handle requests');
|
|
312
|
+
lines.push('- Use the Agentuity Workbench to test agents locally');
|
|
313
|
+
} else if (state === 'error') {
|
|
314
|
+
lines.push('- The dev server encountered an error');
|
|
315
|
+
lines.push('- Check the output panel for details');
|
|
316
|
+
} else {
|
|
317
|
+
lines.push('- The dev server is not running');
|
|
318
|
+
lines.push('- Run `agentuity dev` or use the "Start Dev Server" command to start it');
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
return lines.join('\n');
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
private async resolveAgentDetailContext(
|
|
325
|
+
agentId: string,
|
|
326
|
+
token: vscode.CancellationToken
|
|
327
|
+
): Promise<string> {
|
|
328
|
+
if (!hasProject()) {
|
|
329
|
+
return 'No Agentuity project found in workspace.';
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const cli = getCliClient();
|
|
333
|
+
const agentsResult = await cli.listAgents();
|
|
334
|
+
|
|
335
|
+
if (!agentsResult.success || !agentsResult.data) {
|
|
336
|
+
return `Failed to fetch agent details: ${agentsResult.error || 'Unknown error'}`;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const agent = agentsResult.data.find((a) => a.id === agentId);
|
|
340
|
+
if (!agent) {
|
|
341
|
+
return `Agent with ID ${agentId} not found.`;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
const lines: string[] = [`# Agent: ${agent.name}`, ''];
|
|
345
|
+
lines.push(`- ID: ${agent.id}`);
|
|
346
|
+
lines.push(`- Identifier: ${agent.identifier || 'N/A'}`);
|
|
347
|
+
if (agent.description) {
|
|
348
|
+
lines.push(`- Description: ${agent.description}`);
|
|
349
|
+
}
|
|
350
|
+
if (agent.metadata?.filename) {
|
|
351
|
+
lines.push(`- Source File: ${agent.metadata.filename}`);
|
|
352
|
+
}
|
|
353
|
+
lines.push('');
|
|
354
|
+
|
|
355
|
+
if (!token.isCancellationRequested) {
|
|
356
|
+
const sessionsResult = await cli.listSessions({ count: 10 });
|
|
357
|
+
if (sessionsResult.success && sessionsResult.data) {
|
|
358
|
+
const recentSessions = sessionsResult.data.slice(0, 5);
|
|
359
|
+
if (recentSessions.length > 0) {
|
|
360
|
+
lines.push(`## Recent Sessions (${recentSessions.length})`);
|
|
361
|
+
for (const session of recentSessions) {
|
|
362
|
+
const status = session.success ? '✓' : '✗';
|
|
363
|
+
const time = new Date(session.created_at).toLocaleString();
|
|
364
|
+
lines.push(
|
|
365
|
+
`- ${status} ${session.id.substring(0, 8)} - ${time} (${session.trigger})`
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
return lines.join('\n');
|
|
373
|
+
}
|
|
374
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import * as vscode from 'vscode';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import * as path from 'path';
|
|
2
4
|
import { AgentCodeLensProvider, type AgentCodeLensInfo } from './agentCodeLensProvider';
|
|
3
5
|
import { getDevServerManager } from '../devServer';
|
|
4
6
|
import { getCurrentProject } from '../../core/project';
|
|
@@ -6,6 +8,59 @@ import { getAgentProvider } from '../agentExplorer';
|
|
|
6
8
|
|
|
7
9
|
const SESSIONS_BASE_URL = 'https://app-v1.agentuity.com';
|
|
8
10
|
|
|
11
|
+
interface BuildMetadataAgent {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
filename: string;
|
|
15
|
+
identifier?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface BuildMetadata {
|
|
19
|
+
agents?: BuildMetadataAgent[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function findAgentIdFromMetadata(
|
|
23
|
+
project: { rootPath: string },
|
|
24
|
+
info: AgentCodeLensInfo
|
|
25
|
+
): string | undefined {
|
|
26
|
+
try {
|
|
27
|
+
const metadataPath = path.join(project.rootPath, '.agentuity', 'agentuity.metadata.json');
|
|
28
|
+
if (!fs.existsSync(metadataPath)) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const content = fs.readFileSync(metadataPath, 'utf-8');
|
|
33
|
+
const metadata: BuildMetadata = JSON.parse(content);
|
|
34
|
+
|
|
35
|
+
if (!metadata.agents || metadata.agents.length === 0) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Try to match by identifier first
|
|
40
|
+
if (info.identifier) {
|
|
41
|
+
const byIdentifier = metadata.agents.find(
|
|
42
|
+
(a) => a.name === info.identifier || a.identifier === info.identifier
|
|
43
|
+
);
|
|
44
|
+
if (byIdentifier) {
|
|
45
|
+
return byIdentifier.id;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Try to match by filename
|
|
50
|
+
if (info.filePath) {
|
|
51
|
+
const relativePath = path.relative(project.rootPath, info.filePath);
|
|
52
|
+
const byFilename = metadata.agents.find((a) => a.filename === relativePath);
|
|
53
|
+
if (byFilename) {
|
|
54
|
+
return byFilename.id;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return undefined;
|
|
59
|
+
} catch {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
9
64
|
export function registerCodeLens(context: vscode.ExtensionContext): AgentCodeLensProvider {
|
|
10
65
|
const provider = new AgentCodeLensProvider();
|
|
11
66
|
|
|
@@ -46,8 +101,14 @@ export function registerCodeLens(context: vscode.ExtensionContext): AgentCodeLen
|
|
|
46
101
|
.getConfiguration('agentuity')
|
|
47
102
|
.get<number>('devServer.port', 3500);
|
|
48
103
|
let url = `http://localhost:${port}/workbench`;
|
|
49
|
-
|
|
50
|
-
|
|
104
|
+
|
|
105
|
+
// Get agentId from build metadata
|
|
106
|
+
const project = getCurrentProject();
|
|
107
|
+
if (project) {
|
|
108
|
+
const agentId = findAgentIdFromMetadata(project, info);
|
|
109
|
+
if (agentId) {
|
|
110
|
+
url += `?agent=${encodeURIComponent(agentId)}`;
|
|
111
|
+
}
|
|
51
112
|
}
|
|
52
113
|
|
|
53
114
|
await vscode.env.openExternal(vscode.Uri.parse(url));
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import * as vscode from 'vscode';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
|
|
4
|
+
const AGENTUITY_DEVELOPER_AGENT = `---
|
|
5
|
+
name: Agentuity Developer
|
|
6
|
+
description: Expert at building and debugging Agentuity AI agents
|
|
7
|
+
tools:
|
|
8
|
+
- agentuity-agents
|
|
9
|
+
- agentuity-status
|
|
10
|
+
- agentuity-sessions
|
|
11
|
+
- agentuity-logs
|
|
12
|
+
- agentuity-dev
|
|
13
|
+
- agentuity-deployments
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
You are an expert Agentuity developer assistant. You help build, debug, and deploy AI agents using the Agentuity platform.
|
|
17
|
+
|
|
18
|
+
## Your Capabilities
|
|
19
|
+
|
|
20
|
+
You have access to specialized Agentuity tools:
|
|
21
|
+
- **#agentuity-agents**: List all agents in the project
|
|
22
|
+
- **#agentuity-status**: Get project status (auth, config, dev server, deployments)
|
|
23
|
+
- **#agentuity-sessions**: View recent agent execution sessions
|
|
24
|
+
- **#agentuity-logs**: Get detailed logs for a specific session
|
|
25
|
+
- **#agentuity-dev**: Control the dev server (start/stop/restart/status)
|
|
26
|
+
- **#agentuity-deployments**: List deployment history
|
|
27
|
+
|
|
28
|
+
## Guidelines
|
|
29
|
+
|
|
30
|
+
1. **Before making changes**, always check the current project status with #agentuity-status
|
|
31
|
+
2. **For debugging**, fetch recent sessions and their logs to understand what went wrong
|
|
32
|
+
3. **For testing**, ensure the dev server is running before suggesting tests
|
|
33
|
+
4. **For deployment**, verify authentication status first
|
|
34
|
+
|
|
35
|
+
## Agentuity Agent Structure
|
|
36
|
+
|
|
37
|
+
Agentuity agents are TypeScript/JavaScript files that export a handler:
|
|
38
|
+
|
|
39
|
+
\`\`\`typescript
|
|
40
|
+
import { Agent } from '@agentuity/sdk';
|
|
41
|
+
|
|
42
|
+
export default new Agent({
|
|
43
|
+
name: 'my-agent',
|
|
44
|
+
description: 'What this agent does',
|
|
45
|
+
async handler(request, context) {
|
|
46
|
+
// Agent logic here
|
|
47
|
+
return context.response.text('Hello!');
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
\`\`\`
|
|
51
|
+
|
|
52
|
+
## Common Tasks
|
|
53
|
+
|
|
54
|
+
- **Create agent**: Scaffold a new agent file with proper structure
|
|
55
|
+
- **Debug failures**: Fetch session logs and analyze errors
|
|
56
|
+
- **Test locally**: Start dev server and use the Workbench
|
|
57
|
+
- **Deploy**: Run deployment after verifying all tests pass
|
|
58
|
+
`;
|
|
59
|
+
|
|
60
|
+
const AGENTUITY_REVIEWER_AGENT = `---
|
|
61
|
+
name: Agentuity Reviewer
|
|
62
|
+
description: Reviews Agentuity agent code for best practices and issues
|
|
63
|
+
tools:
|
|
64
|
+
- agentuity-agents
|
|
65
|
+
- agentuity-status
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
You are an Agentuity code reviewer. You review agent implementations for:
|
|
69
|
+
|
|
70
|
+
## Review Checklist
|
|
71
|
+
|
|
72
|
+
### Security
|
|
73
|
+
- [ ] No hardcoded secrets or API keys
|
|
74
|
+
- [ ] Input validation on all user inputs
|
|
75
|
+
- [ ] Proper error handling without leaking sensitive info
|
|
76
|
+
|
|
77
|
+
### Performance
|
|
78
|
+
- [ ] Efficient use of context and memory
|
|
79
|
+
- [ ] Appropriate timeouts for external calls
|
|
80
|
+
- [ ] No blocking operations in hot paths
|
|
81
|
+
|
|
82
|
+
### Best Practices
|
|
83
|
+
- [ ] Clear agent name and description
|
|
84
|
+
- [ ] Proper TypeScript types
|
|
85
|
+
- [ ] Meaningful error messages
|
|
86
|
+
- [ ] Appropriate logging levels
|
|
87
|
+
|
|
88
|
+
### Agentuity-Specific
|
|
89
|
+
- [ ] Correct use of \`context.response\` methods
|
|
90
|
+
- [ ] Proper handling of different content types
|
|
91
|
+
- [ ] Appropriate use of tools and integrations
|
|
92
|
+
|
|
93
|
+
## Review Output Format
|
|
94
|
+
|
|
95
|
+
Provide feedback in this format:
|
|
96
|
+
1. **Summary**: Overall assessment
|
|
97
|
+
2. **Issues**: List of problems found with severity (Critical/Warning/Info)
|
|
98
|
+
3. **Suggestions**: Improvements to consider
|
|
99
|
+
4. **Code Examples**: Show corrected code where applicable
|
|
100
|
+
`;
|
|
101
|
+
|
|
102
|
+
const AGENTUITY_DEBUGGER_AGENT = `---
|
|
103
|
+
name: Agentuity Debugger
|
|
104
|
+
description: Diagnoses and fixes issues with Agentuity agents
|
|
105
|
+
tools:
|
|
106
|
+
- agentuity-agents
|
|
107
|
+
- agentuity-status
|
|
108
|
+
- agentuity-sessions
|
|
109
|
+
- agentuity-logs
|
|
110
|
+
- agentuity-dev
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
You are an Agentuity debugging specialist. Your job is to diagnose and fix issues with AI agents.
|
|
114
|
+
|
|
115
|
+
## Debugging Workflow
|
|
116
|
+
|
|
117
|
+
1. **Gather Context**
|
|
118
|
+
- Use #agentuity-status to check project state
|
|
119
|
+
- Use #agentuity-sessions to find recent failures
|
|
120
|
+
- Use #agentuity-logs to get detailed error information
|
|
121
|
+
|
|
122
|
+
2. **Analyze**
|
|
123
|
+
- Identify error patterns
|
|
124
|
+
- Check for common issues (auth, network, timeouts)
|
|
125
|
+
- Review agent code for bugs
|
|
126
|
+
|
|
127
|
+
3. **Fix**
|
|
128
|
+
- Propose minimal, targeted fixes
|
|
129
|
+
- Explain the root cause
|
|
130
|
+
- Suggest tests to prevent regression
|
|
131
|
+
|
|
132
|
+
## Common Issues
|
|
133
|
+
|
|
134
|
+
### Agent Not Responding
|
|
135
|
+
- Check if dev server is running (#agentuity-dev status)
|
|
136
|
+
- Verify agent is properly exported
|
|
137
|
+
- Check for infinite loops or blocking calls
|
|
138
|
+
|
|
139
|
+
### Authentication Errors
|
|
140
|
+
- Verify #agentuity-status shows authenticated
|
|
141
|
+
- Check API key configuration
|
|
142
|
+
- Ensure correct environment variables
|
|
143
|
+
|
|
144
|
+
### Timeout Errors
|
|
145
|
+
- Look for slow external API calls
|
|
146
|
+
- Check for missing await statements
|
|
147
|
+
- Review promise handling
|
|
148
|
+
|
|
149
|
+
### Response Format Errors
|
|
150
|
+
- Verify correct use of context.response methods
|
|
151
|
+
- Check content-type headers
|
|
152
|
+
- Validate JSON serialization
|
|
153
|
+
`;
|
|
154
|
+
|
|
155
|
+
export async function scaffoldCustomAgents(): Promise<void> {
|
|
156
|
+
const workspaceFolders = vscode.workspace.workspaceFolders;
|
|
157
|
+
if (!workspaceFolders || workspaceFolders.length === 0) {
|
|
158
|
+
vscode.window.showErrorMessage('No workspace folder open. Open a folder first.');
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const rootPath = workspaceFolders[0].uri.fsPath;
|
|
163
|
+
const agentsDir = path.join(rootPath, '.github', 'agents');
|
|
164
|
+
|
|
165
|
+
const agents = [
|
|
166
|
+
{ name: 'agentuity-developer.agent.md', content: AGENTUITY_DEVELOPER_AGENT },
|
|
167
|
+
{ name: 'agentuity-reviewer.agent.md', content: AGENTUITY_REVIEWER_AGENT },
|
|
168
|
+
{ name: 'agentuity-debugger.agent.md', content: AGENTUITY_DEBUGGER_AGENT },
|
|
169
|
+
];
|
|
170
|
+
|
|
171
|
+
const selected = await vscode.window.showQuickPick(
|
|
172
|
+
[
|
|
173
|
+
{ label: 'All Agents', description: 'Create all Agentuity custom agents', value: 'all' },
|
|
174
|
+
{
|
|
175
|
+
label: 'Agentuity Developer',
|
|
176
|
+
description: 'Expert at building and debugging agents',
|
|
177
|
+
value: 'developer',
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
label: 'Agentuity Reviewer',
|
|
181
|
+
description: 'Reviews agent code for best practices',
|
|
182
|
+
value: 'reviewer',
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
label: 'Agentuity Debugger',
|
|
186
|
+
description: 'Diagnoses and fixes agent issues',
|
|
187
|
+
value: 'debugger',
|
|
188
|
+
},
|
|
189
|
+
],
|
|
190
|
+
{
|
|
191
|
+
placeHolder: 'Select which custom agent(s) to create',
|
|
192
|
+
title: 'Create Agentuity Custom Agents',
|
|
193
|
+
}
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
if (!selected) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const agentsDirUri = vscode.Uri.file(agentsDir);
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
await vscode.workspace.fs.createDirectory(agentsDirUri);
|
|
204
|
+
} catch {
|
|
205
|
+
// Directory might already exist
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const toCreate =
|
|
209
|
+
selected.value === 'all'
|
|
210
|
+
? agents
|
|
211
|
+
: agents.filter((a) => a.name.includes(selected.value as string));
|
|
212
|
+
|
|
213
|
+
const writtenFiles: vscode.Uri[] = [];
|
|
214
|
+
|
|
215
|
+
for (const agent of toCreate) {
|
|
216
|
+
const filePath = vscode.Uri.file(path.join(agentsDir, agent.name));
|
|
217
|
+
|
|
218
|
+
try {
|
|
219
|
+
await vscode.workspace.fs.stat(filePath);
|
|
220
|
+
const overwrite = await vscode.window.showWarningMessage(
|
|
221
|
+
`${agent.name} already exists. Overwrite?`,
|
|
222
|
+
'Yes',
|
|
223
|
+
'No'
|
|
224
|
+
);
|
|
225
|
+
if (overwrite !== 'Yes') {
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
} catch {
|
|
229
|
+
// File doesn't exist, proceed
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
await vscode.workspace.fs.writeFile(filePath, Buffer.from(agent.content, 'utf-8'));
|
|
233
|
+
writtenFiles.push(filePath);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (writtenFiles.length === 0) {
|
|
237
|
+
vscode.window.showInformationMessage('No custom agents were created.');
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
vscode.window.showInformationMessage(
|
|
242
|
+
`Created ${writtenFiles.length} custom agent${writtenFiles.length > 1 ? 's' : ''} in .github/agents/`
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
await vscode.window.showTextDocument(writtenFiles[0]);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export function registerCustomAgentCommands(context: vscode.ExtensionContext): void {
|
|
249
|
+
context.subscriptions.push(
|
|
250
|
+
vscode.commands.registerCommand('agentuity.createCustomAgents', () => scaffoldCustomAgents())
|
|
251
|
+
);
|
|
252
|
+
}
|