@nylorun/runtime 0.24.0-beta → 0.25.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 (157) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/README.md +10 -2
  3. package/dist/api/a2a/card.d.ts +11 -1
  4. package/dist/api/a2a/card.js +26 -2
  5. package/dist/api/a2a/endpoint.js +4 -2
  6. package/dist/api/a2a/protocol.d.ts +25 -2
  7. package/dist/api/a2a/protocol.js +20 -3
  8. package/dist/api/a2a/routes.d.ts +4 -1
  9. package/dist/api/a2a/routes.js +65 -7
  10. package/dist/api/ag-ui/endpoint.js +5 -2
  11. package/dist/api/ag-ui/history.d.ts +6 -1
  12. package/dist/api/ag-ui/history.js +35 -2
  13. package/dist/api/ag-ui/routes.js +53 -11
  14. package/dist/api/components.d.ts +1165 -678
  15. package/dist/api/components.js +16 -1
  16. package/dist/api/gate/keys.d.ts +2 -1
  17. package/dist/api/gate/keys.js +7 -0
  18. package/dist/api/gate/routes.js +13 -0
  19. package/dist/api/http/app.js +13 -2
  20. package/dist/api/http/body.d.ts +3 -3
  21. package/dist/api/http/body.js +7 -7
  22. package/dist/api/http/routes/environment-manifests.d.ts +9 -0
  23. package/dist/api/http/routes/environment-manifests.js +118 -0
  24. package/dist/api/http/routes/environments.js +61 -12
  25. package/dist/api/http/routes/reads.d.ts +52 -3
  26. package/dist/api/http/routes/sessions.js +13 -3
  27. package/dist/api/http/routes/tenant.js +35 -7
  28. package/dist/api/inbound-files.d.ts +65 -0
  29. package/dist/api/inbound-files.js +115 -0
  30. package/dist/api/openapi.js +18 -3
  31. package/dist/artifacts/disk.js +20 -14
  32. package/dist/artifacts/media-types.d.ts +15 -0
  33. package/dist/artifacts/media-types.js +56 -4
  34. package/dist/artifacts/parts.d.ts +12 -3
  35. package/dist/artifacts/parts.js +15 -4
  36. package/dist/artifacts/workspace.d.ts +4 -4
  37. package/dist/artifacts/workspace.js +6 -18
  38. package/dist/core/flow-host.d.ts +1 -1
  39. package/dist/core/flow-host.js +2 -2
  40. package/dist/core/sandbox-routes.js +2 -2
  41. package/dist/core/turn-manifest.d.ts +3 -2
  42. package/dist/core/turn-manifest.js +29 -5
  43. package/dist/gates/egress-credentials.js +1 -1
  44. package/dist/gates/egress.d.ts +13 -19
  45. package/dist/gates/egress.js +30 -29
  46. package/dist/gates/http-tool.d.ts +3 -4
  47. package/dist/gates/http-tool.js +8 -12
  48. package/dist/gates/journal.js +0 -1
  49. package/dist/gates/mcp-handler.js +2 -3
  50. package/dist/gates/policy.js +1 -3
  51. package/dist/gates/tool-contract.d.ts +1 -1
  52. package/dist/harness/calls.d.ts +2 -2
  53. package/dist/harness/calls.js +9 -12
  54. package/dist/harness/main.js +7 -1
  55. package/dist/harness/pod.d.ts +6 -1
  56. package/dist/harness/pod.js +5 -0
  57. package/dist/harness/service.js +5 -5
  58. package/dist/harness/setup.d.ts +2 -0
  59. package/dist/harness/setup.js +25 -1
  60. package/dist/harness-api/record.d.ts +1 -1
  61. package/dist/harness-api/record.js +13 -13
  62. package/dist/harness-api/server.d.ts +27 -4
  63. package/dist/harness-api/server.js +41 -8
  64. package/dist/harness-api/tool-journal.d.ts +17 -8
  65. package/dist/harness-api/tool-journal.js +41 -11
  66. package/dist/harness-api/workspace.d.ts +7 -5
  67. package/dist/harness-api/workspace.js +25 -19
  68. package/dist/host/gates.js +2 -2
  69. package/dist/host/stack-config.js +1 -1
  70. package/dist/keys/keys.d.ts +9 -2
  71. package/dist/keys/keys.js +4 -1
  72. package/dist/management-openapi.json +366 -61
  73. package/dist/mcp/connect.d.ts +1 -2
  74. package/dist/mcp/connect.js +1 -4
  75. package/dist/mcp/pool.d.ts +1 -4
  76. package/dist/mcp/pool.js +13 -27
  77. package/dist/mcp/preview.js +0 -1
  78. package/dist/mcp/snapshot.d.ts +11 -13
  79. package/dist/mcp/snapshot.js +27 -38
  80. package/dist/model/capabilities.d.ts +26 -0
  81. package/dist/model/capabilities.js +44 -0
  82. package/dist/model/catalog.d.ts +34 -3
  83. package/dist/model/catalog.js +38 -2
  84. package/dist/model/models.d.ts +2 -0
  85. package/dist/model/models.js +1 -1
  86. package/dist/model/native-blocks.d.ts +35 -0
  87. package/dist/model/native-blocks.js +170 -0
  88. package/dist/model/pi-model.js +106 -94
  89. package/dist/openapi.json +9554 -5104
  90. package/dist/record/environment.js +1 -1
  91. package/dist/sandbox/join.js +4 -0
  92. package/dist/sandbox/manager.d.ts +32 -14
  93. package/dist/sandbox/manager.js +132 -93
  94. package/dist/sandbox/placement.d.ts +1 -1
  95. package/dist/sandbox/placement.js +2 -2
  96. package/dist/sandbox/pods/client.d.ts +3 -1
  97. package/dist/sandbox/pods/lifecycle.d.ts +8 -0
  98. package/dist/sandbox/pods/lifecycle.js +15 -0
  99. package/dist/sandbox/pods/spec.js +2 -1
  100. package/dist/sandbox/resolve.d.ts +5 -3
  101. package/dist/sandbox/resolve.js +9 -2
  102. package/dist/sandbox/runtime-tools.d.ts +9 -0
  103. package/dist/sandbox/runtime-tools.js +16 -0
  104. package/dist/sandbox/session-sandbox.d.ts +4 -6
  105. package/dist/sandbox/session-sandbox.js +47 -94
  106. package/dist/sandbox/setup.d.ts +4 -1
  107. package/dist/sandbox/setup.js +46 -9
  108. package/dist/sandbox/share.d.ts +12 -7
  109. package/dist/sandbox/share.js +27 -25
  110. package/dist/sandbox/skills.d.ts +8 -6
  111. package/dist/sandbox/skills.js +24 -23
  112. package/dist/store/postgres/drizzle/0024_flat_manifest.sql +7 -0
  113. package/dist/store/postgres/drizzle/0025_environment_manifests.sql +14 -0
  114. package/dist/store/postgres/drizzle/0026_environment_forks.sql +1 -0
  115. package/dist/store/postgres/drizzle/0027_environment_image_digest.sql +1 -0
  116. package/dist/store/postgres/drizzle/meta/_journal.json +28 -0
  117. package/dist/store/postgres/reads.js +8 -2
  118. package/dist/store/postgres/schema.d.ts +217 -0
  119. package/dist/store/postgres/schema.js +36 -2
  120. package/dist/store/postgres/store.js +79 -4
  121. package/dist/store/types.d.ts +68 -14
  122. package/dist/tenant/advance.js +3 -0
  123. package/dist/tenant/artifact-tool.d.ts +1 -1
  124. package/dist/tenant/artifact-tool.js +43 -22
  125. package/dist/tenant/commands.js +24 -4
  126. package/dist/tenant/context.d.ts +10 -4
  127. package/dist/tenant/effects.js +7 -9
  128. package/dist/tenant/environment-manifests.d.ts +57 -0
  129. package/dist/tenant/environment-manifests.js +200 -0
  130. package/dist/tenant/environments.d.ts +54 -47
  131. package/dist/tenant/environments.js +304 -83
  132. package/dist/tenant/model-setting.d.ts +14 -0
  133. package/dist/tenant/model-setting.js +51 -0
  134. package/dist/tenant/sessions.d.ts +5 -1
  135. package/dist/tenant/sessions.js +45 -12
  136. package/dist/tenant/skill-tool.d.ts +3 -3
  137. package/dist/tenant/skill-tool.js +6 -11
  138. package/dist/tenant/sweep.js +1 -1
  139. package/dist/tenant/tool-results.js +1 -1
  140. package/dist/tenant/tool-search.d.ts +7 -11
  141. package/dist/tenant/tool-search.js +8 -5
  142. package/dist/tenant/transcript.d.ts +51 -32
  143. package/dist/tenant/transcript.js +2 -1
  144. package/dist/traces/ids.d.ts +0 -1
  145. package/dist/traces/ids.js +0 -4
  146. package/dist/traces/map.d.ts +2 -2
  147. package/dist/traces/map.js +1 -29
  148. package/dist/vault/coverage.js +11 -13
  149. package/dist/vault/host-model.d.ts +4 -1
  150. package/dist/vault/host-model.js +10 -2
  151. package/dist/vault/service.d.ts +49 -4
  152. package/dist/vault/service.js +153 -6
  153. package/dist/version.d.ts +1 -1
  154. package/dist/version.js +1 -1
  155. package/package.json +3 -3
  156. package/dist/sandbox/capability.d.ts +0 -3
  157. package/dist/sandbox/capability.js +0 -10
