Implement mandatory app-attribution headers per the RFC

dsh-llm owns the vocabulary (attribution.ts): AppIdentity with the version
read from the package manifest, userAgent(), and attributionHeaders(target,
identity) over a closed AttributionTarget union ('generic' | 'openrouter').
Both adapters send the headers on every provider request — llm-deepseek in
its fetch headers, llm-pi-ai through pi-ai's StreamOptions.headers — behind
an explicit attributionTarget config (never inferred from baseURL), with
mock-server tests asserting exact wire arrival and the absence of the
OpenRouter set by default.

The RFC moves to implemented/ amended with the settled identity (the
deepseek-harness token, the DeepSeek Harness title, the planned
deepseek-ai/deepseek-harness-sdk URL behind a FIXME until that repo exists)
and the explicit-config OpenRouter decision.
This commit is contained in:
Tianyi Cui
2026-07-04 18:14:42 +08:00
parent 7e6edb7474
commit 0ebb86e70f
18 changed files with 403 additions and 100 deletions

View File

@@ -0,0 +1,75 @@
import { createRequire } from 'node:module'
import { describe, expect, it } from 'vitest'
import { APP_IDENTITY, attributionHeaders, userAgent } from '@deepseek-ai/dsh-llm'
import type { AppIdentity, AttributionTarget } from '@deepseek-ai/dsh-llm'
const manifest = createRequire(import.meta.url)('../package.json') as { version: string }
/** A white-label identity exercising every override seam. */
const forkIdentity: AppIdentity = {
product: 'fork-agent',
version: '9.9.9',
title: 'Fork Agent',
url: 'https://example.com/fork-agent',
categories: ['ide-extension', 'cli-agent'],
}
describe('APP_IDENTITY', () => {
it('sources the version from the package manifest, never a hand-copied constant', () => {
expect(APP_IDENTITY.version).toBe(manifest.version)
})
it('carries only static public product facts', () => {
expect(APP_IDENTITY).toEqual({
product: 'deepseek-harness',
version: manifest.version,
title: 'DeepSeek Harness',
url: 'https://github.com/deepseek-ai/deepseek-harness-sdk',
categories: ['cli-agent'],
})
})
})
describe('userAgent', () => {
it('renders product/version with the +url comment', () => {
expect(userAgent()).toBe(
`deepseek-harness/${manifest.version} (+https://github.com/deepseek-ai/deepseek-harness-sdk)`,
)
})
it('renders a custom identity', () => {
expect(userAgent(forkIdentity)).toBe('fork-agent/9.9.9 (+https://example.com/fork-agent)')
})
})
describe('attributionHeaders', () => {
it('defaults to the provider-neutral baseline: User-Agent and nothing else', () => {
expect(attributionHeaders()).toEqual({ 'user-agent': userAgent() })
})
it('adds exactly the OpenRouter set for the openrouter target', () => {
expect(attributionHeaders('openrouter')).toEqual({
'user-agent': userAgent(),
'http-referer': APP_IDENTITY.url,
'x-openrouter-title': APP_IDENTITY.title,
'x-openrouter-categories': 'cli-agent',
})
})
it('maps a custom identity onto both targets', () => {
expect(attributionHeaders('generic', forkIdentity)).toEqual({
'user-agent': 'fork-agent/9.9.9 (+https://example.com/fork-agent)',
})
expect(attributionHeaders('openrouter', forkIdentity)).toEqual({
'user-agent': 'fork-agent/9.9.9 (+https://example.com/fork-agent)',
'http-referer': 'https://example.com/fork-agent',
'x-openrouter-title': 'Fork Agent',
'x-openrouter-categories': 'ide-extension,cli-agent',
})
})
it('rejects targets outside the closed union at runtime', () => {
expect(() => attributionHeaders('acme' as unknown as AttributionTarget))
.toThrow('unreachable variant in attributionHeaders: "acme"')
})
})