mirror of
https://github.com/stablyai/orca.git
synced 2026-10-06 08:02:28 +00:00
fix(runtime): give the structured-session refusal its own error code
The `agentSession.*` gate refused with a bare `Error` whose message was the magic token, so the RPC envelope flattened it to `runtime_error` and a client could not structurally tell "this host refuses structured chat" from any other runtime fault. The gate now throws the repo's coded-error shape and the code is registered for envelope passthrough; the message is unchanged, so clients that match on the token keep classifying exactly as before.
This commit is contained in:
@@ -109,6 +109,9 @@ const STRUCTURED_RUNTIME_PASSTHROUGH_CODES: ReadonlySet<string> = new Set([
|
||||
'runtime_timeout',
|
||||
'invalid_runtime_response',
|
||||
'capability_unsupported',
|
||||
// The whole `agentSession.*` gate refusal. Coded so a client can route on it without matching
|
||||
// the message; the message is unchanged so older clients still classify.
|
||||
'structured_agent_session_unsupported',
|
||||
'relay_quota_exceeded',
|
||||
'dispatch_capability_invalid',
|
||||
'agent_unconfigured',
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
// for old mobile clients while structured chat is enabled so they receive a fallback row, and that
|
||||
// path constructs the host. `agentSession.*` stays refused either way, which is what this gate is for.
|
||||
|
||||
import { OrchestrationError } from '../../orchestration/orchestration-error'
|
||||
import { getStructuredAgentSessionHost } from '../../../native-chat/agent-session-wire/structured-agent-session-registry'
|
||||
import type { StructuredAgentSessionHost } from '../../../native-chat/agent-session-wire/structured-agent-session-host'
|
||||
import type { StructuredAgentSessionCaller } from '../../../native-chat/agent-session-wire/structured-agent-session-host-types'
|
||||
@@ -17,6 +18,17 @@ import {
|
||||
supportsStructuredAgentSessions
|
||||
} from './structured-agent-session-policy'
|
||||
|
||||
/**
|
||||
* Carries a code so a client can tell "this host refuses structured chat" apart from any other
|
||||
* runtime fault. The message stays the bare token: older clients classify by matching it.
|
||||
*/
|
||||
function structuredSessionsUnsupported(): OrchestrationError {
|
||||
return new OrchestrationError(
|
||||
'structured_agent_session_unsupported',
|
||||
'structured_agent_session_unsupported'
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* In-process callers are the same build as the host, so they carry no negotiated
|
||||
* capability list; every remote client must say it can read structured sessions.
|
||||
@@ -27,7 +39,7 @@ export function supportsStructuredSessions(ctx: RpcContext): boolean {
|
||||
|
||||
export function requireStructuredCapability(ctx: RpcContext): void {
|
||||
if (!supportsStructuredSessions(ctx)) {
|
||||
throw new Error('structured_agent_session_unsupported')
|
||||
throw structuredSessionsUnsupported()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +47,7 @@ export function requireStructuredHost(ctx: RpcContext): StructuredAgentSessionHo
|
||||
requireStructuredCapability(ctx)
|
||||
const host = getStructuredAgentSessionHost()
|
||||
if (!host) {
|
||||
throw new Error('structured_agent_session_unsupported')
|
||||
throw structuredSessionsUnsupported()
|
||||
}
|
||||
return host
|
||||
}
|
||||
@@ -64,11 +76,11 @@ export function requireStructuredHost(ctx: RpcContext): StructuredAgentSessionHo
|
||||
*/
|
||||
export function requireStructuredCleanupHost(ctx: RpcContext): StructuredAgentSessionHost {
|
||||
if (!supportsStructuredAgentSessionCapability(ctx)) {
|
||||
throw new Error('structured_agent_session_unsupported')
|
||||
throw structuredSessionsUnsupported()
|
||||
}
|
||||
const host = getStructuredAgentSessionHost()
|
||||
if (!host) {
|
||||
throw new Error('structured_agent_session_unsupported')
|
||||
throw structuredSessionsUnsupported()
|
||||
}
|
||||
return host
|
||||
}
|
||||
|
||||
@@ -177,6 +177,20 @@ describe('capability gating', () => {
|
||||
expect(hostCalls.send).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('refuses with a code a client can route on, not just a message it must parse', async () => {
|
||||
const response = await call('agentSession.send', sendParams(), {
|
||||
clientKind: 'runtime',
|
||||
clientCapabilities: ['terminal.stream.v1']
|
||||
})
|
||||
expect(response).toMatchObject({
|
||||
ok: false,
|
||||
error: {
|
||||
code: 'structured_agent_session_unsupported',
|
||||
message: 'structured_agent_session_unsupported'
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it('rejects create intent before resolving host-owned fields for an old client', async () => {
|
||||
const worktree = 'id:workspace-1'
|
||||
const response = await call(
|
||||
|
||||
Reference in New Issue
Block a user