@nylorun/runtime 0.1.1-beta → 0.2.0-beta

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.
package/dist/config.js CHANGED
@@ -1,15 +1 @@
1
- export function defineRuntime(config) {
2
- if (!config || !Array.isArray(config.agents))
3
- throw new Error("Runtime config must declare an agents array.");
4
- for (const agent of config.agents) {
5
- if (!agent ||
6
- typeof agent.run !== "function" ||
7
- typeof agent.id !== "string" ||
8
- !agent.manifest)
9
- throw new Error("Every registered agent must satisfy RuntimeAgent.");
10
- }
11
- return Object.freeze({
12
- ...config,
13
- agents: Object.freeze([...config.agents]),
14
- });
15
- }
1
+ export {};
@@ -40,6 +40,10 @@ export interface RuntimeEvent {
40
40
  readonly event?: RuntimeInputEvent;
41
41
  readonly interaction?: unknown;
42
42
  readonly attributes?: unknown;
43
+ readonly tripwire?: {
44
+ readonly code: string;
45
+ readonly message?: string;
46
+ };
43
47
  }
44
48
  export interface RuntimeCompletion {
45
49
  readonly status: "completed" | "waiting" | "rejected" | "cancelled" | "stopped";
@@ -53,9 +57,19 @@ export interface RuntimeSession {
53
57
  readonly completed: Promise<RuntimeCompletion>;
54
58
  };
55
59
  stream(): AsyncIterable<RuntimeEvent>;
56
- observe(listener: (event: RuntimeEvent) => void | Promise<void>): () => void;
57
60
  stop(reason?: string): Promise<void>;
58
61
  }
62
+ export interface RuntimeRunOptions {
63
+ readonly id?: string;
64
+ readonly userId?: string;
65
+ readonly context?: JsonObject;
66
+ readonly onModelCall: RuntimeModelAdapter;
67
+ readonly observer?: {
68
+ (event: {
69
+ readonly type: string;
70
+ }): void | Promise<void>;
71
+ };
72
+ }
59
73
  export interface RuntimeAgent {
60
74
  readonly id: string;
61
75
  readonly name: string;
@@ -63,15 +77,18 @@ export interface RuntimeAgent {
63
77
  readonly id: string;
64
78
  readonly name: string;
65
79
  };
66
- run(options?: {
67
- readonly id?: string;
68
- readonly userId?: string;
69
- readonly context?: JsonObject;
70
- }): RuntimeSession;
80
+ run(options: RuntimeRunOptions): RuntimeSession;
71
81
  close?(): Promise<void>;
72
82
  }
