grisp-shadow-fleet / tests /model-tools.test.ts
SNAPKITTYWEST's picture
push from SNAPKITTYWEST/grisp-shadow-fleet
b8a03fa verified
Raw
History Blame Contribute Delete
1.61 kB
import { buildSystemPrompt } from '../desktop/backend/model-client.js';
import {
formatToolResultForModel,
parseToolCall,
removeToolCallJson,
SOVEREIGN_TOOLS,
} from '../desktop/backend/tools.js';
test('model system prompt exposes only the allowlisted sovereign tools', () => {
const prompt = buildSystemPrompt(SOVEREIGN_TOOLS);
expect(prompt).toContain('Never ask the user for secret keys');
expect(prompt).toContain('workspace.search');
expect(prompt).toContain('repo.verify');
expect(prompt).not.toContain('git push');
expect(prompt).not.toContain('shell');
});
test('model tool call parser accepts raw and fenced JSON requests', () => {
expect(parseToolCall('{"name":"repo.status","input":{}}')).toEqual({
name: 'repo.status',
input: {},
});
expect(parseToolCall([
'```json',
'{"tool_call":{"name":"workspace.read_file","input":{"path":"README.md"}}}',
'```',
].join('\n'))).toEqual({
name: 'workspace.read_file',
input: { path: 'README.md' },
});
});
test('tool call cleanup removes JSON control payloads from chat-visible text', () => {
const fenced = [
'```json',
'{"tool_call":{"name":"repo.status","input":{}}}',
'```',
].join('\n');
expect(removeToolCallJson(fenced)).toBe('');
expect(removeToolCallJson(`Need context.\n\n${fenced}`)).toBe('Need context.');
});
test('tool result formatter returns a structured model followup payload', () => {
expect(formatToolResultForModel(
{ name: 'repo.status', input: {} },
{ name: 'repo.status', ok: true, output: '## main' },
)).toContain('"tool_result"');
});