@@ -12,7 +12,9 @@
12
12
  * - `POST …/threads/:thread/cancel` — cancel the running turn.
13
13
  *
14
14
  * Each thread maps to one session per subject, agent and thread. The message id is the
15
- * idempotency key, approvals become interrupts resumed through `resume`, and the last AG-UI
15
+ * idempotency key, a message's media parts become file parts (bytes sent inline are stored as
16
+ * artifacts of the session, `../inbound-files.ts`; a file the model does not read is a
17
+ * `RUN_ERROR`), approvals become interrupts resumed through `resume`, and the last AG-UI
16
18
  * event made from each Runtime event carries its cursor as the SSE id. A run's session is
17
19
  * created on its first run with the options in `forwardedProps.nylorun.session` and never
18
20
  * changed afterwards. A stream opened with an issuer token ends at the token's expiry with
@@ -22,7 +24,8 @@ import { randomUUID } from "node:crypto";
22
24
  import { EventType, } from "@ag-ui/core";
23
25
  import { RunAgentInputSchema } from "@ag-ui/core/schemas";
24
26
  import { PutSessionRequestSchema, } from "@nylorun/core/contracts";
25
- import { messagesFromEvents } from "./history.js";
27
+ import { messagesFromEvents, NYLORUN_FILE_PROVIDER } from "./history.js";
28
+ import { discardFiles, inlineFileName, messageParts, refuseUrl, } from "../inbound-files.js";
26
29
  import { sessionIdFor } from "./session-id.js";