73
- export type PromptContentPart = UserContentPart | {
83
+ export type PromptContentPart = Exclude<UserContentPart, {
84
+ readonly type: "text";
85
+ }> | {
86
+ readonly type: "text" | "reasoning";
87
+ readonly text: string;
88
+ readonly providerMetadata?: JsonObject;
89
+ } | {
74
90
  readonly type: "tool-call";
91
+ readonly providerMetadata?: JsonObject;
75
92
  readonly id: string;
76
93
  readonly name: string;
77
94
  readonly args: JsonObject;
@@ -117,11 +134,13 @@ export interface RuntimeModelCandidate {
117
134
  readonly output: readonly ({
118
135
  readonly type: "text" | "reasoning";
119
136
  readonly text: string;
137
+ readonly providerMetadata?: JsonObject;
120
138
  } | {
121
139
  readonly type: "json";
122
140
  readonly value: JsonValue;
123
141
  } | {
124
142
  readonly type: "tool-call";
143
+ readonly providerMetadata?: JsonObject;
125
144
  readonly id: string;
126
145
  readonly name: string;
127
146
  readonly args: JsonObject;
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- export { defineRuntime } from "./config.js";
2
1
  export type { RuntimeConfig } from "./config.js";
3
2
  export type * from "./contracts.js";
4
- export { createRuntime } from "./server/host.js";
5
- export { piModel } from "./model/pi-model.js";
6
- export type { PiModelOptions } from "./model/pi-model.js";
3
+ export { Runtime, serveAgents, type AgentRouterOptions, type RuntimeActor, type ServeAgentsOptions, } from "./server/host.js";
7
4
  export { localJsonl, memoryHistory, JsonlJournal } from "./adapters/journal.js";
8
- export type { RuntimePersistence, CanonicalEvent, SessionSummary, } from "./adapters/journal.js";
5
+ export type { RuntimeDurability, CanonicalEvent, SessionSummary, } from "./adapters/journal.js";
6
+ export { jsonlObserver } from "./adapters/observe.js";
9
7
  export { localMedia, MediaStore, IMAGE_MEDIA_TYPES, MAX_IMAGE_BYTES, decodeImageBase64, validateImageBytes, } from "./adapters/media.js";
10
8
  export type { RuntimeMedia, MediaAsset, MediaReference, } from "./adapters/media.js";
9
+ export { piModel } from "./model/pi-model.js";
10
+ export type { PiModelOptions } from "./model/pi-model.js";
11
11
  export { projectAsset } from "./assets.js";
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- export { defineRuntime } from "./config.js";
2
- export { createRuntime } from "./server/host.js";
3
- export { piModel } from "./model/pi-model.js";
1
+ export { Runtime, serveAgents, } from "./server/host.js";
4
2
  export { localJsonl, memoryHistory, JsonlJournal } from "./adapters/journal.js";
3
+ export { jsonlObserver } from "./adapters/observe.js";
5
4
  export { localMedia, MediaStore, IMAGE_MEDIA_TYPES, MAX_IMAGE_BYTES, decodeImageBase64, validateImageBytes, } from "./adapters/media.js";
5
+ export { piModel } from "./model/pi-model.js";
6
6
  export { projectAsset } from "./assets.js";
@@ -21,6 +21,31 @@ export function piModel(options = {}) {
21
21
  const selected = registry.getModel(selection.provider, selection.model);
22
22
  if (!selected)
23
23
  throw new Error("Unknown model. Run nylorun configure.");
24
+ const signatureFor = (part) => {
25
+ const metadata = "providerMetadata" in part ? part.providerMetadata?.pi : undefined;
26
+ if (!metadata || typeof metadata !== "object" || Array.isArray(metadata))
27
+ return;
28
+ if (!("provider" in metadata) ||
29
+ metadata.provider !== selected.provider ||
30
+ !("model" in metadata) ||
31
+ metadata.model !== selected.id ||
32
+ !("signature" in metadata) ||
33
+ typeof metadata.signature !== "string")
34
+ return;
35
+ return metadata.signature;
36
+ };
37
+ const metadataFor = (signature, redacted) => signature === undefined
38
+ ? {}
39
+ : {
40
+ providerMetadata: {
41
+ pi: {
42
+ provider: selected.provider,
43
+ model: selected.id,
44
+ signature,
45
+ ...(redacted ? { redacted: true } : {}),
46
+ },
47
+ },
48
+ };
24
49
  const messages = [];
25
50
  const instructions = [];
26
51
  const content = async (parts) => {
@@ -85,11 +110,37 @@ export function piModel(options = {}) {
85
110
  id: part.id,
86
111
  name: part.name,
87
112
  arguments: { ...part.args },
113
+ ...(signatureFor(part) === undefined
114
+ ? {}
115
+ : { thoughtSignature: signatureFor(part) }),
88
116
  },
89
117
  ]
90
118
  : part.type === "text"
91
- ? [{ type: "text", text: part.text }]
92
- : []),
119
+ ? [
120
+ {
121
+ type: "text",
122
+ text: part.text,
123
+ ...(signatureFor(part) === undefined
124
+ ? {}
125
+ : { textSignature: signatureFor(part) }),
126
+ },
127
+ ]
128
+ : part.type === "reasoning" &&
129
+ signatureFor(part) !== undefined
130
+ ? [
131
+ {
132
+ type: "thinking",
133
+ thinking: part.text,
134
+ thinkingSignature: signatureFor(part),
135
+ ...(typeof part.providerMetadata?.pi === "object" &&
136
+ part.providerMetadata.pi !== null &&
137
+ "redacted" in part.providerMetadata.pi &&
138
+ part.providerMetadata.pi.redacted === true
139
+ ? { redacted: true }
140
+ : {}),
141
+ },
142
+ ]
143
+ : []),
93
144
  });
94
145
  }
95
146
  else
@@ -132,15 +183,24 @@ export function piModel(options = {}) {
132
183
  const output = [];
133
184
  for (const part of response.content) {
134
185
  if (part.type === "text")
135
- output.push({ type: "text", text: part.text });
186
+ output.push({
187
+ type: "text",
188
+ text: part.text,
189
+ ...metadataFor(part.textSignature),
190
+ });
136
191
  else if (part.type === "thinking")
137
- output.push({ type: "reasoning", text: part.thinking });
192
+ output.push({
193
+ type: "reasoning",
194
+ text: part.thinking,
195
+ ...metadataFor(part.thinkingSignature, part.redacted),
196
+ });
138
197
  else if (part.type === "toolCall")
139
198
  output.push({
140
199
  type: "tool-call",
141
200
  id: part.id,
142
201
  name: part.name,
143
202
  args: part.arguments,
203
+ ...metadataFor(part.thoughtSignature),
144
204
  });
145
205
  }
146
206
  return {
@@ -40,13 +40,22 @@ export function agUiEvents(events, threadId, runId) {
40
40
  : JSON.stringify(event.payload.output);
41
41
  output.push({ type: "TEXT_MESSAGE_START", messageId, role: "assistant" }, { type: "TEXT_MESSAGE_CONTENT", messageId, delta: text }, { type: "TEXT_MESSAGE_END", messageId });
42
42
  }
43
- else if (event.type === "error") {
43
+ else if (event.type === "error" || event.type === "tripwire") {
44
+ const tripwire = event.payload.tripwire;
45
+ const payload = tripwire && typeof tripwire === "object"
46
+ ? { ...event.payload, ...tripwire }
47
+ : event.payload;
48
+ const attributes = payload.attributes;
49
+ const message = payload.message ??
50
+ (attributes && typeof attributes === "object" && "message" in attributes
51
+ ? attributes.message
52
+ : undefined);
44
53
  output.push({
45
54
  type: "RUN_ERROR",
46
- message: typeof event.payload.message === "string"
47
- ? event.payload.message
48
- : "Agent run failed.",
55
+ message: typeof message === "string" ? message : "Agent run failed.",
56
+ ...(typeof payload.code === "string" ? { code: payload.code } : {}),
49
57
  });
58
+ return Object.freeze(output);
50
59
  }
51
60
  }
52
61
  output.push({ type: "RUN_FINISHED", threadId, runId });
@@ -1,6 +1,8 @@
1
- import type { RuntimeEvent } from "../contracts.js";
2
1
  /** Optional diagnostic enrichment; engines need not emit model diagnostics. */
3
- export declare function observedPayload(event: RuntimeEvent): Record<string, unknown>;
2
+ export declare function observedPayload(event: {
3
+ readonly type: string;
4
+ readonly attributes?: unknown;
5
+ }): Record<string, unknown>;
4
6
  export declare function modelRequestDigests(value: unknown): {
5
7
  prompt: string;
6
8
  tools: string;
@@ -1,14 +1,27 @@
1
- import { Hono } from "hono";
1
+ import { Hono, type Context } from "hono";
2
+ import type { JsonValue, RuntimeAgent } from "../contracts.js";
2
3
  import type { RuntimeConfig } from "../config.js";
3
- export declare function createRuntime(options: RuntimeConfig): Promise<Readonly<{
4
- app: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
5
- hasSession: (agentId: string, sessionId: string) => boolean;
4
+ export type RuntimeActor = Readonly<{
5
+ id: string;
6
+ context?: Record<string, JsonValue>;
7
+ }>;
8
+ export type AgentRouterOptions = Readonly<{
9
+ /** Public URL prefix of this router, matching the Hono mount path. */
10
+ basePath?: string;
11
+ getActor?: (context: Context) => RuntimeActor | undefined | Promise<RuntimeActor | undefined>;
12
+ getRequestMetadata?: (context: Context) => Record<string, JsonValue> | undefined | Promise<Record<string, JsonValue> | undefined>;
13
+ }>;
14
+ export type ServeAgentsOptions = AgentRouterOptions & {
15
+ readonly agents: readonly RuntimeAgent[];
16
+ readonly runtime: Runtime;
17
+ };
18
+ declare const kServe: unique symbol;
19
+ export declare class Runtime {
20
+ #private;
21
+ constructor(options?: RuntimeConfig);
6
22
  close: () => Promise<void>;
7
- }>>;
8
- /** Host headers a loopback bind answers to, on the port actually in use. */
9
- export declare function loopbackHosts(port: number): readonly string[];
10
- /**
11
- * Decide whether a request's Host header is served. Entries are exact
12
- * `host:port` values or bare host names that accept any port; `*` accepts all.
13
- */
14
- export declare function allowedHost(header: string | undefined, allowed: readonly string[]): boolean;
23
+ [kServe](options: Omit<ServeAgentsOptions, "runtime">): Hono;
24
+ }
25
+ /** Create the Hono protocol mount for a runtime. Applications may close it during graceful shutdown. */
26
+ export declare function serveAgents(options: ServeAgentsOptions): any;
27
+ export {};