mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 17:17:38 +00:00
feat(acp): hosts install a managed runtime over RPC, and mark agents whose program Orca provides (#29024)
* feat(acp): hosts install a managed runtime over RPC, and mark agents whose program Orca provides
managedRuntime.status / managedRuntime.install / managedRuntime.cancel, negotiated by
managed-runtime.install.v1, act on the host that receives them, the one that runs the agent's
chats, with no workspace needed. A status read naming the revision it shows is a long-poll on its
own call-queue lane, so every client sees another's start, progress and outcome.
agentSession.agents marks an agent whose program Orca provides on that host.
* fix(runtime): install status says a copy outside Orca's runs only when a start would really run it
* fix(runtime): install status is pushed to subscribers instead of long-polled, and Cancel answers with the outcome
managedRuntime.subscribe {agent} sends a full snapshot on subscribe, then one
snapshot per install state change, and closes with the transport. It replaces
the managedRuntime.status long-poll and its slot registrations.
This commit is contained in:
@@ -17,7 +17,6 @@ import {
|
||||
} from './managed-runtime-release'
|
||||
import { installFailureText, installRuntimeRelease } from './managed-runtime-release-install'
|
||||
|
||||
const STATUS_WAIT_MS = 25_000
|
||||
const DEADLINE_MS = 45 * 60_000
|
||||
|
||||
export type ManagedRuntimeInstallationDeps = {
|
||||
@@ -46,14 +45,13 @@ export class ManagedRuntimeInstallation {
|
||||
this.mutation = this.reclaim()
|
||||
}
|
||||
|
||||
/** At once without `shown`, else once the revision passes it or after a bounded wait. Disk and
|
||||
* PATH are reread on a first read and when the phase changes, never for byte progress alone. */
|
||||
async status(shown?: number, signal?: AbortSignal): Promise<ManagedRuntimeInstallState> {
|
||||
await this.state.waitForChange(shown, STATUS_WAIT_MS, signal)
|
||||
/** Disk and PATH are reread on a `fresh` read and when the phase changes, never for byte
|
||||
* progress alone. */
|
||||
async status(fresh = true): Promise<ManagedRuntimeInstallState> {
|
||||
const { value: operation, revision } = this.state.get()
|
||||
const phase = `${operation?.id}:${operation?.phase}`
|
||||
let facts = this.facts
|
||||
if (shown === undefined || facts?.phase !== phase) {
|
||||
if (fresh || facts?.phase !== phase) {
|
||||
const read = this.readInstalledFacts()
|
||||
facts = { phase, read }
|
||||
this.facts = facts
|
||||
@@ -65,6 +63,11 @@ export class ManagedRuntimeInstallation {
|
||||
return { agent: this.agent, revision, ...(await facts.read), operation }
|
||||
}
|
||||
|
||||
/** Calls `onChange` after every state revision until the returned unsubscribe. */
|
||||
subscribe(onChange: () => void): () => void {
|
||||
return this.state.subscribe(onChange)
|
||||
}
|
||||
|
||||
private async readInstalledFacts(): Promise<InstalledFacts> {
|
||||
const pin = this.runtime.pin()
|
||||
const { release, broken, unreadable } = resolveInstalledRuntimeRelease(this.root, pin)
|
||||
|
||||
Reference in New Issue
Block a user