mirror of
https://github.com/stablyai/orca.git
synced 2026-10-12 08:02:37 +00:00
* refactor(orchestration): spell the Orca session address orca_session_id:<id> The database already names this identity orca_session_id, but agents saw and typed session:<id>, which collides with the Claude/Codex session ID, Session History and terminal sessions. The prefix is now orca_session_id:. No alias, migration or version handshake for the old session: spelling: restructured native chat is experimental. The coordinator-address triggers compile the prefix into their body, and migrate-v42 stamped them once, so an existing database would keep remembering session:<id> for new Runs. They are now recreated on every open, like the mail routing trigger. Provider-id refusals now name the "Orca session ID" instead of "Orca address"/"Orca id". * fix(orchestration): name the Orca session ID the same way in both provider-id refusals The send refusal handed back orca_session_id:<id> as the Orca session ID while the caller refusal called the bare id by that name. Both now say "This session's Orca session ID is orca_session_id:<id>"; the caller refusal also names the bare value ORCA_AGENT_SESSION_ID accepts, since that input takes only the bare id. Tests pin both refusal texts, that session:<id> no longer parses as a session, and that the older-build trigger rewrite actually changes the trigger SQL. * fix(orchestration): keep chats reachable at their session:<id> address after the rename Existing native chats were addressed as session:<id>, so agents and stored mail still use that spelling. Input now accepts session:<id> and treats it as orca_session_id:<id> (the codec parses both; nothing writes the old one), and schema v43 rewrites every stored session:<id> address once: message senders and recipients, remembered Run coordinator addresses, structured pointer operation keys, and coordinator loop handles. Subjects, bodies and payloads are left as written. * fix(orchestration): refuse session:<id> input again; stored addresses still migrate once The old prefix is not accepted as input: no respelling helper, no special case. A session:<id> recipient is refused like any unknown terminal handle (terminal_not_found), including after v43 rewrote a Run's remembered session:<id> coordinator address, so the old spelling no longer routes. Schema v43 still rewrites stored session:<id> addresses once.
56 lines
2.8 KiB
TypeScript
56 lines
2.8 KiB
TypeScript
import { isAgentSessionId } from './agent-session-record'
|
|
import { STRUCTURED_WORKER_HANDLE_PREFIX } from './structured-worker-handle'
|
|
import { ORCA_SESSION_ADDRESS_PREFIX } from './orca-session-address-prefix'
|
|
|
|
/**
|
|
* The Orca session id is the id Orca minted for a structured session (its session record id, the
|
|
* value of `ORCA_AGENT_SESSION_ID`), never the provider's own session id. Orchestration stores,
|
|
* bare, the one the agent is addressed by: for a `/clear`ed chat, its lineage root's, not the live
|
|
* session's. Mail addresses the session as `orca_session_id:<id>`, beside `run:<id>` and `dispatch:<id>`,
|
|
* and derives that spelling here rather than storing it.
|
|
*
|
|
* Where the session runs is not part of the id; it is read from the session record when needed. PTY
|
|
* agents have none today, and never a pane-keyed one: a pane outlives the agent in it, so such an id
|
|
* would be inherited by the pane's next occupant.
|
|
*/
|
|
export { ORCA_SESSION_ADDRESS_PREFIX }
|
|
|
|
declare const orcaSessionIdBrand: unique symbol
|
|
declare const orcaSessionAddressBrand: unique symbol
|
|
|
|
/** A bare Orca session id; only `isOrcaSessionId` and `parseOrcaSessionAddress` produce one. */
|
|
export type OrcaSessionId = string & { readonly [orcaSessionIdBrand]: true }
|
|
/** An `orca_session_id:<id>` mail address; only `formatOrcaSessionAddress` produces one. */
|
|
export type OrcaSessionAddress = string & { readonly [orcaSessionAddressBrand]: true }
|
|
|
|
// Terminal handles (`term_` from the PTY runtime, `structworker_` from structured-worker-identity)
|
|
// share the session-id charset. A handle is never a session, so one handed over by mistake must not
|
|
// become a durable Orca session id.
|
|
const TERMINAL_HANDLE_PREFIXES = ['term_', STRUCTURED_WORKER_HANDLE_PREFIX] as const
|
|
|
|
export function isOrcaSessionId(id: string): id is OrcaSessionId {
|
|
return isAgentSessionId(id) && !TERMINAL_HANDLE_PREFIXES.some((prefix) => id.startsWith(prefix))
|
|
}
|
|
|
|
export function formatOrcaSessionAddress(orcaSessionId: OrcaSessionId): OrcaSessionAddress {
|
|
const address = `${ORCA_SESSION_ADDRESS_PREFIX}${orcaSessionId}`
|
|
// Always true for a checked id; the check brands the address without a type assertion.
|
|
if (!isOrcaSessionAddress(address)) {
|
|
throw new Error(`Not an Orca session id: ${orcaSessionId}`)
|
|
}
|
|
return address
|
|
}
|
|
|
|
/** The bare Orca session id of an `orca_session_id:<id>` address; anything else reads as null. */
|
|
export function parseOrcaSessionAddress(address: string | null | undefined): OrcaSessionId | null {
|
|
if (!address?.startsWith(ORCA_SESSION_ADDRESS_PREFIX)) {
|
|
return null
|
|
}
|
|
const id = address.slice(ORCA_SESSION_ADDRESS_PREFIX.length)
|
|
return isOrcaSessionId(id) ? id : null
|
|
}
|
|
|
|
function isOrcaSessionAddress(address: string): address is OrcaSessionAddress {
|
|
return parseOrcaSessionAddress(address) !== null
|
|
}
|