chore: initial commit
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
# Protocol conversion
|
||||
|
||||
Public entry points are `ConvertRequest`, `ConvertResponse`, `Stream`, and
|
||||
`ExtractUsage`. No external dependencies are needed. The service should bypass
|
||||
conversion for same-protocol non-streaming traffic. `Stream` preserves original
|
||||
SSE bytes for same-protocol traffic, including comments and CRLF, and returns
|
||||
upstream errors instead of silently swallowing them.
|
||||
|
||||
Cross-protocol support includes text, user URL/base64 images, system messages,
|
||||
function schemas and selection, multiple function calls, tool results, multi-turn
|
||||
history, and incremental tool argument JSON. Responses output item/content part/
|
||||
argument start, delta, done and terminal events are emitted. Anthropic content
|
||||
block and message lifecycles are emitted. Each write flushes when supported.
|
||||
|
||||
## Deliberate limits
|
||||
|
||||
- Anthropic output thinking/redacted_thinking blocks and their thinking/signature
|
||||
stream deltas are omitted when converting to Chat/Responses, never appended to
|
||||
visible text. Block indices and lifecycle are checked. Native Anthropic output
|
||||
bytes remain unchanged; request-side thinking is not translated.
|
||||
|
||||
- Chat output message/delta reasoning_content (string or null) is omitted only
|
||||
during cross-protocol conversion; it is never appended to visible text or
|
||||
fabricated as Anthropic thinking. Native Chat responses/SSE remain unchanged.
|
||||
Optional indices on complete Chat tool calls must match their array positions.
|
||||
|
||||
- Responses output message `phase` is accepted as metadata. Cross-protocol
|
||||
conversion deliberately omits Responses output reasoning, summaries and
|
||||
encrypted content, including their recognized stream events. They are never
|
||||
appended to visible text or converted to Anthropic thinking/signatures.
|
||||
Same-protocol responses and SSE retain these bytes unchanged. Reasoning
|
||||
item/part indices, identities and lifecycles are checked; unrelated unknown
|
||||
content and event types remain errors. Empty output-text logprobs arrays
|
||||
are accepted, but actual logprobs remain unsupported.
|
||||
- Only one choice and function tools are supported. Other reasoning/thinking blocks,
|
||||
audio/video/documents, hosted tools, citations, refusal content, logprobs,
|
||||
structured-output modes, prompt-cache controls and Responses server-side
|
||||
conversation state are rejected rather than approximated. Unknown request
|
||||
fields and unknown stream event types are rejected.
|
||||
- Anthropic targets require an explicit token limit. Developer roles,
|
||||
mid-conversation system messages, strict tool schemas and explicit image
|
||||
detail levels cannot be translated to Anthropic. The implementation currently
|
||||
conservatively rejects explicit image detail for all cross-protocol pairs.
|
||||
- Tool results must be text and cannot carry Anthropic's `is_error=true`.
|
||||
Stop sequences cannot target Responses; stop-sequence termination cannot
|
||||
be represented losslessly across protocols.
|
||||
- Responses streaming supports one output-text content part per message.
|
||||
Final content must agree with deltas; nonincremental/final-only variants
|
||||
are rejected. Tool identity must be complete before argument streaming;
|
||||
later ID/name fragments are rejected. Parallel tool argument fragments are
|
||||
tracked independently.
|
||||
- `Usage.Input` includes cache-read and cache-write tokens. Anthropic input
|
||||
counters exclude these, so they are added on extraction and subtracted on
|
||||
encoding. `Usage.Raw` holds upstream usage JSON; Anthropic stream snapshots
|
||||
are merged so final output-only usage does not erase initial input counts.
|
||||
Unknown usage remains `Known=false`; Anthropic wire messages still carry
|
||||
required zero counters until actual usage is available. OpenAI wire schemas
|
||||
have no separate Anthropic cache-write counter; it remains in returned Usage.
|
||||
- SSE events are limited to 16 MiB; generated content is retained for final
|
||||
Responses snapshots and argument validation. LF and CRLF framing is supported
|
||||
(not standalone CR). Same-protocol streams allow EOF without a terminal marker;
|
||||
cross-protocol streams report truncation. Terminal markers finish immediately.
|
||||
- Context is checked between reads and writes. A generic `io.Reader` cannot be
|
||||
interrupted safely: the service must bind upstream HTTP requests to the same
|
||||
context or close their body on cancellation. Writers/readers remain caller-owned.
|
||||
- Response transport metadata and echoed Responses request settings are not
|
||||
round-tripped. Generated IDs use cryptographic randomness if upstream omits
|
||||
an ID. No external provider or SDK integration tests have been performed.
|
||||
|
||||
Run `go test ./internal/protocol`, `go test -race -cover ./internal/protocol`,
|
||||
and `go vet ./internal/protocol`.
|
||||
Reference in New Issue
Block a user