@nylorun/runtime 0.22.0-beta → 0.24.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.
Files changed (273) hide show
  1. package/CHANGELOG.md +161 -0
  2. package/README.md +95 -30
  3. package/dist/adapters/execution/restate.d.ts +15 -3
  4. package/dist/adapters/execution/restate.js +78 -84
  5. package/dist/adapters/replication/pgoutput.d.ts +2 -0
  6. package/dist/adapters/replication/pgoutput.js +6 -3
  7. package/dist/adapters/sandbox/local.d.ts +9 -1
  8. package/dist/adapters/sandbox/local.js +16 -4
  9. package/dist/adapters/sandbox/virtual.js +4 -1
  10. package/dist/adapters/streams/s2.js +1 -13
  11. package/dist/api/a2a/endpoint.js +5 -1
  12. package/dist/api/a2a/routes.d.ts +2 -0
  13. package/dist/api/a2a/routes.js +2 -2
  14. package/dist/api/a2a/tasks.js +2 -1
  15. package/dist/api/ag-ui/endpoint.js +4 -2
  16. package/dist/api/ag-ui/history.js +4 -1
  17. package/dist/api/ag-ui/routes.d.ts +4 -1
  18. package/dist/api/ag-ui/routes.js +11 -10
  19. package/dist/api/ag-ui/translate.js +3 -2
  20. package/dist/api/components.d.ts +4953 -1204
  21. package/dist/api/components.js +25 -16
  22. package/dist/api/gate/keys.js +7 -1
  23. package/dist/api/gate/routes.d.ts +6 -0
  24. package/dist/api/gate/routes.js +39 -3
  25. package/dist/api/http/app.js +4 -4
  26. package/dist/api/http/define.d.ts +6 -0
  27. package/dist/api/http/define.js +13 -1
  28. package/dist/api/http/respond.js +1 -1
  29. package/dist/api/http/routes/artifacts.js +35 -8
  30. package/dist/api/http/routes/coverage.d.ts +9 -0
  31. package/dist/api/http/routes/coverage.js +34 -0
  32. package/dist/api/http/routes/environments.d.ts +11 -0
  33. package/dist/api/http/routes/environments.js +283 -0
  34. package/dist/api/http/routes/mcp.d.ts +1 -1
  35. package/dist/api/http/routes/mcp.js +2 -2
  36. package/dist/api/http/routes/me.js +1 -1
  37. package/dist/api/http/routes/reads.d.ts +45 -9
  38. package/dist/api/http/routes/reads.js +54 -5
  39. package/dist/api/http/routes/sessions.js +11 -6
  40. package/dist/api/http/routes/tenant.js +32 -10
  41. package/dist/api/openapi.js +31 -26
  42. package/dist/artifacts/disk.d.ts +59 -0
  43. package/dist/artifacts/disk.js +563 -0
  44. package/dist/artifacts/export.d.ts +1 -1
  45. package/dist/artifacts/export.js +2 -3
  46. package/dist/artifacts/folders.d.ts +6 -3
  47. package/dist/artifacts/folders.js +17 -12
  48. package/dist/artifacts/service.d.ts +2 -1
  49. package/dist/artifacts/service.js +6 -1
  50. package/dist/artifacts/workspace.d.ts +1 -1
  51. package/dist/artifacts/workspace.js +1 -1
  52. package/dist/core/flow-host.d.ts +3 -22
  53. package/dist/core/flow-host.js +11 -37
  54. package/dist/core/provider.d.ts +3 -2
  55. package/dist/core/provider.js +5 -37
  56. package/dist/core/sandbox-routes.d.ts +2 -21
  57. package/dist/core/sandbox-routes.js +10 -43
  58. package/dist/execution/types.d.ts +11 -9
  59. package/dist/execution/types.js +5 -7
  60. package/dist/gates/contract.d.ts +3 -24
  61. package/dist/gates/contract.js +1 -36
  62. package/dist/gates/egress-credentials.d.ts +9 -0
  63. package/dist/gates/egress-credentials.js +11 -4
  64. package/dist/gates/egress.d.ts +28 -1
  65. package/dist/gates/egress.js +115 -10
  66. package/dist/gates/fixture-model.d.ts +28 -0
  67. package/dist/gates/fixture-model.js +92 -0
  68. package/dist/gates/handler.js +4 -4
  69. package/dist/gates/http-tool.d.ts +6 -2
  70. package/dist/gates/http-tool.js +3 -5
  71. package/dist/gates/in-process.d.ts +5 -0
  72. package/dist/gates/in-process.js +12 -1
  73. package/dist/gates/journal.d.ts +30 -0
  74. package/dist/gates/journal.js +52 -0
  75. package/dist/gates/mcp-handler.d.ts +4 -0
  76. package/dist/gates/mcp-handler.js +5 -1
  77. package/dist/gates/meter.d.ts +10 -2
  78. package/dist/gates/meter.js +20 -5
  79. package/dist/gates/policy.d.ts +49 -0
  80. package/dist/gates/policy.js +134 -0
  81. package/dist/gates/tenant-vaults.d.ts +7 -7
  82. package/dist/gates/tenant-vaults.js +5 -5
  83. package/dist/gates/tool-calls.d.ts +10 -5
  84. package/dist/gates/tool-calls.js +28 -10
  85. package/dist/gates/tool-client.d.ts +8 -0
  86. package/dist/gates/tool-client.js +27 -11
  87. package/dist/gates/tool-contract.d.ts +10 -68
  88. package/dist/gates/tool-contract.js +1 -85
  89. package/dist/gates/tool-gate.d.ts +1 -1
  90. package/dist/harness/calls.d.ts +12 -5
  91. package/dist/harness/calls.js +21 -12
  92. package/dist/harness/executors.js +12 -9
  93. package/dist/harness/main.js +18 -5
  94. package/dist/harness/pod.d.ts +34 -0
  95. package/dist/harness/pod.js +41 -0
  96. package/dist/harness/service.d.ts +0 -1
  97. package/dist/harness/service.js +13 -5
  98. package/dist/harness/setup.d.ts +27 -0
  99. package/dist/harness/setup.js +150 -0
  100. package/dist/harness/ws-client.js +3 -2
  101. package/dist/harness/ws-port.d.ts +1 -5
  102. package/dist/harness/ws-port.js +1 -5
  103. package/dist/harness-api/in-process.js +3 -3
  104. package/dist/harness-api/record.d.ts +15 -1
  105. package/dist/harness-api/record.js +174 -44
  106. package/dist/harness-api/redact.d.ts +3 -0
  107. package/dist/harness-api/redact.js +45 -0
  108. package/dist/harness-api/server.d.ts +8 -0
  109. package/dist/harness-api/server.js +93 -13
  110. package/dist/harness-api/start.d.ts +10 -3
  111. package/dist/harness-api/start.js +40 -10
  112. package/dist/harness-api/tool-journal.d.ts +96 -0
  113. package/dist/harness-api/tool-journal.js +102 -0
  114. package/dist/harness-api/tool-status.d.ts +13 -0
  115. package/dist/harness-api/tool-status.js +26 -0
  116. package/dist/harness-api/workspace.d.ts +6 -3
  117. package/dist/harness-api/workspace.js +27 -11
  118. package/dist/harness-api/ws-server.d.ts +11 -3
  119. package/dist/harness-api/ws-server.js +94 -15
  120. package/dist/host/execution.d.ts +8 -6
  121. package/dist/host/gates.d.ts +2 -1
  122. package/dist/host/gates.js +10 -2
  123. package/dist/host/main.js +64 -21
  124. package/dist/host/operate.js +67 -5
  125. package/dist/host/stack-config.d.ts +70 -0
  126. package/dist/host/stack-config.js +67 -1
  127. package/dist/infra/execution.d.ts +18 -1
  128. package/dist/infra/execution.js +28 -4
  129. package/dist/infra/index.d.ts +1 -1
  130. package/dist/keys/client.js +4 -1
  131. package/dist/keys/keys.d.ts +5 -5
  132. package/dist/keys/keys.js +5 -7
  133. package/dist/management-openapi.json +999 -2211
  134. package/dist/mcp/connect.d.ts +25 -20
  135. package/dist/mcp/connect.js +29 -30
  136. package/dist/mcp/pool.d.ts +2 -2
  137. package/dist/mcp/pool.js +1 -1
  138. package/dist/mcp/preview.d.ts +3 -3
  139. package/dist/mcp/preview.js +10 -20
  140. package/dist/mcp/snapshot.d.ts +5 -11
  141. package/dist/mcp/snapshot.js +6 -7
  142. package/dist/model/pi-model.js +8 -0
  143. package/dist/openapi.json +6955 -2526
  144. package/dist/reads/types.d.ts +16 -3
  145. package/dist/record/append.d.ts +3 -1
  146. package/dist/record/append.js +1 -0
  147. package/dist/record/envelope.d.ts +5 -1
  148. package/dist/record/envelope.js +7 -3
  149. package/dist/record/environment.d.ts +25 -0
  150. package/dist/record/environment.js +44 -0
  151. package/dist/record/index.d.ts +1 -1
  152. package/dist/record/index.js +1 -1
  153. package/dist/retry.d.ts +21 -0
  154. package/dist/retry.js +34 -0
  155. package/dist/sandbox/disk-fs.d.ts +95 -0
  156. package/dist/sandbox/disk-fs.js +206 -0
  157. package/dist/sandbox/join.d.ts +17 -18
  158. package/dist/sandbox/join.js +46 -20
  159. package/dist/sandbox/manager.d.ts +16 -8
  160. package/dist/sandbox/manager.js +33 -17
  161. package/dist/sandbox/placement.d.ts +13 -12
  162. package/dist/sandbox/placement.js +29 -12
  163. package/dist/sandbox/pods/client.d.ts +6 -1
  164. package/dist/sandbox/pods/lifecycle.d.ts +28 -27
  165. package/dist/sandbox/pods/lifecycle.js +14 -26
  166. package/dist/sandbox/pods/reconcile.js +21 -15
  167. package/dist/sandbox/pods/spec.d.ts +15 -13
  168. package/dist/sandbox/pods/spec.js +16 -20
  169. package/dist/sandbox/records.d.ts +2 -2
  170. package/dist/sandbox/records.js +3 -3
  171. package/dist/sandbox/resolve.d.ts +35 -27
  172. package/dist/sandbox/resolve.js +66 -41
  173. package/dist/sandbox/session-sandbox.js +1 -1
  174. package/dist/sandbox/setup.d.ts +61 -0
  175. package/dist/sandbox/setup.js +123 -0
  176. package/dist/sandbox/share.d.ts +11 -21
  177. package/dist/sandbox/share.js +12 -41
  178. package/dist/sandbox/tenant-config.d.ts +12 -14
  179. package/dist/sandbox/tenant-config.js +12 -17
  180. package/dist/sandbox/types.d.ts +6 -0
  181. package/dist/store/postgres/control.js +8 -1
  182. package/dist/store/postgres/drizzle/0018_wake_outbox_retries.sql +3 -0
  183. package/dist/store/postgres/drizzle/0019_sandbox_signal_outbox.sql +18 -0
  184. package/dist/store/postgres/drizzle/0020_environments.sql +63 -0
  185. package/dist/store/postgres/drizzle/0021_disk_versions.sql +7 -0
  186. package/dist/store/postgres/drizzle/0022_model_usage_timing.sql +5 -0
  187. package/dist/store/postgres/drizzle/0023_artifact_pages.sql +1 -0
  188. package/dist/store/postgres/drizzle/meta/_journal.json +42 -0
  189. package/dist/store/postgres/reads.js +117 -17
  190. package/dist/store/postgres/record-writer.d.ts +4 -4
  191. package/dist/store/postgres/record-writer.js +9 -9
  192. package/dist/store/postgres/record.d.ts +7 -0
  193. package/dist/store/postgres/record.js +23 -2
  194. package/dist/store/postgres/schema.d.ts +1213 -779
  195. package/dist/store/postgres/schema.js +136 -76
  196. package/dist/store/postgres/store.js +283 -117
  197. package/dist/store/types.d.ts +206 -88
  198. package/dist/streams/relay/core.js +1 -13
  199. package/dist/tenant/advance.d.ts +7 -6
  200. package/dist/tenant/advance.js +121 -49
  201. package/dist/tenant/artifact-tool.js +3 -4
  202. package/dist/tenant/commands.d.ts +15 -2
  203. package/dist/tenant/commands.js +94 -14
  204. package/dist/tenant/context.d.ts +67 -33
  205. package/dist/tenant/context.js +4 -15
  206. package/dist/tenant/control.d.ts +8 -1
  207. package/dist/tenant/control.js +2 -0
  208. package/dist/tenant/effects.d.ts +1 -1
  209. package/dist/tenant/effects.js +37 -20
  210. package/dist/tenant/environments.d.ts +167 -0
  211. package/dist/tenant/environments.js +823 -0
  212. package/dist/tenant/harness-tokens.d.ts +21 -0
  213. package/dist/tenant/harness-tokens.js +61 -0
  214. package/dist/tenant/host-token.d.ts +1 -1
  215. package/dist/tenant/host-token.js +2 -4
  216. package/dist/tenant/identity-file.d.ts +4 -4
  217. package/dist/tenant/identity-file.js +17 -8
  218. package/dist/tenant/issuers.js +3 -3
  219. package/dist/tenant/principals.js +1 -1
  220. package/dist/tenant/reset.js +3 -3
  221. package/dist/tenant/runtime.d.ts +6 -1
  222. package/dist/tenant/runtime.js +30 -4
  223. package/dist/tenant/scheduler.d.ts +7 -0
  224. package/dist/tenant/scheduler.js +38 -7
  225. package/dist/tenant/session-streams.d.ts +0 -1
  226. package/dist/tenant/session-streams.js +1 -13
  227. package/dist/tenant/session.d.ts +3 -3
  228. package/dist/tenant/session.js +0 -14
  229. package/dist/tenant/sessions.d.ts +13 -13
  230. package/dist/tenant/sessions.js +61 -138
  231. package/dist/tenant/signing-keys.d.ts +5 -1
  232. package/dist/tenant/status.js +3 -3
  233. package/dist/tenant/streams.js +14 -29
  234. package/dist/tenant/sweep.d.ts +39 -12
  235. package/dist/tenant/sweep.js +168 -63
  236. package/dist/tenant/transcript.d.ts +210 -20
  237. package/dist/tenant/transcript.js +62 -11
  238. package/dist/tenant/turn-timing.d.ts +43 -0
  239. package/dist/tenant/turn-timing.js +39 -0
  240. package/dist/tenant/types.d.ts +2 -0
  241. package/dist/traces/ids.d.ts +42 -0
  242. package/dist/traces/ids.js +85 -0
  243. package/dist/traces/key.d.ts +6 -0
  244. package/dist/traces/key.js +37 -0
  245. package/dist/traces/map.d.ts +113 -0
  246. package/dist/traces/map.js +317 -0
  247. package/dist/traces/options.d.ts +7 -0
  248. package/dist/traces/options.js +1 -0
  249. package/dist/traces/otlp.d.ts +42 -0
  250. package/dist/traces/otlp.js +84 -0
  251. package/dist/traces/projector.d.ts +58 -0
  252. package/dist/traces/projector.js +200 -0
  253. package/dist/traces/read.d.ts +23 -0
  254. package/dist/traces/read.js +16 -0
  255. package/dist/vault/coverage.d.ts +26 -0
  256. package/dist/vault/coverage.js +64 -0
  257. package/dist/vault/error.d.ts +11 -1
  258. package/dist/vault/error.js +5 -1
  259. package/dist/vault/service.d.ts +47 -48
  260. package/dist/vault/service.js +321 -382
  261. package/dist/vault/sources.d.ts +5 -16
  262. package/dist/vault/sources.js +6 -8
  263. package/dist/version.d.ts +1 -1
  264. package/dist/version.js +2 -2
  265. package/package.json +14 -13
  266. package/dist/api/http/routes/sandboxes.d.ts +0 -9
  267. package/dist/api/http/routes/sandboxes.js +0 -153
  268. package/dist/api/http/routes/vaults.d.ts +0 -10
  269. package/dist/api/http/routes/vaults.js +0 -139
  270. package/dist/record/sandbox.d.ts +0 -25
  271. package/dist/record/sandbox.js +0 -43
  272. package/dist/tenant/sandboxes.d.ts +0 -122
  273. package/dist/tenant/sandboxes.js +0 -562
