feat(chat): bind the steward channel defaults to the operator credential - #4417
huangruiteng wants to merge 4 commits into
Conversation
1933637 to
3eed1a4
Compare
8b35803 to
25f712b
Compare
3eed1a4 to
5740c4f
Compare
25f712b to
ea96161
Compare
The steward (manager) channel still defaulted to one individual's CLI login: executor endpoint `codex` plus the vendor model `gpt-6-astra`, overridable only by `LOOPX_MANAGER_MODEL`. Quote the operator credential facts from one shared module (`loopx/control_plane/operator_credential.py`) so the governed Turn surface and the chat channel cannot drift, and resolve the steward defaults from it: with a credential configured the steward model follows the operator provider (`deepseek-flash`) instead of the vendor default, without one it keeps `gpt-6-astra`, and `LOOPX_MANAGER_MODEL` still wins. The interactive chat transport is a separate fact from the credential. A resolved endpoint without one reports the typed `dsh_chat_transport_unsupported` reason instead of silently downgrading, and a session request that names such a host fails as the typed `managed_host_chat_transport_unsupported` host-tool gate rather than an untyped unknown-endpoint error. Readback: `manager_channel_binding` reaches the Chat capabilities `manager` block, the manager context, the dashboard schema, and the Lark routing fallback. The credential variable name is reported, never its value. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…port gate Record the resolved executor/model, their source, the chat-transport reason, and the capabilities readback the frontend can show, plus the host-tool gate a managed host without a chat transport raises. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
…tract Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
ea96161 to
90f4f2f
Compare
The steward channel now selects its executor and its model, and a configured operator credential re-points neither. The previous rule resolved the channel onto the managed host when DEEPSEEK_API_KEY was present while the endpoint stayed codex, because dsh has no interactive Chat transport -- so the executor and the model disagreed, and the swapped model was handed to the Codex adapter. - manager_channel_binding resolves the endpoint from explicit configuration only; `codex` is the shipped default and LOOPX_MANAGER_ENDPOINT re-points it. - The steward model follows the selected executor, so the shipped CLI endpoint keeps the vendor default and manager_model_config no longer reads the credential. - The managed Turn host fails closed as the typed managed_host_chat_transport_unsupported host-tool gate instead of an unknown endpoint ValueError, in the Chat service and Lark routing. - The three hardcoded endpoint fallbacks now resolve through the one function that owns the rule, and Chat capabilities carry the binding for frontend readback. Replaces the steward half of the stacked chain (#4417). Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
|
Superseded by #4446 ( The value here is kept: the steward channel binding, the typed Concretely, the previous shape could resolve an endpoint of The dashboard schema and packaged |
Summary
The steward (manager) chat channel now binds its own executor and model defaults
to the operator credential, for the same reason the governed Turn surface does:
a configured operator credential must not silently fall back to one individual's
CLI login. Stacked on the managed executor readback change.
Changes
loopx/control_plane/operator_credential.pyholds the operator credentialfacts once; the Turn host binding re-uses it instead of keeping a second copy.
manager_channel_binding()projects the resolved executor endpoint, itssource, a typed transport reason, the resolved model with its source, and the
credential env var name (never its value).
manager_model_config()defaults the model to the operator provider(
deepseek-flash) when a credential is configured and keeps the vendor defaultotherwise;
LOOPX_MANAGER_MODELstill wins.open_manager_session()resolves its endpoint only when the caller did not setone; the Lark routing fallbacks resolve the same default.
the typed
managed_host_chat_transport_unsupportedhost-tool gate (Chat 424with gate, Lark 400 with gate) instead of
unknown Agent endpoint.channel_bindingnext tomodel_defaults.Validation
tests/test_manager_channel_binding.py(10 cases: defaults, credentialbinding, blank credential, override precedence, process environment,
endpoint resolution, typed gate, unknown endpoint, capability projection with
and without a binding) plus
tests/test_chat_manager_context.py: 22 testsgreen.
channel, chat manager context/details/inspection, Lark API contract, manager
context handoff/roundtrip/tracking, Turn default host, and Turn executor
suites.
examples/loopx-steward-channel-binding-smoke.pyproves the binding, theoverride, the no-credential default, and the typed gate.
Boundaries
that limit explicit instead of half-connecting the steward channel.
Review notes
(
chat_agent.agent_endpoint_error), sochat_runtime.pydoes not grow(1498 lines, limit 1500) and
chat_server.pystays at its reviewed 1513-lineceiling; the unused
OPERATOR_CREDENTIAL_ENV_VARSimport is removed.source (
loopx/web/chat/index.html,asset-retention.json, hashed assets),which is what
Verify packaged Personal Workspace is currentcompares.manager-channel/context tests, 68 Turn tests, and
examples/loopx-steward-channel-binding-smoke.pygreen.