27
30
  import { SSE_CONTENT_TYPE, SSE_HEARTBEAT, sseFrame } from "./sse.js";
28
31
  import { RunTranslator } from "./translate.js";
@@ -60,11 +63,38 @@ function runError(error) {
60
63
  : error.message;
61
64
  return { type: EventType.RUN_ERROR, message, code };
62
65
  }
63
- /** The trailing user message: the Runtime keeps the transcript, AG-UI resends all of it. */
66
+ /** A media part's file: bytes sent inline, or an artifact the Runtime already holds. */
67
+ function inboundFile(part, index) {
68
+ const { source } = part;
69
+ if (source.type === "url")
70
+ return refuseUrl();
71
+ if (source.type === "file") {
72
+ if (source.provider !== NYLORUN_FILE_PROVIDER)
73
+ return fail(400, `A file source names an artifact: provider "${NYLORUN_FILE_PROVIDER}" and its artifact id`, { code: "invalid_request" });
74
+ return { type: "artifact", artifactId: source.value };
75
+ }
76
+ const metadata = (part.metadata ?? {});
77
+ const named = [metadata.filename, metadata.name].find((value) => typeof value === "string" && value !== "");
78
+ return {
79
+ type: "inline",
80
+ name: named ?? inlineFileName(source.mimeType, index),
81
+ mediaType: source.mimeType,
82
+ data: source.value,
83
+ };
84
+ }
85
+ /**
86
+ * The trailing user message: the Runtime keeps the transcript, AG-UI resends all of it. Its
87
+ * text, or its parts when it carries a media part.
88
+ */
64
89
  function lastUserMessage(messages) {
65
90
  const last = messages.at(-1);
66
91
  if (!last || last.role !== "user")
67
92
  return fail(400, "The run's last message must be a user message");
93
+ if (typeof last.content !== "string" && last.content.some((part) => part.type !== "text")) {
94
+ let files = 0;
95
+ const parts = last.content.map((part) => part.type === "text" ? { type: "text", text: part.text } : inboundFile(part, files++));
96
+ return { id: last.id, text: "", parts };
97
+ }
68
98
  const text = typeof last.content === "string"
69
99
  ? last.content
70
100
  : last.content
@@ -138,12 +168,23 @@ async function submit(ctx, id, input, scope, trace) {
138
168
  const message = lastUserMessage(input.messages);
139
169
  // The AG-UI message id is the idempotency key: a retried run replays the same turn, and
140
170
  // history gives the message back its client id.
141
- return accepted(ctx, id, {
142
- type: "message",
143
- requestId: randomUUID(),
144
- idempotencyKey: message.id,
145
- content: message.text,
146
- }, scope, trace);
171
+ if (!message.parts)
172
+ return accepted(ctx, id, {
173
+ type: "message",
174
+ requestId: randomUUID(),
175
+ idempotencyKey: message.id,
176
+ content: message.text,
177
+ }, scope, trace);
178
+ const access = accessOf(scope);
179
+ const { parts, stored } = await messageParts(ctx, id, message.id, message.parts, access);
180
+ try {
181
+ return await accepted(ctx, id, { type: "message", requestId: randomUUID(), idempotencyKey: message.id, parts }, scope, trace);
182
+ }
183
+ catch (error) {
184
+ // A refused message leaves no files behind.
185
+ await discardFiles(ctx, stored, access);
186
+ throw error;
187
+ }
147
188
  }
148
189
  /**
149
190
  * Streams translated events until the run ends. Closing the connection stops the read, never
@@ -254,8 +295,9 @@ trace) {
254
295
  cursor = await submit(ctx, id, input, scope, trace);
255
296
  }
256
297
  catch (error) {
257
- // A busy session or a limit is a run that could not start, not a transport failure.
258
- if (error instanceof HttpError && (error.status === 409 || error.status === 429))
298
+ // A busy session, a limit or a file the model does not read is a run that could not start,
299
+ // not a transport failure.
300
+ if (error instanceof HttpError && [409, 422, 429].includes(error.status))
259
301
  return stream(response, translator, undefined, [runError(error)]);
260
302
  throw error;
261
303
  }