fix(runtime-sdk): align runtime.llm with the sandbox runtime facade contract - #665
Open
Byc4i wants to merge 1 commit into
Open
fix(runtime-sdk): align runtime.llm with the sandbox runtime facade contract#665Byc4i wants to merge 1 commit into
Byc4i wants to merge 1 commit into
Conversation
…ontract runtime.llm previously ignored the managed sandbox facade environment and always called the public LLMService Generate endpoint, which cannot work from an isolated guest (127.0.0.1 resolves to the guest itself) and never authenticates with the injected facade token. Resolve the endpoint in contract order: 1. An explicit baseUrl keeps selecting the legacy LLMService Generate endpoint (backwards compatible, no token). 2. The managed facade environment (OPENAI_BASE_URL / ANTHROPIC_BASE_URL, or AGENT_COMPOSE_RUNTIME_BASE_URL + SANDBOX_ID) selects the sandbox runtime LLM facade, authenticated via x-api-key with AGENT_COMPOSE_SANDBOX_TOKEN (falling back to the family-specific OPENAI_API_KEY / ANTHROPIC_AUTH_TOKEN / ANTHROPIC_API_KEY). The wire protocol follows LLM_API_PROTOCOL: OpenAI Responses by default, Anthropic Messages for anthropic_messages. 3. Without facade configuration, the legacy BASE_URL/HTTP_URL chain is preserved. Structured output maps to strict text.format json_schema on the Responses facade and prompt-guided JSON on the Anthropic facade. Facade tokens are redacted from thrown errors and never logged. Cover managed URL resolution, authorization, explicit overrides, missing configuration, timeout, and non-2xx responses with unit tests, and add a host-side integration test proving the guest-injected credential reaches the authenticated sandbox facade. README and the runtime contract document now describe the same URL and authentication behavior. Closes chaitin#555
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR: fix(runtime-sdk): align runtime.llm with the sandbox runtime facade contract
Closes #555
Problem
The guest runtime injects
AGENT_COMPOSE_RUNTIME_BASE_URLandAGENT_COMPOSE_SANDBOX_TOKENfor sandbox-scoped access to the daemon runtimefacade, but
runtime.llmconsumed neither. It always resolved the base URLfrom
BASE_URL/HTTP_URL(falling back tohttp://127.0.0.1:7410, which inan isolated guest points at the guest itself) and sent no sandbox bearer
token, diverging from the managed runtime environment and from the
token-required runtime facade routes.
Solution
runtime.llmnow resolves its endpoint in the contract order from #555:baseUrloption — always selects the legacy publicagentcompose.v2.LLMService/GenerateConnect JSON endpoint (backwardscompatible, no token).
OPENAI_BASE_URL/ANTHROPIC_BASE_URL, or is derived fromAGENT_COMPOSE_RUNTIME_BASE_URL+SANDBOX_ID; the call authenticates withAGENT_COMPOSE_SANDBOX_TOKEN(falling back to the family-specificOPENAI_API_KEY/ANTHROPIC_AUTH_TOKEN/ANTHROPIC_API_KEY) sent asx-api-key. The wire protocol followsLLM_API_PROTOCOL: OpenAI Responsesby default, Anthropic Messages for
anthropic_messages(thechat_completionstoken is also valid for the shared OpenAI facade base).BASE_URL/HTTP_URL/AGENT_COMPOSE_BASE_URL/AGENT_COMPOSE_HTTP_URL/127.0.0.1:7410chain is preserved unchanged.Structured output maps to strict
text.format: json_schemaon the OpenAIResponses facade and to prompt-guided JSON on the Anthropic Messages facade.
Response decoding handles Connect JSON, OpenAI Responses (
output_text/output[].content[].text), and Anthropic Messages (content[].text) shapes.Secret handling
The facade token is used only to build the request credential header. Error
messages pass through a redactor for every credential environment variable, so
tokens never appear in thrown errors, stdout, stderr, or persisted artifacts.
Testing
runtime/agent-compose-runtime-sdk/test/llm-facade.test.ts,9 cases): managed URL resolution (family base URL and
AGENT_COMPOSE_RUNTIME_BASE_URL+SANDBOX_IDderivation), authorizationheader, both wire protocols,
outputSchemamapping for both protocols,explicit
baseUrloverride, legacy fallback, missing-model validation,timeout, non-2xx responses, and token redaction. Full SDK suite: 50/50 pass,
tsc --noEmitclean.(
pkg/agentcompose/proxy/runtime_llm_guest_integration_test.go): shapes arequest exactly as the SDK does inside a managed guest (
x-api-key+Responses payload against the sandbox facade URL) and verifies the injected
credential passes facade authorization and reaches the upstream; the same
request without the credential is rejected with 401. Full
pkg/agentcompose/proxysuite passes.Documentation
runtime/agent-compose-runtime-sdk/README.mdanddocs/design/agent-compose-runtime_contract.mdnow describe the same URLresolution order, facade authentication, and wire-protocol behavior,
including the secret-handling guarantee.
Notes for reviewers
LLMService.Generatepath is deliberately kept and tested(contract item 5): explicit
baseUrland non-managed environments behaveexactly as before, so existing out-of-sandbox consumers are unaffected.
chat_completionsresolves to the OpenAI Responses facade endpoint becausethe daemon's runtime facade binds both OpenAI wire protocols to the same
token and base URL; the handler validates token/protocol compatibility.