@rynx-ai/server 0.1.11-beta.20 → 0.1.11-beta.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import Router from "@koa/router";
2
- import { type ConversationRuntime, type MachineSessionRecord, type ResolvedExecutionSnapshot, type SessionWorkspaceSnapshot, type SessionBus, type SessionLogStore, type SkillInstallRecipe } from "@rynx-ai/core";
2
+ import { type ConversationRuntime, type InjectOutcome, type MachineSessionRecord, type ResolvedExecutionSnapshot, type SessionWorkspaceSnapshot, type SessionBus, type SessionLogStore, type SkillInstallRecipe } from "@rynx-ai/core";
3
3
  import type { ControlAgentSummary, ControlAgentRuntimeOption, ControlLocalSkillCandidate, ControlLocalSkillImportResult, SkillSummary, SkillDetail, ProviderCliId } from "@rynx-ai/protocol/control";
4
4
  import type { SessionInteractionResolution } from "@rynx-ai/protocol";
5
5
  import { type RemoteRuntimeRpcParams, type RemoteRuntimeRpcResultFor } from "@rynx-ai/protocol/remote-runtime-rpc";
@@ -9,7 +9,7 @@ import { type DaemonRuntimeHost } from "./remote-runtime.js";
9
9
  import { SessionRuntimeIndex } from "./session-runtime-index.js";
10
10
  import type { SessionEmulatorService } from "./session-emulator-service.js";
11
11
  import { type RuntimeWebAccessPolicy } from "./runtime-web-auth.js";
12
- import type { MachineSessionService } from "./machine-session-service.js";
12
+ import { type MachineSessionService } from "./machine-session-service.js";
13
13
  export interface ControlEmulatorDeps {
14
14
  doctor(): Promise<unknown>;
15
15
  devices(): Promise<unknown[]>;
@@ -188,7 +188,12 @@ export declare function createControlRouter(opts: {
188
188
  execution: ResolvedExecutionSnapshot;
189
189
  }): Promise<boolean>;
190
190
  lastLiveSessionError?(localThreadId: string): string | undefined;
191
- injectMessage?(localThreadId: string, text: string): Promise<"injected" | "notLive" | "notReady" | "failed">;
191
+ lastLiveSessionFailure?(localThreadId: string): {
192
+ message: string;
193
+ code: string;
194
+ statusCode: number;
195
+ } | undefined;
196
+ injectMessage?(localThreadId: string, text: string): Promise<InjectOutcome>;
192
197
  resolveInteraction?(localThreadId: string, interactionId: string, resolution: SessionInteractionResolution): Promise<{
193
198
  disposition: "applied" | "already_resolved" | "not_found" | "invalid";
194
199
  }>;
@@ -19,6 +19,7 @@ import { parseRuntimeBrowserStateGetParams } from "@rynx-ai/protocol/runtime-bro
19
19
  import { encodeDaemonStatus } from "./remote-runtime.js";
20
20
  import { SessionRuntimeIndex } from "./session-runtime-index.js";
21
21
  import { authorizeRuntimeWebRequest, RUNTIME_WEB_CAPABILITY, RUNTIME_WEB_CAPABILITY_HEADER, } from "./runtime-web-auth.js";
22
+ import { MachineSessionServiceFailure, } from "./machine-session-service.js";
22
23
  const PLUGIN_CLI_BODY_MAX_BYTES = 512 * 1024;
23
24
  const PLUGIN_CLI_STDIN_MAX_BYTES = 256 * 1024;
24
25
  const PLUGIN_CLI_ARG_MAX_BYTES = 4 * 1024;
@@ -3252,7 +3253,20 @@ export function createControlRouter(opts) {
3252
3253
  }
3253
3254
  catch (error) {
3254
3255
  ctx.status = 503;
3255
- ctx.body = { error: error instanceof Error ? error.message : String(error) };
3256
+ const runtimeFailure = error instanceof MachineSessionServiceFailure
3257
+ ? error.runtimeFailure
3258
+ : undefined;
3259
+ const message = runtimeFailure?.message
3260
+ ?? (error instanceof MachineSessionServiceFailure ? error.detail : undefined)
3261
+ ?? (error instanceof Error ? error.message : String(error));
3262
+ ctx.body = {
3263
+ error: message,
3264
+ code: runtimeFailure?.code
3265
+ ?? (error instanceof MachineSessionServiceFailure ? error.code : "runtime_error"),
3266
+ outcome: error instanceof MachineSessionServiceFailure && error.code === "outcome_unknown"
3267
+ ? "unknown"
3268
+ : "not_started",
3269
+ };
3256
3270
  }
3257
3271
  return;
3258
3272
  }
@@ -3271,26 +3285,30 @@ export function createControlRouter(opts) {
3271
3285
  execution: structuredClone(meta.execution),
3272
3286
  });
