refactor(schedule): make absolute times explicit
This commit is contained in:
@@ -34,6 +34,8 @@ Session titles ride the generic projection pair like every other domain — the
|
||||
|
||||
Session model selection is a session-domain contract. `session.models` returns the current `ModelSelection` separately from provider-grouped advisory models, exact-model reasoning metadata, and provider-local lookup failures. The selection may be absent from the groups and is never injected as a synthetic row; clients can prompt for another selection without turning the directory into a routing whitelist. `session.selectModel` validates the optional adapter-owned reasoning effort and assigns the complete selection for the next prompt-assembly boundary. Catalog membership is not validation: an adapter may resolve an unlisted model, while an unavailable provider or unsupported effort returns `model-unavailable`. `session.models` additionally reports `routable`: whether an adapter currently serves the selected provider. This is deliberately not derivable from the groups because an adapter may serve an unadvertised model. `session.prompt` refuses on the same fact with `model-unavailable` before opening a turn; a disabled composer is a client affordance, and the method remains callable.
|
||||
|
||||
`session.prompt` also accepts optional request-local `clientTimeZone` provenance. When present, the Host validates and canonicalizes `UTC` or an IANA Area/Location before Agent entry, rejects invalid input with `invalid-time-zone`, and records the canonical value on that exact `user-rpc` message beside its `rpcId`. The value is not Session, connection, create, resume, or fork state; non-browser callers may omit it.
|
||||
|
||||
Pending queued input is a live control-plane contract, not conversation history. The gateway derives the complete `next-turn` queue from durable `agent/inbox/spliced` mutations and broadcasts authoritative `session/queue` snapshots after each change and on reconnect; pending `next-step` steering stays outside this Web projection. Within `next-step`, user-origin messages carry the `steering` placement while injected context (approval notices, task completion, attached snapshots) carries `context` and is not surfaced until claimed. The message-local `agent/inbox/inserted`, `claimed`, and `discarded` notifications remain available to lifecycle observers but do not build the queue view. `session.updateQueue` addresses one `MessageId`; edit and remove mutate the attached Agent through `Inbox.splice()`. A claim's pure deletion splice wins races before pre-step admission, so a later operation returns `queue-item-not-found`. `session.cancel` aborts only the active turn and preserves pending inbox work; after cancellation reaches quiescence and the closing turn flushes, AgentLoop claims the next waking message in FIFO order, and the browser never resends or promotes it. Queue operations never resume a cold session, and the client never infers retirement from turn or status events.
|
||||
|
||||
Workspace and Session lists are separate reconnect baselines. `workspace.create({ name })` creates a uniquely titled directory under the configured root, while `workspace.create({ path })` adopts an existing canonical directory and permits basename-derived titles to repeat. `workspace.delete` removes only the Workspace registration, `session.create` accepts an optional preallocated Session id, and `host/workspace-changed`, `host/workspace-removed`, plus `host/session-added` carry committed increments in either arrival order. `workspace.archiveSession` adds one session to the registry-global archive set and answers the full updated set; `workspace.list` carries that set as the reconnect baseline and `host/archived-sessions-changed` pushes the full snapshot after every durable change. Archiving hides the session from grouping surfaces without touching its log or its workspace account; a session neither live nor persisted fails with `session-not-found`. Registration deletion preserves the directory and session logs; its Sessions remain in `session.list` and become Ungrouped. `SessionSummary.blank` and the `host/session-added` frame carry the derived zero-events bit: clients hide blank sessions and reuse them per workspace, flip blank on the first `host/session-status(running:true)`, and treat `session.list` as the reconnect authority; cold summaries are never blank because lazy persistence keeps never-appended sessions out of `list()`.
|
||||
|
||||
Reference in New Issue
Block a user