fix(local): merge system prompts for vLLM
This commit is contained in:
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');
|
||||
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', () => {
|
||||
|
||||
+6
-3
@@ -744,9 +744,12 @@ class LocalAdapter implements LLMProviderAdapter {
|
||||
+ (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.');
|
||||
const out: { role: string; content: string }[] = [{ role: 'system', content: preamble }];
|
||||
const systemParts = [preamble];
|
||||
const out: { role: string; content: string }[] = [];
|
||||
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(', ')}]` });
|
||||
} else if (m.role === 'tool') {
|
||||
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 });
|
||||
}
|
||||
}
|
||||
return out;
|
||||
return [{ role: 'system', content: systemParts.join('\n\n') }, ...out];
|
||||
}
|
||||
|
||||
async chat(messages: LLMMessage[], options?: ChatOptions): Promise<LLMResponse> {
|
||||
|
||||
Reference in new issue
Block a user