feat(llm): mark compaction requests with x-deepseek-harness-compact header
This commit is contained in:
@@ -38,7 +38,7 @@ The plugin registers the single provider route `deepseek`. A request selects it
|
||||
|
||||
## App attribution
|
||||
|
||||
Every request carries the shared attribution header from dsh-llm's `attributionHeaders()` - the mandatory `User-Agent` baseline identifying the harness (see [dsh-llm § App attribution](../llm/README.md#app-attribution-attributionts)). Direct DeepSeek requests and OpenAI-compatible gateway requests get no provider-specific app-attribution headers under this adapter contract; OpenRouter app attribution is deferred to a future explicit OpenRouter adapter or mode.
|
||||
Every request carries the shared attribution header from dsh-llm's `attributionHeaders()` - the mandatory `User-Agent` baseline identifying the harness (see [dsh-llm § App attribution](../llm/README.md#app-attribution-attributionts)). Direct DeepSeek requests and OpenAI-compatible gateway requests get no provider-specific app-attribution headers under this adapter contract; OpenRouter app attribution is deferred to a future explicit OpenRouter adapter or mode. A request with `GenerateOptions.compact` set (dsh-compact-basic's auxiliary summarization call) additionally carries `x-deepseek-harness-compact: 1`, so the host can separate compaction traffic from conversation requests.
|
||||
|
||||
## Wire-format notes (verified live + against the official docs)
|
||||
|
||||
|
||||
@@ -182,6 +182,9 @@ export class DeepSeekAdapter extends LlmAdapter {
|
||||
...options.sessionId !== undefined
|
||||
? { 'x-deepseek-harness-session-id': String(options.sessionId) }
|
||||
: {},
|
||||
...options.compact === true
|
||||
? { 'x-deepseek-harness-compact': '1' }
|
||||
: {},
|
||||
}
|
||||
|
||||
// TODO(http): adopt the Cordis HTTP service when shared transport configuration
|
||||
|
||||
@@ -129,6 +129,8 @@ describe('DeepSeekAdapter against a mock server', () => {
|
||||
expect(server.headers[0]).not.toHaveProperty('http-referer')
|
||||
expect(server.headers[0]).not.toHaveProperty('x-openrouter-title')
|
||||
expect(server.headers[0]).not.toHaveProperty('x-openrouter-categories')
|
||||
// A conversation request carries no compaction marker.
|
||||
expect(server.headers[0]).not.toHaveProperty('x-deepseek-harness-compact')
|
||||
})
|
||||
|
||||
it('streams raw chunks through ctx.llm.stream', async () => {
|
||||
@@ -159,6 +161,19 @@ describe('DeepSeekAdapter against a mock server', () => {
|
||||
expect(server.headers[0]?.['x-deepseek-harness-session-id']).toBe('child-session')
|
||||
})
|
||||
|
||||
it('marks the auxiliary compaction call on the wire', async () => {
|
||||
const server = await mockServer([{ kind: 'sse', events: textEvents }])
|
||||
const ctx = await harness(server.url)
|
||||
|
||||
await assemble(ctx, {
|
||||
model: 'deepseek-v4-flash',
|
||||
messages: [{ role: 'user', content: [{ type: 'text', text: 'hi' }] }],
|
||||
compact: true,
|
||||
})
|
||||
|
||||
expect(server.headers[0]?.['x-deepseek-harness-compact']).toBe('1')
|
||||
})
|
||||
|
||||
it('forwards thinking config onto the wire', async () => {
|
||||
const server = await mockServer([{ kind: 'sse', events: textEvents }])
|
||||
const ctx = await harness(server.url, { thinking: 'disabled', reasoningEffort: 'high' })
|
||||
|
||||
@@ -226,4 +226,11 @@ export interface GenerateOptions {
|
||||
* it; replay uses it to keep concurrent parent and child cursors independent.
|
||||
*/
|
||||
sessionId?: Branded<'SessionId'>
|
||||
/**
|
||||
* Marks the auxiliary compaction (summarization) call. The DeepSeek adapter
|
||||
* forwards it as the `x-deepseek-harness-compact: 1` request header so the
|
||||
* host can separate compaction traffic from conversation requests; it never
|
||||
* enters the model-visible request body. Loop-built requests leave it unset.
|
||||
*/
|
||||
compact?: boolean
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user