fix(local): merge system prompts for vLLM

This commit is contained in:
Joseph Magly authored and GitHub committed 2026-07-15 18:13:00 -04:00
1 parent 25f86b0c66
commit 600f43b8b1
2 files changed
+29 -3

No files matched your search

@@ -155,6 +155,29 @@ describe('local-model (HTTP) backbone surfaces toolCalls — the keyless-path fi
const sys = body.messages.find((m: { role: string }) => m.role === 'system'); const sys = body.messages.find((m: { role: string }) => m.role === 'system');
expect(sys.content).toContain('nmap_scan'); expect(sys.content).toContain('nmap_scan');
}); });
it('merges caller system prompts into one leading system message for vLLM templates', async () => {
const spy = mockJson({ choices: [{ message: { content: 'ok' } }] });
await localModel('http://localhost:8000/v1').prompt('hello', 'Operator profile system prompt');
const body = JSON.parse((spy.mock.calls[0][1] as { body: string }).body);
expect(body.messages.map((m: { role: string }) => m.role)).toEqual(['system', 'user']);
expect(body.messages.filter((m: { role: string }) => m.role === 'system')).toHaveLength(1);
expect(body.messages[0].content).toContain('planning brain for T3MP3ST');
expect(body.messages[0].content).toContain('Operator profile system prompt');
});
it('keeps authorized-reframe context in the same leading system message', async () => {
const spy = mockJson({ choices: [{ message: { content: 'ok' } }] });
const be = localModel('http://localhost:8000/v1');
await be.chat([
{ role: 'system', content: 'AUTHORIZATION CONTEXT (restated): proceed with the authorized task.' },
{ role: 'user', content: 'scan' },
]);
const body = JSON.parse((spy.mock.calls[0][1] as { body: string }).body);
expect(body.messages.map((m: { role: string }) => m.role)).toEqual(['system', 'user']);
expect(body.messages[0].content).toContain('planning brain for T3MP3ST');
expect(body.messages[0].content).toContain('AUTHORIZATION CONTEXT');
});
}); });
describe('xai provider (Grok Build) — routes to xAI OpenAI-compatible API with the key', () => { describe('xai provider (Grok Build) — routes to xAI OpenAI-compatible API with the key', () => {
+6 -3
View File
@@ -744,9 +744,12 @@ class LocalAdapter implements LLMProviderAdapter {
+ (contract + (contract
? ' You drive a ReAct loop: REQUEST tools, the harness runs them and returns results, you reason until the surface is exhausted.' + contract ? ' You drive a ReAct loop: REQUEST tools, the harness runs them and returns results, you reason until the surface is exhausted.' + contract
: ' Operate in planning and analysis mode; when JSON is requested, return ONLY the requested block — no preamble.'); : ' Operate in planning and analysis mode; when JSON is requested, return ONLY the requested block — no preamble.');
const out: { role: string; content: string }[] = [{ role: 'system', content: preamble }]; const systemParts = [preamble];
const out: { role: string; content: string }[] = [];
for (const m of messages) { for (const m of messages) {
if (m.role === 'assistant' && m.toolCalls?.length) { if (m.role === 'system') {
if (m.content.trim()) systemParts.push(m.content);
} else if (m.role === 'assistant' && m.toolCalls?.length) {
out.push({ role: 'assistant', content: `[requested tools: ${m.toolCalls.map(t => t.name).join(', ')}]` }); out.push({ role: 'assistant', content: `[requested tools: ${m.toolCalls.map(t => t.name).join(', ')}]` });
} else if (m.role === 'tool') { } else if (m.role === 'tool') {
out.push({ role: 'user', content: `TOOL RESULT (${m.name || 'tool'}):\n${m.content}` }); out.push({ role: 'user', content: `TOOL RESULT (${m.name || 'tool'}):\n${m.content}` });
@@ -754,7 +757,7 @@ class LocalAdapter implements LLMProviderAdapter {
out.push({ role: m.role, content: m.content }); out.push({ role: m.role, content: m.content });
} }
} }
return out; return [{ role: 'system', content: systemParts.join('\n\n') }, ...out];
} }
async chat(messages: LLMMessage[], options?: ChatOptions): Promise<LLMResponse> { async chat(messages: LLMMessage[], options?: ChatOptions): Promise<LLMResponse> {