Skip to content

Serving completions: the llm extra

Part of the SDKs.

What an LLM provider and funduq agree on — the party that holds a real key and answers KYOK completions. Two dependencies: funduq-provider-sdk (identity is identity; the keypair class is shared because one keypair may serve agents and models at once) and openai (the wire shapes are OpenAI's chat completions — types only, no client is constructed here). No transport, no funduq, same fitness test.

Identity and signing

No payloads of its own. The offering roster's registration and deletion used to be two signed families here; they are operations on the open link now, and the link's own sign_connect — shared with the agent SDK — is the only thing this package signs.

The port and the worker

FunduqLLMLink is the abstract port a transport implements: the base translates funduq's completion request into a DeliveredCompletion, and serve is where the provider's own code takes over — the interposition point every completion passes through before any money moves. The worker is a plain CompletionHandler — an async function from DeliveredCompletion to a stream of chunks — and InProcessLLMProvider is the in-process transport driving one (in-process is a transport, not a special case, same as the agent side).

The envelopes

DeliveredCompletion is both what the handler consumes and the declared wire frame (model_dump(by_alias=True) / model_validate): the run id, the proven calling-agent identity, which model was addressed, the opaque context relayed untouched, and the run's actor chain — everything a policy needs, with no trust in funduq's summary required.

Refusing structurally

CompletionRefused(payload) raised from a handler travels to the calling agent as data — funduq relays the payload intact and never reads it. The library defines only the envelope; what a refusal means (a ceiling reached, a chain not served, anything) is vocabulary between the provider and its callers. Policy itself — spend ceilings, model allow-lists, chain checks via verify_chain — is deliberately the provider's own few lines, not a library feature; the package README carries a worked, test-pinned example.