style: auto-fix ESLint issues (curly braces and formatting)
- Add curly braces to all if/else/for/while statements - Fix indentation and trailing spaces - Auto-fixed 372 linting errors using eslint --fix - Remaining issues are warnings only (non-null assertions, explicit any types)
This commit is contained in:
@@ -27,9 +27,9 @@ export function createAgentsListTool(registry: AgentConfigRegistry): Tool {
|
||||
|
||||
const lines = configs.map((c) => {
|
||||
const parts = [`- **${c.name}**`];
|
||||
if (c.modelTier) parts.push(`tier=${c.modelTier}`);
|
||||
if (c.toolProfile) parts.push(`profile=${c.toolProfile}`);
|
||||
if (c.sandbox) parts.push('sandboxed');
|
||||
if (c.modelTier) {parts.push(`tier=${c.modelTier}`);}
|
||||
if (c.toolProfile) {parts.push(`profile=${c.toolProfile}`);}
|
||||
if (c.sandbox) {parts.push('sandboxed');}
|
||||
if (c.systemPrompt) {
|
||||
const preview = c.systemPrompt.slice(0, 80).replace(/\n/g, ' ');
|
||||
parts.push(`prompt="${preview}${c.systemPrompt.length > 80 ? '...' : ''}"`);
|
||||
|
||||
@@ -31,7 +31,7 @@ function findChrome(): string {
|
||||
];
|
||||
|
||||
for (const candidate of candidates) {
|
||||
if (existsSync(candidate)) return candidate;
|
||||
if (existsSync(candidate)) {return candidate;}
|
||||
}
|
||||
|
||||
throw new Error('Chrome/Chromium not found. Set browser.executable_path in config or install Chrome.');
|
||||
@@ -120,7 +120,7 @@ export class BrowserManager {
|
||||
async shutdown(): Promise<void> {
|
||||
for (const [, page] of this.pages) {
|
||||
try {
|
||||
if (!page.isClosed()) await page.close();
|
||||
if (!page.isClosed()) {await page.close();}
|
||||
} catch { /* ignore */ }
|
||||
}
|
||||
this.pages.clear();
|
||||
|
||||
@@ -23,7 +23,7 @@ export function createCronTools(scheduler: CronScheduler): Tool[] {
|
||||
|
||||
const lines = jobNames.map((name) => {
|
||||
const job = scheduler.getJob(name);
|
||||
if (!job) return `- ${name}`;
|
||||
if (!job) {return `- ${name}`;}
|
||||
return `- **${name}** — schedule: \`${job.schedule}\`, enabled: ${job.enabled}, output: ${job.output.channel}/${job.output.peer}\n message: "${job.message.length > 80 ? job.message.slice(0, 80) + '...' : job.message}"`;
|
||||
});
|
||||
return {
|
||||
|
||||
@@ -62,8 +62,8 @@ function setupValidAuth() {
|
||||
mockExistsSync.mockReturnValue(true);
|
||||
mockReadFileSync.mockImplementation((path: unknown) => {
|
||||
const p = String(path);
|
||||
if (p.includes('creds')) return JSON.stringify(fakeCredentials);
|
||||
if (p.includes('token')) return JSON.stringify(fakeToken);
|
||||
if (p.includes('creds')) {return JSON.stringify(fakeCredentials);}
|
||||
if (p.includes('token')) {return JSON.stringify(fakeToken);}
|
||||
return '';
|
||||
});
|
||||
}
|
||||
|
||||
@@ -101,9 +101,9 @@ function formatEvents(events: EventSummary[]): string {
|
||||
return events
|
||||
.map(e => {
|
||||
const parts = [`[${e.id}] ${e.summary}`, ` Time: ${e.start} — ${e.end}`];
|
||||
if (e.location) parts.push(` Location: ${e.location}`);
|
||||
if (e.attendees.length > 0) parts.push(` Attendees: ${e.attendees.join(', ')}`);
|
||||
if (e.htmlLink) parts.push(` Link: ${e.htmlLink}`);
|
||||
if (e.location) {parts.push(` Location: ${e.location}`);}
|
||||
if (e.attendees.length > 0) {parts.push(` Attendees: ${e.attendees.join(', ')}`);}
|
||||
if (e.htmlLink) {parts.push(` Link: ${e.htmlLink}`);}
|
||||
return parts.join('\n');
|
||||
})
|
||||
.join('\n\n');
|
||||
|
||||
@@ -67,8 +67,8 @@ function setupValidAuth() {
|
||||
mockExistsSync.mockReturnValue(true);
|
||||
mockReadFileSync.mockImplementation((path: unknown) => {
|
||||
const p = String(path);
|
||||
if (p.includes('creds')) return JSON.stringify(fakeCredentials);
|
||||
if (p.includes('token')) return JSON.stringify(fakeToken);
|
||||
if (p.includes('creds')) {return JSON.stringify(fakeCredentials);}
|
||||
if (p.includes('token')) {return JSON.stringify(fakeToken);}
|
||||
return '';
|
||||
});
|
||||
}
|
||||
|
||||
@@ -67,8 +67,8 @@ function formatDocs(docs: DocSummary[]): string {
|
||||
.map(d => {
|
||||
const parts = [`[${d.id}] ${d.name}`];
|
||||
parts.push(` Modified: ${d.modifiedTime}`);
|
||||
if (d.owners.length > 0) parts.push(` Owners: ${d.owners.join(', ')}`);
|
||||
if (d.webViewLink) parts.push(` Link: ${d.webViewLink}`);
|
||||
if (d.owners.length > 0) {parts.push(` Owners: ${d.owners.join(', ')}`);}
|
||||
if (d.webViewLink) {parts.push(` Link: ${d.webViewLink}`);}
|
||||
return parts.join('\n');
|
||||
})
|
||||
.join('\n\n');
|
||||
@@ -76,7 +76,7 @@ function formatDocs(docs: DocSummary[]): string {
|
||||
|
||||
/** Extract plain text from a Google Docs document body. */
|
||||
function extractPlainText(body: import('googleapis').docs_v1.Schema$Body): string {
|
||||
if (!body.content) return '';
|
||||
if (!body.content) {return '';}
|
||||
|
||||
const parts: string[] = [];
|
||||
for (const structural of body.content) {
|
||||
|
||||
@@ -65,8 +65,8 @@ function setupValidAuth() {
|
||||
mockExistsSync.mockReturnValue(true);
|
||||
mockReadFileSync.mockImplementation((path: unknown) => {
|
||||
const p = String(path);
|
||||
if (p.includes('creds')) return JSON.stringify(fakeCredentials);
|
||||
if (p.includes('token')) return JSON.stringify(fakeToken);
|
||||
if (p.includes('creds')) {return JSON.stringify(fakeCredentials);}
|
||||
if (p.includes('token')) {return JSON.stringify(fakeToken);}
|
||||
return '';
|
||||
});
|
||||
}
|
||||
|
||||
@@ -75,11 +75,11 @@ function friendlyMimeType(mimeType: string): string {
|
||||
|
||||
/** Format file size in human-readable form. */
|
||||
function formatSize(bytes: string | undefined): string {
|
||||
if (!bytes) return '';
|
||||
if (!bytes) {return '';}
|
||||
const n = parseInt(bytes, 10);
|
||||
if (isNaN(n)) return '';
|
||||
if (n < 1024) return `${n} B`;
|
||||
if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
|
||||
if (isNaN(n)) {return '';}
|
||||
if (n < 1024) {return `${n} B`;}
|
||||
if (n < 1024 * 1024) {return `${(n / 1024).toFixed(1)} KB`;}
|
||||
return `${(n / (1024 * 1024)).toFixed(1)} MB`;
|
||||
}
|
||||
|
||||
@@ -95,9 +95,9 @@ function formatFiles(files: FileSummary[]): string {
|
||||
parts.push(` Type: ${friendlyMimeType(f.mimeType)}`);
|
||||
parts.push(` Modified: ${f.modifiedTime}`);
|
||||
const size = formatSize(f.size);
|
||||
if (size) parts.push(` Size: ${size}`);
|
||||
if (f.owners.length > 0) parts.push(` Owners: ${f.owners.join(', ')}`);
|
||||
if (f.webViewLink) parts.push(` Link: ${f.webViewLink}`);
|
||||
if (size) {parts.push(` Size: ${size}`);}
|
||||
if (f.owners.length > 0) {parts.push(` Owners: ${f.owners.join(', ')}`);}
|
||||
if (f.webViewLink) {parts.push(` Link: ${f.webViewLink}`);}
|
||||
return parts.join('\n');
|
||||
})
|
||||
.join('\n\n');
|
||||
|
||||
@@ -69,8 +69,8 @@ function setupValidAuth() {
|
||||
mockExistsSync.mockReturnValue(true);
|
||||
mockReadFileSync.mockImplementation((path: unknown) => {
|
||||
const p = String(path);
|
||||
if (p.includes('creds')) return JSON.stringify(fakeCredentials);
|
||||
if (p.includes('token')) return JSON.stringify(fakeToken);
|
||||
if (p.includes('creds')) {return JSON.stringify(fakeCredentials);}
|
||||
if (p.includes('token')) {return JSON.stringify(fakeToken);}
|
||||
return '';
|
||||
});
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ function extractTextBody(payload: {
|
||||
// Recurse into nested multipart
|
||||
if (part.parts) {
|
||||
const nested = extractTextBody(part as typeof payload);
|
||||
if (nested) return nested;
|
||||
if (nested) {return nested;}
|
||||
}
|
||||
}
|
||||
if (htmlFallback) {
|
||||
@@ -184,9 +184,9 @@ export function createGmailTools(config: NonNullable<GmailConfig>): Tool[] {
|
||||
const emails: EmailSummary[] = [];
|
||||
|
||||
for (const msg of messages) {
|
||||
if (!msg.id) continue;
|
||||
if (!msg.id) {continue;}
|
||||
const details = await fetchMessageDetails(gmail, msg.id);
|
||||
if (details) emails.push(details);
|
||||
if (details) {emails.push(details);}
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -239,9 +239,9 @@ export function createGmailTools(config: NonNullable<GmailConfig>): Tool[] {
|
||||
const emails: EmailSummary[] = [];
|
||||
|
||||
for (const msg of messages) {
|
||||
if (!msg.id) continue;
|
||||
if (!msg.id) {continue;}
|
||||
const details = await fetchMessageDetails(gmail, msg.id);
|
||||
if (details) emails.push(details);
|
||||
if (details) {emails.push(details);}
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -65,8 +65,8 @@ function setupValidAuth() {
|
||||
mockExistsSync.mockReturnValue(true);
|
||||
mockReadFileSync.mockImplementation((path: unknown) => {
|
||||
const p = String(path);
|
||||
if (p.includes('creds')) return JSON.stringify(fakeCredentials);
|
||||
if (p.includes('token')) return JSON.stringify(fakeToken);
|
||||
if (p.includes('creds')) {return JSON.stringify(fakeCredentials);}
|
||||
if (p.includes('token')) {return JSON.stringify(fakeToken);}
|
||||
return '';
|
||||
});
|
||||
}
|
||||
|
||||
@@ -86,8 +86,8 @@ function formatTasks(tasks: TaskSummary[]): string {
|
||||
.map(t => {
|
||||
const checkbox = t.status === 'completed' ? '[x]' : '[ ]';
|
||||
const parts = [`${checkbox} ${t.title}`];
|
||||
if (t.due) parts.push(` Due: ${t.due}`);
|
||||
if (t.notes) parts.push(` Notes: ${t.notes}`);
|
||||
if (t.due) {parts.push(` Due: ${t.due}`);}
|
||||
if (t.notes) {parts.push(` Notes: ${t.notes}`);}
|
||||
parts.push(` ID: ${t.id}`);
|
||||
return parts.join('\n');
|
||||
})
|
||||
|
||||
@@ -7,7 +7,7 @@ describe('image.analyze tool', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
mockClient = {
|
||||
chat: vi.fn()
|
||||
chat: vi.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -25,7 +25,7 @@ describe('image.analyze tool', () => {
|
||||
mockClient.chat = vi.fn().mockResolvedValueOnce({
|
||||
content: 'This is a beautiful sunset over the ocean.',
|
||||
stopReason: 'end_turn',
|
||||
usage: { inputTokens: 100, outputTokens: 50 }
|
||||
usage: { inputTokens: 100, outputTokens: 50 },
|
||||
});
|
||||
|
||||
const tool = createImageAnalyzeTool(mockClient);
|
||||
@@ -46,15 +46,15 @@ describe('image.analyze tool', () => {
|
||||
source: expect.objectContaining({
|
||||
type: 'url',
|
||||
media_type: 'image/jpeg',
|
||||
url: 'https://example.com/image.jpg'
|
||||
})
|
||||
}
|
||||
])
|
||||
})
|
||||
url: 'https://example.com/image.jpg',
|
||||
}),
|
||||
},
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
system: expect.stringContaining('vision assistant'),
|
||||
maxTokens: 1024
|
||||
})
|
||||
maxTokens: 1024,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -63,13 +63,13 @@ describe('image.analyze tool', () => {
|
||||
mockClient.chat = vi.fn().mockResolvedValueOnce({
|
||||
content: 'This is a sample image.',
|
||||
stopReason: 'end_turn',
|
||||
usage: { inputTokens: 100, outputTokens: 20 }
|
||||
usage: { inputTokens: 100, outputTokens: 20 },
|
||||
});
|
||||
|
||||
const tool = createImageAnalyzeTool(mockClient);
|
||||
const result = await tool.execute({
|
||||
data: base64Data,
|
||||
media_type: 'image/png'
|
||||
media_type: 'image/png',
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
@@ -87,15 +87,15 @@ describe('image.analyze tool', () => {
|
||||
source: expect.objectContaining({
|
||||
type: 'base64',
|
||||
media_type: 'image/png',
|
||||
data: base64Data
|
||||
})
|
||||
}
|
||||
])
|
||||
})
|
||||
data: base64Data,
|
||||
}),
|
||||
},
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
system: expect.stringContaining('vision assistant'),
|
||||
maxTokens: 1024
|
||||
})
|
||||
maxTokens: 1024,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -103,13 +103,13 @@ describe('image.analyze tool', () => {
|
||||
mockClient.chat = vi.fn().mockResolvedValueOnce({
|
||||
content: 'The image shows a cat sitting on a mat.',
|
||||
stopReason: 'end_turn',
|
||||
usage: { inputTokens: 100, outputTokens: 30 }
|
||||
usage: { inputTokens: 100, outputTokens: 30 },
|
||||
});
|
||||
|
||||
const tool = createImageAnalyzeTool(mockClient);
|
||||
const result = await tool.execute({
|
||||
url: 'https://example.com/cat.jpg',
|
||||
prompt: 'What is in this image?'
|
||||
prompt: 'What is in this image?',
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
@@ -120,11 +120,11 @@ describe('image.analyze tool', () => {
|
||||
expect.objectContaining({
|
||||
content: expect.arrayContaining([
|
||||
{ type: 'text', text: 'What is in this image?' },
|
||||
expect.any(Object)
|
||||
])
|
||||
})
|
||||
])
|
||||
})
|
||||
expect.any(Object),
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -132,7 +132,7 @@ describe('image.analyze tool', () => {
|
||||
mockClient.chat = vi.fn().mockResolvedValueOnce({
|
||||
content: 'This is the default prompt response.',
|
||||
stopReason: 'end_turn',
|
||||
usage: { inputTokens: 100, outputTokens: 10 }
|
||||
usage: { inputTokens: 100, outputTokens: 10 },
|
||||
});
|
||||
|
||||
const tool = createImageAnalyzeTool(mockClient);
|
||||
@@ -144,11 +144,11 @@ describe('image.analyze tool', () => {
|
||||
expect.objectContaining({
|
||||
content: expect.arrayContaining([
|
||||
{ type: 'text', text: 'Describe this image in detail.' },
|
||||
expect.any(Object)
|
||||
])
|
||||
})
|
||||
])
|
||||
})
|
||||
expect.any(Object),
|
||||
]),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
@@ -165,7 +165,7 @@ describe('image.analyze tool', () => {
|
||||
const tool = createImageAnalyzeTool(mockClient);
|
||||
const result = await tool.execute({
|
||||
url: 'https://example.com/image.jpg',
|
||||
data: 'base64data'
|
||||
data: 'base64data',
|
||||
});
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
@@ -177,7 +177,7 @@ describe('image.analyze tool', () => {
|
||||
const tool = createImageAnalyzeTool(mockClient);
|
||||
const result = await tool.execute({
|
||||
data: 'base64data',
|
||||
prompt: 'Test'
|
||||
prompt: 'Test',
|
||||
});
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
@@ -189,7 +189,7 @@ describe('image.analyze tool', () => {
|
||||
const tool = createImageAnalyzeTool(mockClient);
|
||||
const result = await tool.execute({
|
||||
data: 'base64data',
|
||||
media_type: 'image/tiff'
|
||||
media_type: 'image/tiff',
|
||||
});
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
@@ -204,13 +204,13 @@ describe('image.analyze tool', () => {
|
||||
mockClient.chat = vi.fn().mockResolvedValueOnce({
|
||||
content: 'Success',
|
||||
stopReason: 'end_turn',
|
||||
usage: { inputTokens: 10, outputTokens: 10 }
|
||||
usage: { inputTokens: 10, outputTokens: 10 },
|
||||
});
|
||||
|
||||
const tool = createImageAnalyzeTool(mockClient);
|
||||
const result = await tool.execute({
|
||||
data: 'base64data',
|
||||
media_type: mediaType
|
||||
media_type: mediaType,
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
@@ -245,12 +245,12 @@ describe('image.analyze tool', () => {
|
||||
const mockRequest = {
|
||||
messages: [] as any,
|
||||
system: '',
|
||||
maxTokens: 1024
|
||||
maxTokens: 1024,
|
||||
};
|
||||
const mockResponse = {
|
||||
content: 'Analysis complete.',
|
||||
stopReason: 'end_turn',
|
||||
usage: { inputTokens: 100, outputTokens: 10 }
|
||||
usage: { inputTokens: 100, outputTokens: 10 },
|
||||
};
|
||||
|
||||
mockClient.chat = vi.fn().mockResolvedValue(mockResponse).mockImplementationOnce(async (r) => {
|
||||
@@ -260,7 +260,7 @@ describe('image.analyze tool', () => {
|
||||
const tool = createImageAnalyzeTool(mockClient);
|
||||
await tool.execute({
|
||||
url: 'https://example.com/image.jpg',
|
||||
prompt: 'Analyze the colors.'
|
||||
prompt: 'Analyze the colors.',
|
||||
});
|
||||
|
||||
const callArgs = (mockClient.chat as any).mock.calls[0][0];
|
||||
@@ -272,12 +272,12 @@ describe('image.analyze tool', () => {
|
||||
const mockRequest = {
|
||||
messages: [] as any,
|
||||
system: '',
|
||||
maxTokens: 1024
|
||||
maxTokens: 1024,
|
||||
};
|
||||
const mockResponse = {
|
||||
content: 'Short response',
|
||||
stopReason: 'end_turn',
|
||||
usage: { inputTokens: 10, outputTokens: 10 }
|
||||
usage: { inputTokens: 10, outputTokens: 10 },
|
||||
};
|
||||
|
||||
mockClient.chat = vi.fn().mockResolvedValueOnce(mockResponse);
|
||||
@@ -294,7 +294,7 @@ describe('image.analyze tool', () => {
|
||||
mockClient.chat.mockResolvedValueOnce({
|
||||
content: expectedContent,
|
||||
stopReason: 'end_turn',
|
||||
usage: { inputTokens: 100, outputTokens: 100 }
|
||||
usage: { inputTokens: 100, outputTokens: 100 },
|
||||
});
|
||||
|
||||
const tool = createImageAnalyzeTool(mockClient);
|
||||
|
||||
@@ -21,24 +21,24 @@ export function createImageAnalyzeTool(modelClient: ModelClient): Tool {
|
||||
properties: {
|
||||
url: {
|
||||
type: 'string',
|
||||
description: 'URL of the image to analyze'
|
||||
description: 'URL of the image to analyze',
|
||||
},
|
||||
data: {
|
||||
type: 'string',
|
||||
description: 'Base64-encoded image data (alternative to url)'
|
||||
description: 'Base64-encoded image data (alternative to url)',
|
||||
},
|
||||
media_type: {
|
||||
type: 'string',
|
||||
description:
|
||||
'MIME type of the image (required when using data). One of: image/jpeg, image/png, image/gif, image/webp'
|
||||
'MIME type of the image (required when using data). One of: image/jpeg, image/png, image/gif, image/webp',
|
||||
},
|
||||
prompt: {
|
||||
type: 'string',
|
||||
description:
|
||||
'What to analyze or describe about the image. Default: "Describe this image in detail."'
|
||||
}
|
||||
'What to analyze or describe about the image. Default: "Describe this image in detail."',
|
||||
},
|
||||
},
|
||||
required: []
|
||||
required: [],
|
||||
},
|
||||
execute: async (rawArgs: unknown): Promise<ToolResult> => {
|
||||
try {
|
||||
@@ -48,7 +48,7 @@ export function createImageAnalyzeTool(modelClient: ModelClient): Tool {
|
||||
return {
|
||||
success: false,
|
||||
output: '',
|
||||
error: 'Either "url" or "data" must be provided'
|
||||
error: 'Either "url" or "data" must be provided',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ export function createImageAnalyzeTool(modelClient: ModelClient): Tool {
|
||||
return {
|
||||
success: false,
|
||||
output: '',
|
||||
error: 'Cannot provide both "url" and "data" - choose one'
|
||||
error: 'Cannot provide both "url" and "data" - choose one',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ export function createImageAnalyzeTool(modelClient: ModelClient): Tool {
|
||||
return {
|
||||
success: false,
|
||||
output: '',
|
||||
error: 'media_type is required when providing data'
|
||||
error: 'media_type is required when providing data',
|
||||
};
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ export function createImageAnalyzeTool(modelClient: ModelClient): Tool {
|
||||
return {
|
||||
success: false,
|
||||
output: '',
|
||||
error: `Invalid media_type: ${args.media_type}. Must be one of: ${VALID_MEDIA_TYPES.join(', ')}`
|
||||
error: `Invalid media_type: ${args.media_type}. Must be one of: ${VALID_MEDIA_TYPES.join(', ')}`,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -80,42 +80,42 @@ export function createImageAnalyzeTool(modelClient: ModelClient): Tool {
|
||||
|
||||
const imageSource = args.url
|
||||
? {
|
||||
type: 'url' as const,
|
||||
media_type: args.media_type || 'image/jpeg',
|
||||
url: args.url
|
||||
}
|
||||
type: 'url' as const,
|
||||
media_type: args.media_type || 'image/jpeg',
|
||||
url: args.url,
|
||||
}
|
||||
: {
|
||||
type: 'base64' as const,
|
||||
media_type: args.media_type!,
|
||||
data: args.data
|
||||
};
|
||||
type: 'base64' as const,
|
||||
media_type: args.media_type!,
|
||||
data: args.data,
|
||||
};
|
||||
|
||||
const message = {
|
||||
role: 'user' as const,
|
||||
content: [
|
||||
{ type: 'text' as const, text: prompt },
|
||||
{ type: 'image' as const, source: imageSource }
|
||||
]
|
||||
{ type: 'image' as const, source: imageSource },
|
||||
],
|
||||
};
|
||||
|
||||
const response = await modelClient.chat({
|
||||
messages: [message],
|
||||
system:
|
||||
'You are a vision assistant. Analyze the provided image according to the user\'s request. Provide detailed, helpful descriptions.',
|
||||
maxTokens: 1024
|
||||
maxTokens: 1024,
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: response.content
|
||||
output: response.content,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
output: '',
|
||||
error: error instanceof Error ? error.message : String(error)
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ export function createMemorySearchTool(store: MemoryStore, hybridSearch?: Hybrid
|
||||
const formatted = results.map((result) => {
|
||||
const sourceLabel = result.source === 'both' ? 'keyword+vector'
|
||||
: result.source === 'vector' ? 'vector'
|
||||
: 'keyword';
|
||||
: 'keyword';
|
||||
return `[${result.namespace}:${result.line}] (${sourceLabel}, score: ${result.score.toFixed(3)}) ${result.content}\n context: ${result.context}`;
|
||||
}).join('\n\n');
|
||||
|
||||
@@ -66,7 +66,7 @@ export function createMemorySearchTool(store: MemoryStore, hybridSearch?: Hybrid
|
||||
|
||||
// Format each result as a readable block with namespace, line number, and context
|
||||
const formatted = results.map((result) =>
|
||||
`[${result.namespace}:${result.line}] ${result.content}\n context: ${result.context}`
|
||||
`[${result.namespace}:${result.line}] ${result.content}\n context: ${result.context}`,
|
||||
).join('\n\n');
|
||||
|
||||
return {
|
||||
|
||||
@@ -21,7 +21,7 @@ export function createProcessListTool(manager: ProcessManager): Tool {
|
||||
? `${Math.round((Date.now() - p.startedAt) / 1000)}s`
|
||||
: 'N/A';
|
||||
let line = `${p.id} PID=${p.pid} status=${p.status} uptime=${uptime} cmd="${p.command}"`;
|
||||
if (p.exitCode !== undefined) line += ` exit=${p.exitCode}`;
|
||||
if (p.exitCode !== undefined) {line += ` exit=${p.exitCode}`;}
|
||||
return line;
|
||||
});
|
||||
|
||||
|
||||
@@ -204,7 +204,7 @@ describe('Process tools', () => {
|
||||
let manager: ProcessManager;
|
||||
|
||||
afterEach(async () => {
|
||||
if (manager) await manager.shutdown();
|
||||
if (manager) {await manager.shutdown();}
|
||||
});
|
||||
|
||||
it('process.start tool creates and returns process info', async () => {
|
||||
|
||||
@@ -39,7 +39,7 @@ export class RingBuffer {
|
||||
|
||||
/** Read all buffered data as a UTF-8 string. */
|
||||
read(): string {
|
||||
if (this.length === 0) return '';
|
||||
if (this.length === 0) {return '';}
|
||||
|
||||
if (this.length < this.capacity) {
|
||||
// Buffer not full — data is contiguous, starting at (writePos - length)
|
||||
@@ -202,15 +202,15 @@ export class ProcessManager {
|
||||
/** Get recent output from a process's ring buffer. */
|
||||
getOutput(id: string): string {
|
||||
const proc = this.processes.get(id);
|
||||
if (!proc) throw new Error(`Process ${id} not found`);
|
||||
if (!proc) {throw new Error(`Process ${id} not found`);}
|
||||
return proc.outputBuffer.read();
|
||||
}
|
||||
|
||||
/** Kill a process by sending a signal. Returns true if signal was sent. */
|
||||
kill(id: string, signal: NodeJS.Signals = 'SIGTERM'): boolean {
|
||||
const proc = this.processes.get(id);
|
||||
if (!proc) throw new Error(`Process ${id} not found`);
|
||||
if (proc.status !== 'running') return false;
|
||||
if (!proc) {throw new Error(`Process ${id} not found`);}
|
||||
if (proc.status !== 'running') {return false;}
|
||||
|
||||
const child = this.childProcesses.get(id);
|
||||
if (child) {
|
||||
@@ -229,7 +229,7 @@ export class ProcessManager {
|
||||
runningCount(): number {
|
||||
let count = 0;
|
||||
for (const proc of this.processes.values()) {
|
||||
if (proc.status === 'running') count++;
|
||||
if (proc.status === 'running') {count++;}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
@@ -254,7 +254,7 @@ export class ProcessManager {
|
||||
}
|
||||
|
||||
const running = this.list().filter(p => p.status === 'running');
|
||||
if (running.length === 0) return;
|
||||
if (running.length === 0) {return;}
|
||||
|
||||
console.log(`[ProcessManager] Killing ${running.length} running process(es)...`);
|
||||
|
||||
|
||||
@@ -32,9 +32,9 @@ export function createProcessStatusTool(manager: ProcessManager): Tool {
|
||||
info += `PID: ${proc.pid}\n`;
|
||||
info += `Status: ${proc.status}\n`;
|
||||
info += `Uptime: ${uptime}\n`;
|
||||
if (proc.exitCode !== undefined) info += `Exit code: ${proc.exitCode}\n`;
|
||||
if (proc.errorMessage) info += `Error: ${proc.errorMessage}\n`;
|
||||
if (proc.cwd) info += `CWD: ${proc.cwd}\n`;
|
||||
if (proc.exitCode !== undefined) {info += `Exit code: ${proc.exitCode}\n`;}
|
||||
if (proc.errorMessage) {info += `Error: ${proc.errorMessage}\n`;}
|
||||
if (proc.cwd) {info += `CWD: ${proc.cwd}\n`;}
|
||||
|
||||
return { success: true, output: info.trimEnd() };
|
||||
},
|
||||
|
||||
@@ -61,7 +61,7 @@ export class ToolExecutor {
|
||||
const result = await Promise.race([
|
||||
tool.execute(args),
|
||||
new Promise<ToolResult>((_, reject) =>
|
||||
setTimeout(() => reject(new Error(`Tool '${toolName}' timed out after ${this.defaultTimeoutMs}ms`)), this.defaultTimeoutMs)
|
||||
setTimeout(() => reject(new Error(`Tool '${toolName}' timed out after ${this.defaultTimeoutMs}ms`)), this.defaultTimeoutMs),
|
||||
),
|
||||
]);
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ export class ToolRegistry {
|
||||
|
||||
/** Return tools filtered by the policy for a given context. */
|
||||
filteredList(context?: ToolPolicyContext): Tool[] {
|
||||
if (!this._policy) return this.list();
|
||||
if (!this._policy) {return this.list();}
|
||||
return this._policy.filterTools(this.list(), context);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user