3273
3287
  if (!live) {
3288
+ const failure = runnerManager.lastLiveSessionFailure?.(id);
3274
3289
  ctx.status = 503;
3275
3290
  ctx.body = {
3276
- error: `live session unavailable (${meta.execution.provider})`,
3277
- ...(runnerManager.lastLiveSessionError?.(id)
3278
- ? { detail: runnerManager.lastLiveSessionError(id) }
3279
- : {}),
3291
+ error: failure?.message
3292
+ ?? runnerManager.lastLiveSessionError?.(id)
3293
+ ?? `live session unavailable (${meta.execution.provider})`,
3294
+ code: failure?.code ?? "live_unavailable",
3295
+ outcome: "not_started",
3280
3296
  };
3281
3297
  return;
3282
3298
  }
3283
3299
  const outcome = await runnerManager.injectMessage(id, message);
3284
- if (outcome === "injected") {
3300
+ if (outcome === "injected" || outcome === "steered") {
3285
3301
  ctx.body = { ok: true, injected: true };
3286
3302
  return;
3287
3303
  }
3288
3304
  ctx.status = 503;
3305
+ const failure = runnerManager.lastLiveSessionFailure?.(id);
3289
3306
  ctx.body = {
3290
- error: `live injection ${outcome}`,
3291
- ...(runnerManager.lastLiveSessionError?.(id)
3292
- ? { detail: runnerManager.lastLiveSessionError(id) }
3293
- : {}),
3307
+ error: failure?.message
3308
+ ?? runnerManager.lastLiveSessionError?.(id)
3309
+ ?? `live injection ${outcome}`,
3310
+ code: failure?.code ?? "live_inject_failed",
3311
+ outcome: outcome === "failed" ? "unknown" : "not_started",
3294
3312
  };
3295
3313
  });
3296
3314
  // Stop the session's active turn (the web Stop button). For a live native
@@ -3576,6 +3594,14 @@ function optionalRuntimeDevice(body) {
3576
3594
  return body.device === undefined ? {} : { device: body.device };
3577
3595
  }
3578
3596
  function remoteRuntimeRpcTimeoutMs(method, params) {
3597
+ // Native startup/delivery owns phase-specific deadlines and returns their
3598
+ // concrete failures. A BFF deadline here would race those phases and replace
3599
+ // the real error with an ambiguous generic RPC timeout. The setup queue also
3600
+ // awaits Terminal startup before acknowledging the request.
3601
+ if (method === "session.message.send" ||
3602
+ method === "session.message.enqueue" ||
3603
+ method === "session.terminal.start")
3604
+ return null;
3579
3605
  if (method === "session.emulator.attach")
3580
3606
  return REMOTE_RUNTIME_EMULATOR_ATTACH_TIMEOUT_MS;
3581
3607
  if (method === "session.emulator.type") {
@@ -3899,8 +3925,14 @@ function runtimeTargetHostError(ctx, error, forcedOutcome) {
3899
3925
  const status = runtimeTargetHttpStatus(code);
3900
3926
  ctx.status = status;
3901
3927
  const outcome = forcedOutcome ?? runtimeTargetErrorOutcome(error);
3928
+ const applicationMessage = error instanceof Error && error.name === "DirectRuntimeRpcError"
3929
+ ? error.message.replace(/^Remote Runtime RPC failed: [^:]+: /, "")
3930
+ : undefined;
3902
3931
  ctx.body = {
3903
- error: status === 500 ? "internal_error" : code,
3932
+ error: applicationMessage ?? (status === 500 ? "internal_error" : code),
3933
+ ...(applicationMessage
3934
+ ? { code: status === 500 ? "internal_error" : code }
3935
+ : {}),
3904
3936
  ...(outcome === undefined ? {} : { outcome }),
3905
3937
  };
3906
3938
  }
@@ -1 +1 @@
1
- import{R as x,L as d,A as f}from"./mermaid-GHXKKRXX-5TjLyIbA.js";import{r,j as p}from"./index-BKgzgxRn.js";var R=({code:i,language:e,raw:a,className:u,startLine:m,lineNumbers:n,...g})=>{let{shikiTheme:l}=r.useContext(x),s=d(),[h,t]=r.useState(a);return r.useEffect(()=>{if(!s){t(a);return}let o=s.highlight({code:i,language:e,themes:l},c=>{t(c)});o&&t(o)},[i,e,l,s,a]),p.jsx(f,{className:u,language:e,lineNumbers:n,result:h,startLine:m,...g})};export{R as HighlightedCodeBlockBody};
1
+ import{R as x,L as d,A as f}from"./mermaid-GHXKKRXX-CJPtDfFU.js";import{r,j as p}from"./index-BQFR9W8k.js";var R=({code:i,language:e,raw:a,className:u,startLine:m,lineNumbers:n,...g})=>{let{shikiTheme:l}=r.useContext(x),s=d(),[h,t]=r.useState(a);return r.useEffect(()=>{if(!s){t(a);return}let o=s.highlight({code:i,language:e,themes:l},c=>{t(c)});o&&t(o)},[i,e,l,s,a]),p.jsx(f,{className:u,language:e,lineNumbers:n,result:h,startLine:m,...g})};export{R as HighlightedCodeBlockBody};