@@ -4,6 +4,9 @@
4
4
  * Payload schemas: `@nylorun/core/contracts` (`parseTranscriptEvent`).
5
5
  */
6
6
  import type { HostEffect } from "@nylorun/harness/run";
7
+ import type { TOOL_CALL_KINDS, TOOL_CALL_STATUSES } from "@nylorun/core/contracts";
8
+ export type ToolCallStatus = (typeof TOOL_CALL_STATUSES)[number];
9
+ export type ToolCallKind = (typeof TOOL_CALL_KINDS)[number];
7
10
  /** The model's tool call id and the harness invocation, for tool effects. */
8
11
  export declare function toolIds(context: unknown): {
9
12
  callId: string;
@@ -11,7 +14,9 @@ export declare function toolIds(context: unknown): {
11
14
  } | Record<string, never>;
12
15
  /**
13
16
  * `message.assistant` for a completed model effect: the step's text and tool calls. The
14
- * provider returns a `ModelCandidate` or a bare string; anything else writes no event.
17
+ * provider returns a `ModelCandidate` or a bare string. A step that said nothing (no text, no
18
+ * tool calls; a structured answer) is still one event, with `text: ""` (R7.1): every model call
19
+ * has its outcome row. Readers that build a conversation skip it (`isEmptyAssistantMessage`).
15
20
  */
16
21
  export declare function assistantMessage(request: HostEffect, value: unknown): {
17
22
  agent: import("@nylorun/core/define").AgentRef;
@@ -46,7 +51,8 @@ export declare function assistantMessage(request: HostEffect, value: unknown): {
46
51
  } | undefined;
47
52
  /**
48
53
  * `context.compacted` for a model effect that summarized history (Model Calls §8): the
49
- * engine replaced the older transcript with that summary.
54
+ * engine replaced the older transcript with that summary. A partial summary (one call of
55
+ * several) is marked `partial: true` (R7.1): only the last call's event replaced the history.
50
56
  */
51
57
  export declare function contextCompacted(request: HostEffect, value: unknown): {
52
58
  agent: import("@nylorun/core/define").AgentRef;
@@ -54,12 +60,14 @@ export declare function contextCompacted(request: HostEffect, value: unknown): {
54
60
  trigger: "overflow" | "threshold";
55
61
  tokensBefore: number;
56
62
  tokensAfter: number;
63
+ partial?: true | undefined;
57
64
  } | {
58
65
  agent?: undefined;
59
66
  invocationId?: string | undefined;
60
67
  trigger: "overflow" | "threshold";
61
68
  tokensBefore: number;
62
69
  tokensAfter: number;
70
+ partial?: true | undefined;
63
71
  } | undefined;
64
72
  /** `model.failed` for a model effect that completed with a failure outcome (Model Calls §6.4). */
65
73
  export declare function modelFailed(request: HostEffect, value: unknown): {
@@ -75,59 +83,149 @@ export declare function modelFailed(request: HostEffect, value: unknown): {
75
83
  message: string;
76
84
  retryable: boolean;
77
85
  } | undefined;
78
- /** `tool.completed` for a tool the Runtime ran: its output, or the tool error it reported. */
79
- export declare function toolCompleted(request: HostEffect, value: unknown): {
86
+ /** A gate's own start and end of a call (R7.1). */
87
+ export interface GateTimes {
88
+ readonly startedAt: string;
89
+ readonly endedAt: string;
90
+ }
91
+ /** What the usage ledger holds for a model call (R7.1): its `model_usage` row's columns. */
92
+ export interface MeteredCall {
93
+ readonly startedAt: string | null;
94
+ readonly endedAt: string | null;
95
+ readonly firstTokenMs: number | null;
96
+ readonly inputTokens: number;
97
+ readonly outputTokens: number;
98
+ readonly totalTokens: number;
99
+ readonly cachedTokens: number;
100
+ readonly costUsd: number;
101
+ }
102
+ /** From `startedAt` to `endedAt` in whole milliseconds; undefined unless both are times. */
103
+ export declare function durationBetween(startedAt: string | undefined, endedAt: string | undefined): number | undefined;
104
+ /**
105
+ * The timing a model call's outcome event carries (R7.1): its effect id, the journal's window
106
+ * (`startedAt` on the row to `settledAt`), and, when the gate metered the call (`metered`), the
107
+ * gate's own start and end, the first token's time and the metered usage.
108
+ */
109
+ export declare function modelOutcomeFacts(effectId: string, window: {
110
+ startedAt?: string;
111
+ settledAt?: string;
112
+ }, metered: MeteredCall | undefined): {
113
+ effectId: string;
114
+ durationMs?: number | undefined;
115
+ gate?: {
116
+ startedAt: string;
117
+ endedAt: string;
118
+ } | undefined;
119
+ firstTokenMs?: number | undefined;
120
+ meteredUsage?: {
121
+ inputTokens: number;
122
+ outputTokens: number;
123
+ totalTokens: number;
124
+ cachedTokens?: number | undefined;
125
+ costUsd?: number | undefined;
126
+ } | undefined;
127
+ };
128
+ /** What the Tenant's tool policy did with a call, when it did more than allow it (R7.1). */
129
+ export interface ToolPolicyFact {
130
+ readonly decision: "ask" | "deny";
131
+ readonly reason: string;
132
+ readonly approvedBy?: string;
133
+ }
134
+ /** What the journal knows of a tool call when it ends (R5.1, R7.1), for its `tool.completed`. */
135
+ export interface ToolCallFacts {
136
+ readonly status: ToolCallStatus;
137
+ readonly kind?: ToolCallKind;
138
+ readonly server?: string;
139
+ readonly attempts?: number;
140
+ readonly durationMs?: number;
141
+ readonly effectId?: string;
142
+ readonly gate?: GateTimes;
143
+ readonly policy?: ToolPolicyFact;
144
+ }
145
+ /**
146
+ * `tool.completed` for a tool call that ended: its output, or the tool error it reported, and
147
+ * how it ended (R5.1).
148
+ */
149
+ export declare function toolCompleted(request: HostEffect, value: unknown, facts?: ToolCallFacts): {
80
150
  agent: import("@nylorun/core/define").AgentRef;
81
151
  error: {
82
152
  code: string;
83
153
  message: string;
84
154
  server?: string | undefined;
85
- vault?: string | undefined;
86
155
  retryable?: boolean | undefined;
87
156
  };
88
157
  output?: undefined;
89
158
  redacted: number;
90
159
  capabilityId: string;
91
160
  toolName: string;
161
+ status?: "cancelled" | "completed" | "failed" | undefined;
162
+ kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
163
+ server?: string | undefined;
164
+ attempts?: number | undefined;
165
+ durationMs?: number | undefined;
166
+ effectId?: string | undefined;
167
+ gate?: GateTimes | undefined;
168
+ policy?: ToolPolicyFact | undefined;
92
169
  } | {
93
170
  agent?: undefined;
94
171
  error: {
95
172
  code: string;
96
173
  message: string;
97
174
  server?: string | undefined;
98
- vault?: string | undefined;
99
175
  retryable?: boolean | undefined;
100
176
  };
101
177
  output?: undefined;
102
178
  redacted: number;
103
179
  capabilityId: string;
104
180
  toolName: string;
181
+ status?: "cancelled" | "completed" | "failed" | undefined;
182
+ kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
183
+ server?: string | undefined;
184
+ attempts?: number | undefined;
185
+ durationMs?: number | undefined;
186
+ effectId?: string | undefined;
187
+ gate?: GateTimes | undefined;
188
+ policy?: ToolPolicyFact | undefined;
105
189
  } | {
106
- redacted?: undefined;
107
190
  agent: import("@nylorun/core/define").AgentRef;
108
191
  error: {
109
192
  code: string;
110
193
  message: string;
111
194
  server?: string | undefined;
112
- vault?: string | undefined;
113
195
  retryable?: boolean | undefined;
114
196
  };
115
197
  output?: undefined;
198
+ redacted?: undefined;
116
199
  capabilityId: string;
117
200
  toolName: string;
201
+ status?: "cancelled" | "completed" | "failed" | undefined;
202
+ kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
203
+ server?: string | undefined;
204
+ attempts?: number | undefined;
205
+ durationMs?: number | undefined;
206
+ effectId?: string | undefined;
207
+ gate?: GateTimes | undefined;
208
+ policy?: ToolPolicyFact | undefined;
118
209
  } | {
119
- redacted?: undefined;
120
210
  agent?: undefined;
121
211
  error: {
122
212
  code: string;
123
213
  message: string;
124
214
  server?: string | undefined;
125
- vault?: string | undefined;
126
215
  retryable?: boolean | undefined;
127
216
  };
128
217
  output?: undefined;
218
+ redacted?: undefined;
129
219
  capabilityId: string;
130
220
  toolName: string;
221
+ status?: "cancelled" | "completed" | "failed" | undefined;
222
+ kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
223
+ server?: string | undefined;
224
+ attempts?: number | undefined;
225
+ durationMs?: number | undefined;
226
+ effectId?: string | undefined;
227
+ gate?: GateTimes | undefined;
228
+ policy?: ToolPolicyFact | undefined;
131
229
  } | {
132
230
  agent: import("@nylorun/core/define").AgentRef;
133
231
  error?: undefined;
@@ -135,6 +233,14 @@ export declare function toolCompleted(request: HostEffect, value: unknown): {
135
233
  redacted: number;
136
234
  capabilityId: string;
137
235
  toolName: string;
236
+ status?: "cancelled" | "completed" | "failed" | undefined;
237
+ kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
238
+ server?: string | undefined;
239
+ attempts?: number | undefined;
240
+ durationMs?: number | undefined;
241
+ effectId?: string | undefined;
242
+ gate?: GateTimes | undefined;
243
+ policy?: ToolPolicyFact | undefined;
138
244
  } | {
139
245
  agent?: undefined;
140
246
  error?: undefined;
@@ -142,20 +248,44 @@ export declare function toolCompleted(request: HostEffect, value: unknown): {
142
248
  redacted: number;
143
249
  capabilityId: string;
144
250
  toolName: string;
251
+ status?: "cancelled" | "completed" | "failed" | undefined;
252
+ kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
253
+ server?: string | undefined;
254
+ attempts?: number | undefined;
255
+ durationMs?: number | undefined;
256
+ effectId?: string | undefined;
257
+ gate?: GateTimes | undefined;
258
+ policy?: ToolPolicyFact | undefined;
145
259
  } | {
146
- redacted?: undefined;
147
260
  agent: import("@nylorun/core/define").AgentRef;
148
261
  error?: undefined;
149
262
  output: unknown;
263
+ redacted?: undefined;
150
264
  capabilityId: string;
151
265
  toolName: string;
266
+ status?: "cancelled" | "completed" | "failed" | undefined;
267
+ kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
268
+ server?: string | undefined;
269
+ attempts?: number | undefined;
270
+ durationMs?: number | undefined;
271
+ effectId?: string | undefined;
272
+ gate?: GateTimes | undefined;
273
+ policy?: ToolPolicyFact | undefined;
152
274
  } | {
153
- redacted?: undefined;
154
275
  agent?: undefined;
155
276
  error?: undefined;
156
277
  output: unknown;
278
+ redacted?: undefined;
157
279
  capabilityId: string;
158
280
  toolName: string;
281
+ status?: "cancelled" | "completed" | "failed" | undefined;
282
+ kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
283
+ server?: string | undefined;
284
+ attempts?: number | undefined;
285
+ durationMs?: number | undefined;
286
+ effectId?: string | undefined;
287
+ gate?: GateTimes | undefined;
288
+ policy?: ToolPolicyFact | undefined;
159
289
  } | {
160
290
  callId: string;
161
291
  invocationId: string;
@@ -164,13 +294,20 @@ export declare function toolCompleted(request: HostEffect, value: unknown): {
164
294
  code: string;
165
295
  message: string;
166
296
  server?: string | undefined;
167
- vault?: string | undefined;
168
297
  retryable?: boolean | undefined;
169
298
  };
170
299
  output?: undefined;
171
300
  redacted: number;
172
301
  capabilityId: string;
173
302
  toolName: string;
303
+ status?: "cancelled" | "completed" | "failed" | undefined;
304
+ kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
305
+ server?: string | undefined;
306
+ attempts?: number | undefined;
307
+ durationMs?: number | undefined;
308
+ effectId?: string | undefined;
309
+ gate?: GateTimes | undefined;
310
+ policy?: ToolPolicyFact | undefined;
174
311
  } | {
175
312
  callId: string;
176
313
  invocationId: string;
@@ -179,15 +316,21 @@ export declare function toolCompleted(request: HostEffect, value: unknown): {
179
316
  code: string;
180
317
  message: string;
181
318
  server?: string | undefined;
182
- vault?: string | undefined;
183
319
  retryable?: boolean | undefined;
184
320
  };
185
321
  output?: undefined;
186
322
  redacted: number;
187
323
  capabilityId: string;
188
324
  toolName: string;
325
+ status?: "cancelled" | "completed" | "failed" | undefined;
326
+ kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
327
+ server?: string | undefined;
328
+ attempts?: number | undefined;
329
+ durationMs?: number | undefined;
330
+ effectId?: string | undefined;
331
+ gate?: GateTimes | undefined;
332
+ policy?: ToolPolicyFact | undefined;
189
333
  } | {
190
- redacted?: undefined;
191
334
  callId: string;
192
335
  invocationId: string;
193
336
  agent: import("@nylorun/core/define").AgentRef;
@@ -195,14 +338,21 @@ export declare function toolCompleted(request: HostEffect, value: unknown): {
195
338
  code: string;
196
339
  message: string;
197
340
  server?: string | undefined;
198
- vault?: string | undefined;
199
341
  retryable?: boolean | undefined;
200
342
  };
201
343
  output?: undefined;
344
+ redacted?: undefined;
202
345
  capabilityId: string;
203
346
  toolName: string;
347
+ status?: "cancelled" | "completed" | "failed" | undefined;
348
+ kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
349
+ server?: string | undefined;
350
+ attempts?: number | undefined;
351
+ durationMs?: number | undefined;
352
+ effectId?: string | undefined;
353
+ gate?: GateTimes | undefined;
354
+ policy?: ToolPolicyFact | undefined;
204
355
  } | {
205
- redacted?: undefined;
206
356
  callId: string;
207
357
  invocationId: string;
208
358
  agent?: undefined;
@@ -210,12 +360,20 @@ export declare function toolCompleted(request: HostEffect, value: unknown): {
210
360
  code: string;
211
361
  message: string;
212
362
  server?: string | undefined;
213
- vault?: string | undefined;
214
363
  retryable?: boolean | undefined;
215
364
  };
216
365
  output?: undefined;
366
+ redacted?: undefined;
217
367
  capabilityId: string;
218
368
  toolName: string;
369
+ status?: "cancelled" | "completed" | "failed" | undefined;
370
+ kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
371
+ server?: string | undefined;
372
+ attempts?: number | undefined;
373
+ durationMs?: number | undefined;
374
+ effectId?: string | undefined;
375
+ gate?: GateTimes | undefined;
376
+ policy?: ToolPolicyFact | undefined;
219
377
  } | {
220
378
  callId: string;
221
379
  invocationId: string;
@@ -225,6 +383,14 @@ export declare function toolCompleted(request: HostEffect, value: unknown): {
225
383
  redacted: number;
226
384
  capabilityId: string;
227
385
  toolName: string;
386
+ status?: "cancelled" | "completed" | "failed" | undefined;
387
+ kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
388
+ server?: string | undefined;
389
+ attempts?: number | undefined;
390
+ durationMs?: number | undefined;
391
+ effectId?: string | undefined;
392
+ gate?: GateTimes | undefined;
393
+ policy?: ToolPolicyFact | undefined;
228
394
  } | {
229
395
  callId: string;
230
396
  invocationId: string;
@@ -234,22 +400,46 @@ export declare function toolCompleted(request: HostEffect, value: unknown): {
234
400
  redacted: number;
235
401
  capabilityId: string;
236
402
  toolName: string;
403
+ status?: "cancelled" | "completed" | "failed" | undefined;
404
+ kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
405
+ server?: string | undefined;
406
+ attempts?: number | undefined;
407
+ durationMs?: number | undefined;
408
+ effectId?: string | undefined;
409
+ gate?: GateTimes | undefined;
410
+ policy?: ToolPolicyFact | undefined;
237
411
  } | {
238
- redacted?: undefined;
239
412
  callId: string;
240
413
  invocationId: string;
241
414
  agent: import("@nylorun/core/define").AgentRef;
242
415
  error?: undefined;
243
416
  output: unknown;
417
+ redacted?: undefined;
244
418
  capabilityId: string;
245
419
  toolName: string;
420
+ status?: "cancelled" | "completed" | "failed" | undefined;
421
+ kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
422
+ server?: string | undefined;
423
+ attempts?: number | undefined;
424
+ durationMs?: number | undefined;
425
+ effectId?: string | undefined;
426
+ gate?: GateTimes | undefined;
427
+ policy?: ToolPolicyFact | undefined;
246
428
  } | {
247
- redacted?: undefined;
248
429
  callId: string;
249
430
  invocationId: string;
250
431
  agent?: undefined;
251
432
  error?: undefined;
252
433
  output: unknown;
434
+ redacted?: undefined;
253
435
  capabilityId: string;
254
436
  toolName: string;
437
+ status?: "cancelled" | "completed" | "failed" | undefined;
438
+ kind?: "http" | "mcp" | "platform" | "sandbox" | undefined;
439
+ server?: string | undefined;
440
+ attempts?: number | undefined;
441
+ durationMs?: number | undefined;
442
+ effectId?: string | undefined;
443
+ gate?: GateTimes | undefined;
444
+ policy?: ToolPolicyFact | undefined;
255
445
  } | undefined;
@@ -9,7 +9,9 @@ export function toolIds(context) {
9
9
  const agentOf = (request) => request.agent ? { agent: request.agent } : {};
10
10
  /**
11
11
  * `message.assistant` for a completed model effect: the step's text and tool calls. The
12
- * provider returns a `ModelCandidate` or a bare string; anything else writes no event.
12
+ * provider returns a `ModelCandidate` or a bare string. A step that said nothing (no text, no
13
+ * tool calls; a structured answer) is still one event, with `text: ""` (R7.1): every model call
14
+ * has its outcome row. Readers that build a conversation skip it (`isEmptyAssistantMessage`).
13
15
  */
14
16
  export function assistantMessage(request, value) {
15
17
  const invocationId = request.context
@@ -31,8 +33,6 @@ export function assistantMessage(request, value) {
31
33
  typeof block.name === "string")
32
34
  toolCalls.push({ callId: block.id, name: block.name, input: block.args });
33
35
  }
34
- if (!text && toolCalls.length === 0)
35
- return undefined;
36
36
  const candidate = (typeof value === "object" && value !== null ? value : {});
37
37
  const producer = candidate.evidence?.extras?.producer;
38
38
  return {
@@ -53,11 +53,12 @@ export function assistantMessage(request, value) {
53
53
  }
54
54
  /**
55
55
  * `context.compacted` for a model effect that summarized history (Model Calls §8): the
56
- * engine replaced the older transcript with that summary.
56
+ * engine replaced the older transcript with that summary. A partial summary (one call of
57
+ * several) is marked `partial: true` (R7.1): only the last call's event replaced the history.
57
58
  */
58
59
  export function contextCompacted(request, value) {
59
60
  const compaction = request.context?.compaction;
60
- if (!compaction || compaction.partial || isModelFailureOutcome(value))
61
+ if (!compaction || isModelFailureOutcome(value))
61
62
  return undefined;
62
63
  const summary = typeof value === "string"
63
64
  ? value
@@ -74,6 +75,7 @@ export function contextCompacted(request, value) {
74
75
  trigger: compaction.trigger === "overflow" ? "overflow" : "threshold",
75
76
  tokensBefore,
76
77
  tokensAfter: keptTokens + Math.ceil(summary.trim().length / 4),
78
+ ...(compaction.partial ? { partial: true } : {}),
77
79
  ...agentOf(request),
78
80
  };
79
81
  }
@@ -91,8 +93,48 @@ export function modelFailed(request, value) {
91
93
  ...agentOf(request),
92
94
  };
93
95
  }
94
- /** `tool.completed` for a tool the Runtime ran: its output, or the tool error it reported. */
95
- export function toolCompleted(request, value) {
96
+ /** From `startedAt` to `endedAt` in whole milliseconds; undefined unless both are times. */
97
+ export function durationBetween(startedAt, endedAt) {
98
+ const started = startedAt ? Date.parse(startedAt) : NaN;
99
+ const ended = endedAt ? Date.parse(endedAt) : NaN;
100
+ if (!Number.isFinite(started) || !Number.isFinite(ended))
101
+ return undefined;
102
+ return Math.max(0, Math.round(ended - started));
103
+ }
104
+ /**
105
+ * The timing a model call's outcome event carries (R7.1): its effect id, the journal's window
106
+ * (`startedAt` on the row to `settledAt`), and, when the gate metered the call (`metered`), the
107
+ * gate's own start and end, the first token's time and the metered usage.
108
+ */
109
+ export function modelOutcomeFacts(effectId, window, metered) {
110
+ const durationMs = durationBetween(window.startedAt, window.settledAt);
111
+ return {
112
+ effectId,
113
+ ...(durationMs === undefined ? {} : { durationMs }),
114
+ ...(metered?.startedAt && metered.endedAt
115
+ ? { gate: { startedAt: metered.startedAt, endedAt: metered.endedAt } }
116
+ : {}),
117
+ ...(metered?.firstTokenMs !== null && metered?.firstTokenMs !== undefined
118
+ ? { firstTokenMs: metered.firstTokenMs }
119
+ : {}),
120
+ ...(metered
121
+ ? {
122
+ meteredUsage: {
123
+ inputTokens: metered.inputTokens,
124
+ outputTokens: metered.outputTokens,
125
+ totalTokens: metered.totalTokens,
126
+ ...(metered.cachedTokens > 0 ? { cachedTokens: metered.cachedTokens } : {}),
127
+ ...(metered.costUsd > 0 ? { costUsd: metered.costUsd } : {}),
128
+ },
129
+ }
130
+ : {}),
131
+ };
132
+ }
133
+ /**
134
+ * `tool.completed` for a tool call that ended: its output, or the tool error it reported, and
135
+ * how it ended (R5.1).
136
+ */
137
+ export function toolCompleted(request, value, facts) {
96
138
  const ids = toolIds(request.context);
97
139
  if (!("callId" in ids))
98
140
  return undefined;
@@ -102,11 +144,8 @@ export function toolCompleted(request, value) {
102
144
  error: {
103
145
  code: String(outcome.code ?? "tool.failed"),
104
146
  message: String(outcome.message ?? ""),
105
- // `credential_rejected` (R2b C1): which server, and which vault's credential.
147
+ // `credential_rejected` (R2b C1): which server.
106
148
  ...(typeof outcome.server === "string" ? { server: outcome.server } : {}),
107
- ...(outcome.vault === "installation" || outcome.vault === "user"
108
- ? { vault: outcome.vault }
109
- : {}),
110
149
  ...(typeof outcome.retryable === "boolean" ? { retryable: outcome.retryable } : {}),
111
150
  },
112
151
  }
@@ -121,6 +160,18 @@ export function toolCompleted(request, value) {
121
160
  ...ids,
122
161
  capabilityId: request.capabilityId,
123
162
  toolName: request.toolName,
163
+ ...(facts
164
+ ? {
165
+ status: facts.status,
166
+ ...(facts.kind === undefined ? {} : { kind: facts.kind }),
167
+ ...(facts.server === undefined ? {} : { server: facts.server }),
168
+ ...(facts.attempts === undefined ? {} : { attempts: facts.attempts }),
169
+ ...(facts.durationMs === undefined ? {} : { durationMs: facts.durationMs }),
170
+ ...(facts.effectId === undefined ? {} : { effectId: facts.effectId }),
171
+ ...(facts.gate === undefined ? {} : { gate: facts.gate }),
172
+ ...(facts.policy === undefined ? {} : { policy: facts.policy }),
173
+ }
174
+ : {}),
124
175
  ...result,
125
176
  ...redacted,
126
177
  ...agentOf(request),
@@ -0,0 +1,43 @@
1
+ /**
2
+ * A turn's timing and totals (R7.1), so the event that ends it is its span. The session body
3
+ * keeps when its active turn started (`turnStartedAt`, set beside `activeTurnId`), how long it
4
+ * has waited paused for a person (`pausedMs`), and since when it waits (`pausedAt`, while
5
+ * paused). `turn.completed`, `turn.failed` and `turn.cancelled` carry `endTurn`'s facts.
6
+ *
7
+ * A turn started before the Runtime recorded these has no `turnStartedAt`: its end carries no
8
+ * `durationMs`.
9
+ */
10
+ import type { Tx } from "../store/types.js";
11
+ /** The turn timing a session body keeps. */
12
+ export interface TurnTiming {
13
+ turnStartedAt?: string;
14
+ /** The trace context the turn's message arrived with (R7.4); it ends with the turn. */
15
+ turnTrace?: unknown;
16
+ pausedMs?: number;
17
+ pausedAt?: string;
18
+ }
19
+ /** A new turn starts now. Mutates `s`. */
20
+ export declare function startTurn(s: TurnTiming, now?: Date): void;
21
+ /** The turn waits for a person from now, unless it already does. Mutates `s`. */
22
+ export declare function pauseTurn(s: TurnTiming, now?: Date): void;
23
+ /** A paused turn goes on: its wait is added to `pausedMs`. No-op when it was not paused. */
24
+ export declare function resumeTurn(s: TurnTiming, now?: Date): void;
25
+ /**
26
+ * The facts the event that ends turn `turnId` carries: `durationMs` from its start to now, waits
27
+ * included, so the turn's span holds every crossing in it; `pausedMs`, how long it waited paused
28
+ * (a wait still open ends now, as for a cancel); the session's agent;
29
+ * and the turn's totals from the usage ledger (one read, as `/v1/tenant/usage` totals a turn;
30
+ * `steps` are the model calls the gate metered). Clears the turn's timing from `s`.
31
+ */
32
+ export declare function endTurn(t: Tx, s: TurnTiming & {
33
+ agentId: string;
34
+ }, turnId: string | null, now?: Date): Promise<{
35
+ durationMs?: number;
36
+ pausedMs?: number;
37
+ agentId: string;
38
+ totals?: {
39
+ steps: number;
40
+ tokens: number;
41
+ costUsd: number;
42
+ };
43
+ }>;
@@ -0,0 +1,39 @@
1
+ import { durationBetween } from "./transcript.js";
2
+ /** A new turn starts now. Mutates `s`. */
3
+ export function startTurn(s, now = new Date()) {
4
+ s.turnStartedAt = now.toISOString();
5
+ s.pausedMs = 0;
6
+ delete s.pausedAt;
7
+ }
8
+ /** The turn waits for a person from now, unless it already does. Mutates `s`. */
9
+ export function pauseTurn(s, now = new Date()) {
10
+ s.pausedAt ??= now.toISOString();
11
+ }
12
+ /** A paused turn goes on: its wait is added to `pausedMs`. No-op when it was not paused. */
13
+ export function resumeTurn(s, now = new Date()) {
14
+ if (s.pausedAt === undefined)
15
+ return;
16
+ s.pausedMs = (s.pausedMs ?? 0) + (durationBetween(s.pausedAt, now.toISOString()) ?? 0);
17
+ delete s.pausedAt;
18
+ }
19
+ /**
20
+ * The facts the event that ends turn `turnId` carries: `durationMs` from its start to now, waits
21
+ * included, so the turn's span holds every crossing in it; `pausedMs`, how long it waited paused
22
+ * (a wait still open ends now, as for a cancel); the session's agent;
23
+ * and the turn's totals from the usage ledger (one read, as `/v1/tenant/usage` totals a turn;
24
+ * `steps` are the model calls the gate metered). Clears the turn's timing from `s`.
25
+ */
26
+ export async function endTurn(t, s, turnId, now = new Date()) {
27
+ resumeTurn(s, now);
28
+ const elapsed = durationBetween(s.turnStartedAt, now.toISOString());
29
+ const totals = turnId ? await t.modelUsageTotals({ scope: "turn", id: turnId }) : undefined;
30
+ const facts = {
31
+ ...(elapsed === undefined ? {} : { durationMs: Math.max(0, elapsed), pausedMs: s.pausedMs ?? 0 }),
32
+ agentId: s.agentId,
33
+ ...(totals ? { totals: { steps: totals.calls, tokens: totals.tokens, costUsd: totals.costUsd } } : {}),
34
+ };
35
+ delete s.turnStartedAt;
36
+ delete s.pausedMs;
37
+ delete s.turnTrace;
38
+ return facts;
39
+ }
@@ -119,6 +119,8 @@ export interface TenantHandle {
119
119
  attachHarness?(channel: HarnessChannel, peer: HarnessPeer): () => void;
120
120
  /** The Tenant's side of a sandbox pod's join (F7.2); absent without sandbox pods. */
121
121
  hostAuthority?(): HostAuthority | undefined;
122
+ /** The custom harness a per-harness token is for (R4.1), or undefined. */
123
+ harnessOfToken?(token: string): Promise<string | undefined>;
122
124
  /** The Tenant's harnesses (F6.2), for `/ready`. */
123
125
  harnessStatus?(): HarnessStatus;
124
126
  }
@@ -0,0 +1,42 @@
1
+ /** The Tenant's trace key (`traces/key.ts`). */
2
+ export type TraceKey = Buffer;
3
+ export declare function traceIdOf(key: TraceKey, tenantId: string, sessionId: string, turnId: string): string;
4
+ export declare function turnSpanOf(key: TraceKey, turnId: string): string;
5
+ export declare function effectSpanOf(key: TraceKey, effectId: string): string;
6
+ export declare function egressSpanOf(key: TraceKey, sessionId: string, seq: number): string;
7
+ export declare function eventSpanOf(key: TraceKey, sessionId: string, seq: number): string;
8
+ /** W3C trace context (R7.4): `traceparent`, and `tracestate` when the caller sent one. */
9
+ export interface TraceContext {
10
+ readonly traceparent: string;
11
+ readonly tracestate?: string;
12
+ }
13
+ /**
14
+ * A `traceparent` as W3C trace context reads it: its trace id and parent span id, or undefined
15
+ * when it is malformed (version `ff`, an all-zero id, or another shape), which a receiver
16
+ * ignores. A version above `00` may carry more fields after the flags.
17
+ */
18
+ export declare function parseTraceparent(value: string): {
19
+ traceId: string;
20
+ spanId: string;
21
+ } | undefined;
22
+ /**
23
+ * The trace context a request's headers carry (R7.4), or undefined without a valid
24
+ * `traceparent`. A `tracestate` too long or with control characters is dropped, never the
25
+ * `traceparent`. Kept normalized: `00-<trace>-<span>-<flags>`.
26
+ */
27
+ export declare function traceContextOf(headers: {
28
+ get(name: string): string | null | undefined;
29
+ }): TraceContext | undefined;
30
+ /** `00-<trace>-<span>-01`: the context a turn or a crossing hands on (sampled). */
31
+ export declare function traceparentOf(traceId: string, spanId: string): string;
32
+ /**
33
+ * The trace id of turn `turnId`: the one its message arrived with (`inbound`, R7.4), else
34
+ * derived. The same as `turnTraceOf` reads from the turn's `command.message`.
35
+ */
36
+ export declare function turnTraceIdOf(key: TraceKey, ids: {
37
+ tenantId: string;
38
+ sessionId: string;
39
+ turnId: string;
40
+ }, inbound?: {
41
+ readonly traceparent: string;
42
+ }): string;