nylorun 0.15.1-beta → 0.17.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 (46) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/README.md +136 -74
  3. package/dist/cli.js +31 -12
  4. package/dist/client/agent-manifests.d.ts +4 -0
  5. package/dist/client/agent-manifests.js +100 -0
  6. package/dist/client/agents.d.ts +1 -3
  7. package/dist/client/agents.js +459 -117
  8. package/dist/client/apply.d.ts +7 -0
  9. package/dist/client/apply.js +99 -0
  10. package/dist/client/artifacts.js +3 -3
  11. package/dist/client/doctor.d.ts +1 -1
  12. package/dist/client/doctor.js +2 -2
  13. package/dist/client/io.d.ts +2 -0
  14. package/dist/client/io.js +11 -0
  15. package/dist/client/mcp.d.ts +5 -3
  16. package/dist/client/mcp.js +28 -25
  17. package/dist/client/migrate.d.ts +4 -0
  18. package/dist/client/migrate.js +140 -0
  19. package/dist/client/model/pi-ai.d.ts +1 -1
  20. package/dist/client/model/pi-ai.js +1 -1
  21. package/dist/client/models.d.ts +5 -2
  22. package/dist/client/models.js +17 -8
  23. package/dist/client/runtime.js +3 -3
  24. package/dist/client/sessions.js +29 -18
  25. package/dist/client/settings.d.ts +5 -5
  26. package/dist/client/settings.js +38 -18
  27. package/dist/client/tenant.d.ts +1 -1
  28. package/dist/client/tenant.js +10 -7
  29. package/dist/project/seed.js +2 -1
  30. package/dist/sandbox/commands.js +10 -8
  31. package/dist/sandbox/kubectl.js +2 -1
  32. package/dist/sandbox/manifests.js +3 -2
  33. package/dist/sandbox/probe.js +9 -7
  34. package/dist/stack/commands.js +12 -11
  35. package/dist/stack/compose-file.d.ts +3 -0
  36. package/dist/stack/compose-file.js +32 -36
  37. package/dist/stack/operator-keys.js +7 -6
  38. package/dist/stack/ports.js +2 -1
  39. package/dist/stack/studio-login.js +2 -1
  40. package/dist/tuning.d.ts +90 -0
  41. package/dist/tuning.js +143 -0
  42. package/package.json +9 -9
  43. package/dist/client/environment-manifests.d.ts +0 -10
  44. package/dist/client/environment-manifests.js +0 -173
  45. package/dist/client/environments.d.ts +0 -4
  46. package/dist/client/environments.js +0 -295
package/CHANGELOG.md CHANGED
@@ -1,5 +1,139 @@
1
1
  # nylorun
2
2
 
3
+ ## 0.17.0-beta
4
+
5
+ ### Minor Changes
6
+
7
+ - cc8d034: Track T3 in the clients. The SDK has `client.agents.plan(id, input)` (what a move would do), `client.agents.restart(id, { retry? })` and `list({ outdated: true })`. The CLI has `nylorun agents pin <id> <n>`, `track <id>`, `restart <id> [--retry]`, `put --dry-run`, and `list --outdated` (`--behind` kept as its alias), and prints the version an Agent moves to. Studio's Agent page moves an Agent (Move to vN, Pin, Track), restarts it on a pending version or retries a failed one, and shows "vN at next start", a version waiting for secrets, or one that failed to start. The starter's dev loop no longer deletes and remakes its Agent: the tracking Agent moves on each save.
8
+ - 22c61ce: Protocol 16, Agents from one manifest (track T2), a fresh start. An agent manifest (v8) is one versioned document at `/v1/agent-manifests/{name}` with a `harness` section (what runs inside the loop, including the harness's id) and a `runtime` section (what an environment manifest said). The Runtime checks the two against each other when it is saved (`422 manifest_inconsistent` with `details.gaps`), in place of `requires` at session open. Agent definitions and environment manifests are gone.
9
+
10
+ Environments are Agents: `/v1/agents/{id}` and its sub-routes, made from a saved manifest only (`manifest: "name"` tracks it, `"name@n"` pins a version; either resolves once, into `resolvedVersion`), with a derived `state` (`working`, `sleeping`, `input_required`, `failing`, `paused`) and `attention`. Every session runs on one Agent (`PUT /v1/sessions/{id} { agent, ownerUserId }`) and pins its manifest version. No session is special (D71). Error codes, events (`agent.*`), scopes (`agents:write`, `agent-manifests:write`) and identity-file grants (`agents`) say Agent; model budget scope `agent` is `manifest`. Harness API 5: `turn.start.agent` replaces `turn.start.environment`, with `definition` and `loop`. Migration 0032 closes older sessions (`protocol_16`) and drops Environments with their disks and vaults.
11
+
12
+ The SDK has `client.agentManifests`, `client.agents` and `composeManifest(dir)` for three-file authoring; the CLI has `nylorun apply`, `nylorun agent-manifests`, `nylorun agents` and `nylorun migrate v8`; Studio has an Agents screen, an Agent page and an Agent manifests screen. See MIGRATION.md.
13
+
14
+ - 4fa160d: Agent memory, storage and API (track T5, D72). An agent manifest's `harness.memory` (`access`: `read_write` or `read_only`; `instructions`, at most 4,096 characters) turns on the Agent's memory: Markdown files under `/memories` it keeps across sessions, wakes and upgrades. The Runtime keeps them in Postgres (`memories`, `memory_versions`, migration 0036) with a version per change and who made it. `GET /v1/agents/{id}/memories` lists them (`pathPrefix`), `GET`, `PUT` (whole content, with an optional `contentSha256` precondition: `409 memory_conflict`) and `DELETE /v1/agents/{id}/memories/{path}` read, write and delete one (or a folder), and `GET /v1/agents/{id}/memory_versions` and `.../memory_versions/{versionId}` page the versions. A fork copies the memories (the fork plan adds `memories`); a delete removes them. `@nylorun/core` adds `memoryPathOf`, `memoryDescriptionOf` and the memory contracts; new Runtime limits `memoryBytes` (100 KB) and `memoriesPerAgent` (10,000); new error code `memory_conflict`. The SDK adds `client.agents.memories`; the CLI adds `nylorun agents memories ls|cat|put|rm|versions`. The model's `memory` tool arrives in the next steps of T5.
15
+ - 9e60e40: Protocol 17, a queue per session (track T4, D76). A message sent while the session's turn runs or waits is queued (`{status: "queued", queuedMessageId, position}`, `message.queued`) and starts the next turn when this one ends, with every queued message, each its own user message (`queue.taken`); a cancel ends the turn, not the queue. `delivery: "reject"` keeps the refusal, now `409 session_busy`, and a protocol 16 client's messages default to it, so the Host serves protocol 16 and 17. The queue holds at most the Runtime limit `sessionQueuedMessages` (`429 queue_full`), and session reads count `queuedMessages`. Our engine takes `{kind: "messages", messages}` as a turn's input. The SDK's `input` and `inputParts` take `delivery`, and the CLI's `sessions send` takes `--reject-if-busy`. See MIGRATION.md.
16
+ - f85483d: Triggers (track T4, D74). An agent manifest's `runtime.triggers` declares `schedule` (cron with an IANA `timezone`) and `at` triggers, each with the session its runs go to (a session id, opened on the first run, or `new` for a session per run) and its prompt. They start active with a new Agent, fire on a durable timer per trigger with Postgres as the truth (one late fire after downtime, never a backfill, a fixed jitter per trigger), and each fire is a run (`started`, `queued`, `skipped` or `failed`, with a reason) at `GET /v1/agents/{id}/runs`. A schedule adds at most one queued message to a busy session. `GET /v1/agents/{id}/triggers` and `POST .../triggers/{triggerId}/pause`, `/resume` and `/run` (with an `Idempotency-Key`); Agent reads add `nextWakeAt`, and the Agent's stream adds `agent.run`, `agent.trigger_paused` and `agent.trigger_resumed`. New Runtime limits: `triggersPerAgent`, `triggerMinIntervalMs` and `triggerRunRetentionMs` (with floors), `triggerRunsPerHour`, `triggerJitterPercent`, `triggerJitterMaxMs`, `triggerPromptChars`; Host tuning `triggers.lateGraceMs` and `triggers.intervalCheckFires`. The SDK's `client.agents` adds `triggers`, `pauseTrigger`, `resumeTrigger`, `runTrigger` and `runs`; the CLI adds `nylorun agents triggers` and `nylorun agents runs`.
17
+ - ae54de7: Webhook triggers (track T4, D75). A `webhook: "standard-webhooks"` trigger has an endpoint, `POST /v1/webhooks/{endpointId}`, an anonymous, unversioned route that takes any body up to the new Runtime limit `webhookBodyBytes` and verifies Standard Webhooks (`webhook-id`, `webhook-timestamp` within the Host's `triggers.webhookToleranceMs`, `webhook-signature`) in the keys service, which alone opens the trigger's sealed secret; anything else is `401` and writes nothing. A delivery runs the trigger once per `webhook-id` (`202 {runId, status}`); a paused trigger answers a signed one `409 trigger_paused`. `POST /v1/agents/{id}/triggers/{triggerId}/secret` makes or replaces the `whsec_` secret, shown once (`agent.trigger_secret_rotated`); trigger reads show `webhookUrl` and `secretSet`. The payload reaches the model under the trigger's prompt in a labelled `<trigger-payload>` block. The SDK adds `agents.rotateWebhookSecret`, and the CLI `nylorun agents triggers new-secret`.
18
+
19
+ ### Patch Changes
20
+
21
+ - Pin core to the tested release.
22
+ - Pin agents to the tested release.
23
+ - Pin admin to the tested release.
24
+ - Pin runtime to the tested release.
25
+ - Pin studio to the tested release.
26
+ - Updated dependencies [218b078]
27
+ - Updated dependencies [cc8d034]
28
+ - Updated dependencies [22c61ce]
29
+ - Updated dependencies [1ded443]
30
+ - Updated dependencies [76dcd11]
31
+ - Updated dependencies [bf942ed]
32
+ - Updated dependencies [4fa160d]
33
+ - Updated dependencies [9fed948]
34
+ - Updated dependencies [ffeb3bb]
35
+ - Updated dependencies [9e60e40]
36
+ - Updated dependencies [f85483d]
37
+ - Updated dependencies [ae54de7]
38
+ - Updated dependencies
39
+ - Updated dependencies
40
+ - @nylorun/core@0.24.0-beta
41
+ - @nylorun/agents@0.24.0-beta
42
+ - @nylorun/admin@0.19.0-beta
43
+
44
+ ## 0.16.0-beta
45
+
46
+ ### Minor Changes
47
+
48
+ - 0a2fbc5: **Artifacts reach the harness through the Harness API; `read_artifact` and `save_artifact` run in the harness (protocol 15, Harness API 4).** The first step of the harness boundary: model-facing work belongs to the harness, and the Runtime offers primitives and holds limits and access. A fresh start for agent sessions: the Runtime speaks protocol 15 only. See MIGRATION.md.
49
+
50
+ - **The artifact seam.** A harness reads and writes the artifacts of the run it holds: `artifact.read {artifactId, version?, offset?, length?}` answers the version's metadata (`ArtifactMetaSchema`) and its bytes from `offset`, at most `turn.start.limits.chunkBytes`; `artifact.write` (`begin`, `chunk`, `commit`, `abort`) makes a file artifact of the session or a new version of one of its own, streamed with backpressure into the Object store and committed in Postgres within the Tenant's and the Environment's artifact limits. The scope is always the run's session: its own artifacts, and the Tenant-wide ones its messages named; anything else is the new error code `not_found`, alike. A write's `key` makes it idempotent within the session (`artifact_versions.write_key`, migration 0028), and its `effectId` links the artifact to a tool call of the turn, whose call id `artifact.created` carries. An upload the run leaves open commits nothing. Client helpers: `readArtifact`, `openArtifactWrite`, `writeArtifactBytes`, `toBase64` and `fromBase64` in `@nylorun/core/harness-api`.
51
+ - **Our harness runs the artifact tools.** `read_artifact` (every agent) and `save_artifact` (with a sandbox) are our engine's tools, defined in `@nylorun/harness` (`artifactToolsFor`, `runArtifactTool`) and run over the seam and the run's sandbox files (`HarnessExecutors.files`, `SandboxManager.writeBytes`); their calls are kind `harness`. `save_artifact` keys its write by its effect id. `read_artifact` takes `path` with a sandbox, which copies the whole artifact into it, and hands a file of any other type to the model as a file of the result (the Model Gate writes the note for one the model does not read; `artifact.unsupported` is gone). Its page is harness configuration, `createHarness({ artifactPageBytes })` (32 KiB by default), and now always ends on a whole character. `runDurable` takes `engineTools`; `apiHost` takes the engine's configuration.
52
+ - **The Runtime pins no artifact tools.** `runtimeManifestFor` has no `save` or `read`; `RUNTIME_TOOL_NAMES` no longer holds the two names, so an author tool may take one (our harness then refuses the turn). A session without a sandbox or skills pins its definition unchanged. Core no longer runs either tool (`tenant/artifact-tool.ts` is gone). Migration 0029 closes every agent session that pinned them (`closedReason: "protocol_15"`, `409 session_closed`); workflow sessions carry over.
53
+ - **Media types are core's.** `contentTypeFor`, `essence`, `normalizeContentType`, `isText`, `isModelImage`, `modelInputOf`, `inputLabel`, `extensionFor`, `unreadableReason`, `MODEL_IMAGE_TYPES` and `DEFAULT_CONTENT_TYPE` are exported from `@nylorun/core/contracts`, for the Runtime and harnesses alike.
54
+ - `PROTOCOL_VERSION` 15 with required feature `harness-boundary`; `HARNESS_API_VERSION` 4. The SDKs and the CLI send protocol 15.
55
+
56
+ - b1e815d: **Runtime limits are a Tenant setting, and harnesses get them in `turn.start.limits`.**
57
+
58
+ - What one record entry, model call, model file, tool answer, custom harness state and Harness API chunk may hold is the new Management API setting `GET`/`PUT /v1/tenant/limits` (`{ limits: { recordEntryBytes, modelCallBytes, modelFileBytes, toolAnswerBytes, harnessStateBytes, chunkBytes } }`), also `admin.settings.limits` and `nylorun tenant settings limits [get | put <file|->]`.
59
+ - The defaults are today's sizes (`RUNTIME_LIMIT_DEFAULTS`): 960 KiB, 32 MiB, 8 MiB, 8 MiB, 256 KiB and 16 MiB. A limit left out of a `PUT` takes its default.
60
+ - Each limit has a ceiling a dependency sets (`RUNTIME_LIMIT_CEILINGS`): S2's 1 MiB record less 64 KiB for the event's envelope, the 64 MiB Harness API frame, the longest JavaScript string. A limit above its ceiling is `400`, naming the ceiling.
61
+ - Each is read from the Tenant's database where it is checked; nothing keeps it.
62
+ - **The record holds every write to `recordEntryBytes`.** An event whose payload, or an effect outcome whose value, is larger, whoever wrote it, is refused with `limit_exceeded`: `413` (`details.limit: "recordEntryBytes"`) to an API client, the new Harness API error code `limit_exceeded` to a harness. A harness's claimed event past it is refused rather than dropped. Before, such an event reached a record S2 could not take.
63
+ - **The gates read the setting.** The Model Gate refuses a body past `modelCallBytes` and a file past `modelFileBytes`; the Tool Gate keeps no MCP or HTTP answer past `toolAnswerBytes` (`mcp.too-large`, `http.too-large`) and reads no tool body past it. A custom harness's state past `harnessStateBytes` fails its turn with `limit_exceeded` (it was `invalid`), and a `definition.file` range longer than `chunkBytes` is `limit_exceeded`. Core's step budget for tool results is unchanged (256 KiB), or half `recordEntryBytes` when that is less.
64
+ - **`turn.start` carries `limits`** (`RuntimeLimitsSchema`), the limits in force when the segment started. Harness API 3 and protocol 14 are unchanged, but `TurnStartSchema` is strict: a harness built against an older `@nylorun/core` refuses a `turn.start` with `limits`, so upgrade a custom harness with the Runtime. Our harness asks for skill files `limits.chunkBytes` at a time, and holds MCP answers on its own connections to `limits.toolAnswerBytes`. `createHarness` takes `onStart(grant, start)`.
65
+ - **Removed exports:** `MAX_MODEL_CALL_BYTES`, `MAX_TOOL_BODY_BYTES`, `MAX_HARNESS_STATE_BYTES` and `DEFINITION_FILE_CHUNK_BYTES` from `@nylorun/core`. Added: `RuntimeLimitsSchema`, `RUNTIME_LIMIT_DEFAULTS`, `RUNTIME_LIMIT_CEILINGS`, `runtimeLimitsOf`, `runtimeLimitIssues`, `limitExceededMessage`, `S2_RECORD_MAX_BYTES`, `RECORD_ENVELOPE_RESERVE_BYTES`, `JS_STRING_MAX_LENGTH` and the `TenantLimits*` schemas.
66
+
67
+ - f2e9b0a: **Skill and artifact limits are set per Tenant and per Environment manifest; a skill holds up to 2 GiB by default, with no limit per file or on the number of files.**
68
+
69
+ - The 10 MiB limit per skill file and the 500-file limit are gone. A skill's files may hold up to the Tenant's skill limit together: 2 GiB by default (`SKILL_TOTAL_BYTES_DEFAULT`). A file at two paths counts twice, since a sandbox holds both copies. `SKILL_FILES_MAX` and `DEFINITION_FILE_MAX_BYTES` are no longer exported.
70
+ - The Tenant's skill limit is the new Management API setting `GET`/`PUT /v1/tenant/skills` (`{ limits: { totalBytes } }`), also available as `admin.settings.skills` and `nylorun tenant settings skills [get | put <file|->]`.
71
+ - `PUT /v1/files/sha256:<hex>` takes a file up to that limit.
72
+ - `PUT /v1/agents/{id}` refuses a skill over it, an agent used as a tool included: `413 limit_exceeded`, with `details.skills` listing each skill and its size.
73
+ - An environment manifest, or the inline fields of `PUT /v1/environments/{id}`, may set `limits`: `artifacts.fileBytes`, `artifacts.totalBytes` and `skills.totalBytes`. Like the manifest's other fields, they are fixed for the Environment's life.
74
+ - Each limit must be at most the Tenant's. A higher one is refused with `400` when the Environment is made or the manifest is saved.
75
+ - A limit left out is the Tenant's at the time it is checked. A Tenant that lowers a limit lowers it for every Environment.
76
+ - The Environment view's new `limits` field gives the limits in force.
77
+ - An Environment's artifacts are its sessions' artifacts and its disk versions. Uploads, `save_artifact`, turn-end exports and disk snapshots hold them to the Environment's per-file limit and to its own total, as well as to the Tenant's total. A turn-end export past the Environment's total is skipped with the new reason `environment_total`, and a disk snapshot past it is `413` with `details.limit: "environment_total"`.
78
+ - A session opens on an Environment only when its agent's skills fit the Environment's skill limit; otherwise it is `409 environment_unsuitable`, with `details.skills`.
79
+ - `PUT /v1/files` streams the body to the Object store instead of holding it in memory. Only bytes that match the named hash reach the file's key. Environment files named by hash are held to the same per-file maximum.
80
+ - `@nylorun/agents`: loading a skills folder no longer checks a size, since the limit is the Tenant's; the Runtime refuses an oversized skill. The `skills.file-too-large` and `skills.too-many-files` errors are gone. Files are hashed and read a chunk at a time.
81
+ - Sandboxes get skill files as a stream. A harness fetches them from core 16 MiB at a time: `definition.file` takes optional `offset` and `length` (at most the Runtime limit `chunkBytes`).
82
+ - `load_skill` and `read_skill_resource` read files of up to 10 MiB into the model's context. A larger file fails with `skill.resource_too_large`, and the error names the file's path in the sandbox when there is one.
83
+
84
+ ### Patch Changes
85
+
86
+ - cf425c6: **The harness mounts skills and saves outputs; the in-process harness uses the gates; compaction is a transcript edit (protocol 15).** The fifth step of the harness boundary, still protocol 15 and Harness API 4. See MIGRATION.md.
87
+
88
+ - **Skill folders are our engine's.** Before each sandbox call our engine mounts each skill version of the turn's tree at `/skills/<name>@<hash>/` with `executors.files.mount`, reading the bytes over `definition.file`; the SandboxManager only writes them (`mountFolder`), once per open sandbox (`present` after). `SandboxManager.mountSkills`, its `definitionFile` port and `SandboxSessionRef.manifest` are gone, and the operator sandbox route mounts nothing.
89
+ - **The outputs folder is our engine's (Q5).** At a completed turn's end in a sandbox our engine saves `/workspace/outputs` as the session's `outputs` folder before `turn.completed`, over the new folder mode of `artifact.write` (`kind: "folder"`, `file`, chunks named by hash, `unchanged`, `refused`). Core takes every byte, checks each file's hash before content is stored under it, dedupes, and keeps the content epoch and quotas. Versions say `source: "engine"`; `artifact.export.skipped` and `artifact.export.failed` are harness claims. Core's export (`artifacts/export.ts`, the `WorkspaceReader`, `workspace.read` listing and bytes calls) is removed.
90
+ - **No limit literals.** The new Runtime limit `folderEntries` (10,000; a count, its ceiling from the manifest's one string) replaces `EXPORT_MAX_FILES`, and `createHarness({ outputs: { dir, maxBytes } })` (`/workspace/outputs`, 1 GiB) replaces `EXPORT_MAX_BYTES`. `RUNTIME_LIMIT_CEILINGS` entries are `{value, unit, why}`.
91
+ - **In-process parity.** Every model call goes through the Model Gate: a scripted model is served by `providerModelGate`, metered like any. The MCP pool opens every server through the Tool Gate (`openRemote` is required; the in-process gate's `openMcp` finds the server in the session's pinned manifest and authorizes it with the vault). `ModelRoute` is `{tenantId, modelGate}`; `TenantContext.modelProvider`, `useVaultModel` and `workspaces` are gone.
92
+ - **Compaction is a transcript edit (Q4).** Summary calls say `purpose: "summary"` (no `message.assistant`), and the segment's edit that replaced the history says `kind: "compaction"` with its facts and summary calls (`CompactionFactsSchema`, `transcriptUpdates(..., compaction)`). Core checks the calls and writes one `context.compacted`, which loses `partial`.
93
+
94
+ - dc75e58: **Host timings, retries and engine settings are configuration with defaults (B15).** Still protocol 15 and Harness API 4. See MIGRATION.md and DEPLOYMENT.md ("Host tuning").
95
+
96
+ - **Host tuning.** The Runtime processes' timeouts, retries, poll intervals and internal sizes are one typed schema with a default each (`HostTuningSchema`, `runtime/server/src/tuning.ts`): keys, the Harness API, the API's streams, the Host, the Object store, the Tenant, its sweep, Durable Session Execution, Restate, Postgres, Durable Streams and the relay, the gates, egress-gate, sandbox pods, harnesses and traces. An operator sets any part in `NYLORUN_TUNING` (JSON), parsed with the stack configuration and read once at start; every default is the value before. An unknown key or a value past its ceiling (Node's longest timer, S3's part sizes, S2's batch, the sandboxes service's wait) stops the process naming the key. Core hands a sandbox pod's engine the `harness` and `engine` groups the operator set. `nylorun start` passes `NYLORUN_TUNING` to the runtime, gateway and harness containers.
97
+ - **Our engine's loop is configuration.** `createHarness` takes `compaction` (`CompactionConfig`, `DEFAULT_COMPACTION_CONFIG`: the kept tail, the reply's reserve, the estimate), `partialOutputChars` (a failed agent-as-tool's output its parent sees), `resendDelaysMs` and `leaseRetryMs`; `runDurable` takes `loop` (`LoopConfig`), which an invocation hands its agents used as tools. `EngineToolConfig` is `EngineConfig`. The Runtime's harness host passes the tuning's `engine` group to `createHarness`.
98
+ - **Kept as constants**, each justified where it is defined: Node's longest timer, S3's part sizes and object key, S2's batch, the sandboxes service's longest wait and pod variable, the `environment.egress` event's 16 running turns, W3C's 512-character `tracestate`, and the 24-hour floor of a wake's dedupe key.
99
+
100
+ - 23774c4: **The last hard-coded limits are configuration (harness boundary B15c).** Still protocol 15 and Harness API 4. Every default is the value before. See MIGRATION.md, and DEPLOYMENT.md's Runtime limits and Host tuning.
101
+
102
+ - **21 more Runtime limits** (`GET`/`PUT /v1/tenant/limits`): a message's parts (`messageParts`), page sizes (`pageItems`, `exportPageItems`, `environmentEventItems`; a page asked larger holds that many), labels (`artifactLabels`, `labelKeyChars`, `labelValueChars`), a manifest's setup command, descriptions and secret hosts (`setupCommandChars`, `manifestDescriptionChars`, `secretDescriptionChars`, `secretHosts`), a failed pod's reason (`setupReasonChars`, `setupCommandExcerptChars`), secret values (`secretValueChars`), the tool policy and budgets (`toolRules`, `toolRuleFieldChars`, `toolRuleTextChars`, `modelBudgets`) and flows (`flowConcurrency`, `flowMapItems`, `flowLoopIterations`, replacing the `NYLORUN_FLOW_*` variables no Host read). Request schemas lose these maxima; the Runtime checks the Tenant's.
103
+ - **More Host tuning** (`NYLORUN_TUNING`): token lifetimes and clock tolerance (`keys.*`), the advance deadline and grace (`execution.*`), `nylorun-operate`'s waits, the credential store's lock, sweep arming, Postgres batches and the replication pool, a basin repair's log cadence, egress sockets, the engine poll and sandbox memory floor, MCP listing pages and diagnostics, sandbox helper commands, the scrub threshold, exec event and local stream sizes; and in the engine, `flowValueChars` and `toolResults.minPreviewBytes`.
104
+ - **The CLI's own waits are `NYLORUN_CLI_TUNING`**: `nylorun start`'s waits and polls, the Compose healthchecks and WAL cap, and `nylorun local sandbox`'s waits.
105
+ - **Studio follows the Runtime's limits**: no upload cap of its own, the Tenant's `requestBodyBytes` read for a write it parses past the default (`@nylorun/agents` exports `RUNTIME_LIMIT_DEFAULTS`), no CPU cap in its form.
106
+ - **Kept, each justified where it is defined**: Linux's `MAX_ARG_STRLEN` (a setup command's ceiling) and `PATH_MAX` (a link target), a model-facing tool name's 64 characters, RFC 6838's media type length, Postgres's 65,535 bind parameters, a tmpfs page, and identifier grammars (the protocol's).
107
+
108
+ - 6772612: **The remaining request, upload, token and sandbox limits are Tenant settings (harness boundary B15).** Still protocol 15 and Harness API 4. See MIGRATION.md and DEPLOYMENT.md's Runtime limits.
109
+
110
+ - **27 more Runtime limits** in `GET`/`PUT /v1/tenant/limits`, each with today's value as its default and a ceiling from a dependency (a JavaScript string or timer, a request read as one string, a Harness API frame, a JavaScript number): request bodies and inline files (`requestBodyBytes`, `inlineFileBytes`), `a2aWaitMs`, `errorExcerptChars`, `traceContentBytes`, an Environment's labels, setup and input files (`environmentLabels`, `environmentSetupCommands`, `environmentFiles`, `environmentFilesPerEntry`, `environmentSecretSlots`, `setupCommandMs`, `setupOutputChars`), disk versions (`diskVersionEntries`, `diskVersionBytes`, `diskLeaseMs`, `diskPodWaitMs`; an Environment's manifest may lower the first two with `limits.disk`), model calls (`modelRequestMs`, `modelIdleMs`, `modelAttempts`, `modelRetryDelayMs`, `modelProviderRetries`, `modelRetryDelayMaxMs`, read by the gates for each call) and tools (`toolAttempts`, `httpToolTimeoutMs`, `mcpPreviewMs`, `mcpMetadataBytes`, and the new `mcpSnapshotBytes`: what a session pins of its MCP servers' tools and instructions, past which a server is left out with a diagnostic).
111
+ - **Schema maxima are checked against the Tenant's limits**: an Environment's labels, setup commands, input files, files per entry, secret slots and setup timeout, and an HTTP tool's `timeoutMs` (at deploy and at each call). `limits.environments` and `lifecycle.stopGrace` lose their arbitrary caps; an identity file's issuer takes any number of grants and `jwksFetch` settings.
112
+ - **`turn.start.limits` carries only a harness's limits** (`HarnessLimitsSchema`, `harnessLimitsOf`), and a harness drops one it does not know. `transcriptUpdates` takes `recordEntryBytes` and fills each event up to it; `CHUNK_BYTES` is gone.
113
+ - **Constants a dependency or a standard fixes stay, named for it**: a token is read up to Node's `http.maxHeaderSize`; artifact names and folder paths keep `FILE_NAME_MAX` (255) and `FILE_PATH_MAX` (1,024); a skill file's path is what `FILE_PATH_MAX` leaves under its mount folder; `tracestate` keeps W3C's 512.
114
+ - **Removed**: `ENVIRONMENT_LABELS_MAX`, `ENVIRONMENT_SETUP_MAX`, `ENVIRONMENT_SETUP_TIMEOUT_MAX_MS` (now `ENVIRONMENT_SETUP_TIMEOUT_DEFAULT`), `ENVIRONMENT_FILES_MAX`, `ENVIRONMENT_SECRET_SLOTS_MAX`, `TOKEN_ENVIRONMENT_GRANTS_MAX`, `HTTP_TOOL_MAX_TIMEOUT_MS`, `READ_ARTIFACT_MAX_BYTES` and `CHUNK_BYTES` from `@nylorun/core`; the image checks (`decodeImageBase64`, `validateImageBytes`, `IMAGE_MEDIA_TYPES`, `MAX_IMAGE_BYTES`), the Tenant configuration's `modelCall` and `TrustedIssuersOptions`' `refetchMs`/`maxAgeMs` from `@nylorun/runtime`. Studio's Environment form no longer caps setup commands and input files at 16: the Runtime checks the Tenant's limit.
115
+
116
+ - Pin core to the tested release.
117
+ - Pin agents to the tested release.
118
+ - Pin admin to the tested release.
119
+ - Pin runtime to the tested release.
120
+ - Pin studio to the tested release.
121
+ - Updated dependencies [0a2fbc5]
122
+ - Updated dependencies [ebe7348]
123
+ - Updated dependencies [ff6470e]
124
+ - Updated dependencies [f443475]
125
+ - Updated dependencies [cf425c6]
126
+ - Updated dependencies [23774c4]
127
+ - Updated dependencies [b1e815d]
128
+ - Updated dependencies [2459430]
129
+ - Updated dependencies [f2e9b0a]
130
+ - Updated dependencies [6772612]
131
+ - Updated dependencies
132
+ - Updated dependencies
133
+ - @nylorun/core@0.23.0-beta
134
+ - @nylorun/agents@0.23.0-beta
135
+ - @nylorun/admin@0.18.0-beta
136
+
3
137
  ## 0.15.1-beta
4
138
 
5
139
  ### Patch Changes
package/README.md CHANGED
@@ -15,7 +15,7 @@ and S2, serving exactly that Tenant, and its name is the Tenant's name.
15
15
  `nylorun start` in a project creates the project's Tenant (the Runtime creates
16
16
  it on its first start) and links the project to it; anywhere else, it starts
17
17
  the Tenant `default`. Projects that must not share agents, credentials or
18
- history run separate Tenants. The `tenant` and `environments` groups act on a
18
+ history run separate Tenants. The `tenant`, `agents` and `apply` commands act on a
19
19
  Tenant over its APIs, so they work on a remote installation too
20
20
  ([below](#remote-installations)). Depends on `@nylorun/core`,
21
21
  `@nylorun/admin` and `@nylorun/agents` among Nylorun packages and never imports
@@ -50,32 +50,33 @@ nylorun studio [--tenant <name>] [--no-open] # sign a browser in to Studio on
50
50
  nylorun doctor [--json] # prerequisites and the Tenant's health
51
51
  nylorun doctor sandbox [--tenant <name>] [--json] # the sandbox backend the Tenant's Host offers
52
52
 
53
- # agents, sessions, environments, artifacts: the Runtime API (an application key, or NYLORUN_TOKEN)
53
+ # apply, agent-manifests, agents, sessions, artifacts: the Runtime API (an application key, or NYLORUN_TOKEN)
54
54
  # every one takes --tenant <name>, and --as <subject> [--scope <scope>]... to act for a person
55
- nylorun agents list [--json]
56
- nylorun agents get <id> # its manifest
57
- nylorun agents save <manifest.json|-> [--files <dir>]... [--implementation-version <v>] [--dry-run]
58
- nylorun sessions list [--agent <id>] [--status <s>] [--environment <id>] [--owner <user>] [--limit <n>] [--cursor <c>] [--json]
59
- nylorun sessions create --agent <id> --owner <user> [--environment <id>] [--id <id>] [--info <json>]
55
+ nylorun apply [<dir>...] [--dry-run] [--if-match <n>] # plan, then save each folder's agent.manifest.json, its files uploaded
56
+ nylorun migrate v8 <agent.json> [--runtime <environment-manifest.json>] [--name <name>] [--out <dir>] # the three files from a v7 manifest; reads no Runtime
57
+ nylorun agent-manifests list [--json] # name, latest version, runtime kind, harness, Agents
58
+ nylorun agent-manifests get <name>[@<n>] | versions <name> | rm <name>
59
+ nylorun agents list [--state <s>] [--manifest <name>] [--label <key=value>]... [--behind] [--limit <n>] [--cursor <c>] [--json] # --behind: on an older manifest version
60
+ nylorun agents get|stop|reset|rm|snapshot|versions <id>
61
+ nylorun agents put <id> --manifest <name[@n]> [--owner <user>] [--label <key=value>]... # name tracks its latest version, name@n pins one
62
+ nylorun agents fork <id> <new-id> [--manifest <name[@n]>] [--disk <latest|n|empty>] [--secrets <copy|none>] [--dry-run] # onto a new manifest version
63
+ nylorun agents restore <id> <version|latest>
64
+ nylorun agents delete-version <id> <version>
65
+ nylorun agents events <id> [--from <n>] [--types <type,…>] [--since <time>] [--until <time>]
66
+ nylorun agents triggers list <id> | pause|resume <id> <trigger> | run <id> <trigger> [--idempotency-key <k>] | new-secret <id> <trigger>
67
+ nylorun agents runs <id> [--trigger <id>] [--limit <n>] [--cursor <c>] # what each trigger fire came to
68
+ nylorun agents memories ls|cat|put|rm|versions <id> [<path>] [<file|->] # its memories (track T5); put seeds one
69
+ nylorun agents secrets list|get|put|rm <id> [<name>] [<secret.json|->] # put without a file: a slot's value on stdin
70
+ nylorun sessions list [--agent <id>] [--manifest <name>] [--status <s>] [--owner <user>] [--limit <n>] [--cursor <c>] [--json]
71
+ nylorun sessions create --agent <id> --owner <user> [--id <id>] [--info <json>] # a session on Agent <id>
60
72
  nylorun sessions get <id>
61
- nylorun sessions send <id> [<text>] [--data <json>] [--file <artifact>[@<version>]]... [--idempotency-key <k>]
73
+ nylorun sessions send <id> [<text>] [--data <json>] [--file <artifact>[@<version>]]... [--idempotency-key <k>] [--reject-if-busy] # queued while a turn runs
62
74
  nylorun sessions approve <id> <interaction> [--deny]
63
75
  nylorun sessions respond <id> <interaction> <json>
64
76
  nylorun sessions cancel <id> [--reason <text>]
65
77
  nylorun sessions watch <id> [--follow] [--cursor <c>] # events as JSON lines until interrupted
66
78
  nylorun sessions history|usage|calls [--tool]|trace <id> …
67
79
  nylorun sessions exec <id> [--timeout <s>] -- <command>... # bash in the session's sandbox
68
- nylorun environments list [--label <key=value>]... [--behind] [--limit <n>] [--cursor <c>] [--json] # --behind: made from an older manifest version
69
- nylorun environments get|stop|reset|delete|snapshot|versions <id>
70
- nylorun environments put <id> --manifest <name[@n]> [--label <key=value>]... # made from a manifest version; what it runs never changes
71
- nylorun environments put <id> [<inline.json|->] [--kind <virtual|pod|none>] [--label <key=value>]...
72
- nylorun environments fork <id> <new-id> [--manifest <name[@n]>] [--disk <latest|n|empty>] [--secrets <copy|none>] [--dry-run] # onto a new manifest version
73
- nylorun environments restore <id> <version|latest>
74
- nylorun environments delete-version <id> <version>
75
- nylorun environments events <id> [--from <n>] [--types <type,…>] [--since <time>] [--until <time>]
76
- nylorun environments secrets list|get|put|rm <id> [<name>] [<secret.json|->] # put without a file: a slot's value on stdin
77
- nylorun environments manifests list [--json] | get <name> [--version <n>] | versions <name> | rm <name>
78
- nylorun environments manifests save <manifest.json>... [--if-match <n>] [--dry-run] # files with "from": a folder, uploaded by hash
79
80
  nylorun artifacts list [--session <id>] [--label <key=value>]... [--limit <n>] [--cursor <c>] [--json]
80
81
  nylorun artifacts get|tree|diff|link|rm <id> …
81
82
  nylorun artifacts upload <file|-> [--name <name>] [--content-type <type>] [--session <id>] [--label <key=value>]... [--to <id>]
@@ -83,7 +84,7 @@ nylorun artifacts download <id> [--version <n>] [--output <file>]
83
84
  nylorun artifacts zip <id> [--version <n>] --output <file>
84
85
 
85
86
  # tenant: the Tenant's settings (Management API, a management key)
86
- nylorun tenant reset [--sessions|--environments|--all] [--yes] [--tenant <name>]
87
+ nylorun tenant reset [--sessions|--agents|--all] [--yes] [--tenant <name>]
87
88
  nylorun tenant keys put <id> [--management] [--tenant <name>] # create or rotate key <id>; prints it once
88
89
  nylorun tenant keys list [--tenant <name>] [--json] # id, role, when issued
89
90
  nylorun tenant keys rm <id> [--tenant <name>] # it stops working at once
@@ -92,13 +93,13 @@ nylorun tenant models catalog|providers|get [--tenant <name>] [--json] # the m
92
93
  nylorun tenant models set [--tenant <name>] # sign in to a model provider and set the Tenant's model
93
94
  nylorun tenant models set --provider <id> --model <id> [--base-url <url>] [--tenant <name>] # the same, with an API key piped in on stdin (CI)
94
95
  nylorun tenant models select <provider> [--model <id>] [--tenant <name>] # use another provider that has a credential
95
- nylorun tenant usage [--scope tenant|agent|turn] [--id <id>] [--period day|month|total] [--tenant <name>] # calls, tokens and cost (JSON)
96
+ nylorun tenant usage [--scope tenant|manifest|turn] [--id <id>] [--period day|month|total] [--tenant <name>] # calls, tokens and cost (JSON); manifest: the Agents made from agent manifest <id>
96
97
  nylorun tenant calls [--after <cursor>] [--limit <n>] [--tenant <name>] # every recorded model call as NDJSON, until caught up
97
- nylorun tenant budgets [get | put <file|->] [--tenant <name>] # the model spend caps
98
+ nylorun tenant budgets [get | put <file|->] [--tenant <name>] # the model spend caps: tenant, manifest (id: its name) or turn
98
99
  nylorun tenant tool-policy [get | put <file|->] [--tenant <name>] # the Tool Gate's rules
99
- nylorun tenant settings sandbox|artifacts [get | put <file|->] [--tenant <name>] # Environment and artifact store settings
100
- nylorun tenant coverage --agent <id> [--environment <id>] [--tenant <name>] [--json] # which secret each MCP server and HTTP tool would get
101
- nylorun tenant mcp inspect <url> [--server <name>] [--environment <id>] [--sse] [--tenant <name>] [--json]
100
+ nylorun tenant settings sandbox|artifacts|skills|limits [get | put <file|->] [--tenant <name>] # Agents' environments, artifact store and skill settings, Runtime limits
101
+ nylorun tenant coverage --agent <id> [--tenant <name>] [--json] # which secret of Agent <id>'s vault each MCP server and HTTP tool would get
102
+ nylorun tenant mcp inspect <url> [--server <name>] [--agent <id>] [--sse] [--tenant <name>] [--json]
102
103
 
103
104
  # local: the Tenants on this machine (Docker and kubectl)
104
105
  nylorun local ls [--json] # the Tenants on this machine, with their state, memory and URLs
@@ -116,10 +117,13 @@ stops the containers and keeps the volumes, so no Tenant data is lost. A command
116
117
  that moved into a group, or was removed, exits 2 naming its replacement:
117
118
  `nylorun logs`, `ls`, `delete`, `reset` and `telemetry` are under `local` (and
118
119
  `sandbox enable|disable|status`); `nylorun key` and `mcp` are under `tenant`;
119
- `nylorun sandbox ls|rm` is `nylorun environments list|delete`; `nylorun
120
- configure` is `nylorun tenant models set`. `nylorun dev`, `nylorun env` and the
121
- MCP OAuth `connect` subcommand of `nylorun tenant mcp` (protocol 10: write a key
122
- or a gateway credential as an Environment's secret instead) are gone.
120
+ `nylorun sandbox ls|rm` is `nylorun agents list|rm`; `nylorun environments` is
121
+ `nylorun agents` (protocol 16: Environments are Agents, and environment manifests
122
+ are the runtime section of an agent manifest); `nylorun agents save` is `nylorun
123
+ apply`; `nylorun configure` is `nylorun tenant models set`. `nylorun dev`,
124
+ `nylorun env` and the MCP OAuth `connect` subcommand of `nylorun tenant mcp`
125
+ (protocol 10: write a key or a gateway credential as an Agent's secret instead)
126
+ are gone.
123
127
 
124
128
  The package's second command, `nylo`, was the Runtime client until nylorun took
125
129
  its commands. For one release it names the `nylorun` command that replaced each
@@ -260,19 +264,21 @@ shows each key's id, role and when it was issued, never the keys; `nylorun
260
264
  tenant keys rm <id>` deletes one. Ids match `^[a-z][a-z0-9-]{0,31}$`; `studio`
261
265
  belongs to Studio and `bootstrap` to `NYLORUN_MANAGEMENT_KEY_FILE`, and both are
262
266
  refused. Putting an id that holds the other role is refused. Give each app server
263
- its own application key. On a local Tenant, the `tenant` and `environments`
267
+ its own application key. On a local Tenant, the `tenant` and Runtime API
264
268
  commands use the linked project's keys, or the keys `cli` and `cli-management`
265
269
  they put once and keep in `<Host root>/cli-credentials.json` (mode 0600).
266
270
 
267
271
  ## MCP servers
268
272
 
269
- An agent names its MCP servers by URL; a session gets a credential for a URL from
270
- the Environment it is opened on (`createSession({ environment })`): a secret of that
271
- Environment, a `bearer` token or a `headers` map, with `via` and an identity
272
- header when an MCP gateway holds each person's sign-in. Write it with
273
- `nylorun environments secrets put <id> <name> <secret.json|->` (the secret's JSON
273
+ An agent manifest names its MCP servers by URL, and may name the runtime
274
+ section's secret slot each one authenticates with (`credential`); a session gets
275
+ a credential for a URL from the Agent it runs on (`createSession({ agent })`): a
276
+ secret of that Agent's vault, a `bearer` token or a `headers` map, with `via` and
277
+ an identity header when an MCP gateway holds each person's sign-in. Write it with
278
+ `nylorun agents secrets put <id> <name>` (a slot's value on standard input) or
279
+ `nylorun agents secrets put <id> <name> <secret.json|->` (the secret's JSON
274
280
  comes from a file or standard input, never the command line),
275
- `client.environments.secrets.put(id, name, secret)` of `@nylorun/agents` (the
281
+ `client.agents.secrets.put(id, name, secret)` of `@nylorun/agents` (the
276
282
  Runtime API, an application key) or in Studio.
277
283
  The whole flow, with gateway recipes, is in
278
284
  [DEPLOYMENT.md](../../guides/DEPLOYMENT.md#mcp-servers-and-http-tools).
@@ -280,7 +286,7 @@ The whole flow, with gateway recipes, is in
280
286
  `nylorun tenant mcp inspect <url>` shows what a remote MCP server offers before an
281
287
  agent names it, through the Tenant's Management API
282
288
  (`POST /v1/tenant/mcp/preview`, with the management key). The Runtime connects
283
- with Environment `<id>`'s credential for `<url>` when `--environment <id>` names one
289
+ with Agent `<id>`'s credential for `<url>` when `--agent <id>` names one
284
290
  (without it, no credential is sent), lists the tools within 15 s and calls none. It
285
291
  prints a table of each tool's model name, input schema size, hints
286
292
  (`read-only`, `destructive`, `idempotent`) and description, then the tools
@@ -288,7 +294,7 @@ renamed for the model. `--server` is the server name your manifest uses (default
288
294
  the host's name, `linear` for `mcp.linear.app`); `--sse` speaks the older SSE
289
295
  transport; `--json` prints the Runtime's answer. A server that answers `401`
290
296
  needs a credential: it says so, and names the server's sign-in from its
291
- protected-resource metadata, since such a server needs a key in an Environment's
297
+ protected-resource metadata, since such a server needs a key in an Agent's
292
298
  secrets or an MCP gateway that holds each person's sign-in. A server it cannot list exits 1 with
293
299
  the reason (`mcp.unreachable` for an address the Runtime refuses).
294
300
 
@@ -382,20 +388,22 @@ on every start and writes the result to `NYLORUN_STUDIO_ANALYTICS_ID` in
382
388
 
383
389
  ## Sandboxes
384
390
 
385
- A session gets a sandbox from the Environment it is opened on
386
- (`createSession({ environment: id })`; protocol 11): an Environment has its own id
387
- (`PUT /v1/environments/{id}`, `client.environments` in `@nylorun/agents`), one
388
- sandbox and one vault of secrets, and outlives the sessions that name it. A session
389
- opened on none has no sandbox. Kind `virtual` (the default) runs on the Runtime's
390
- **virtual** backend: an emulated shell in the Runtime process, with no extra
391
- containers. It is not a VM or container boundary. Kind `pod` runs in a pod on a
392
- cluster (below).
393
-
394
- `nylorun environments list` lists the Tenant's Environments with their kind,
395
- state, sessions and labels; `nylorun environments delete <id>` deletes one, with its files
396
- and vault (refused while a turn runs in it). Neither starts a stopped Tenant
397
- (exit 3). The Tenant's limits for Environments (`limits.environments`, `idle`,
398
- resources, network) are `PUT /v1/tenant/sandbox` on the Management API.
391
+ A session gets a sandbox from the Agent it runs on (`createSession({ agent: id })`;
392
+ protocol 16): an Agent has its own id (`PUT /v1/agents/{id}`, `client.agents` in
393
+ `@nylorun/agents`), is made from a saved agent manifest, has the sandbox its
394
+ manifest's `runtime.kind` gives and one vault of secrets, and outlives its
395
+ sessions. Kind `virtual` runs on the Runtime's **virtual** backend: an emulated
396
+ shell in the Runtime process, with no extra containers. It is not a VM or
397
+ container boundary. Kind `pod` runs in a pod on a cluster (below); kind `none`
398
+ has no sandbox, and a manifest with no runtime section makes Agents of kind
399
+ `none`.
400
+
401
+ `nylorun agents list` lists the Tenant's Agents with the manifest version each
402
+ runs, its kind, state, sessions, owner and labels; `nylorun agents rm <id>`
403
+ deletes one, with its files and vault (refused while a turn runs on it). Neither
404
+ starts a stopped Tenant (exit 3). The Tenant's limits for Agents
405
+ (`limits.environments`, `idle`, resources, network) are `PUT /v1/tenant/sandbox`
406
+ on the Management API.
399
407
 
400
408
  ### Pods on a cluster (preview)
401
409
 
@@ -411,7 +419,7 @@ service to the Tenant: the one container holding the cluster credentials
411
419
  (`<Host root>/sandboxes/`). On kind under Linux, pass `--host-address 172.17.0.1`.
412
420
  `nylorun local sandbox disable` removes the service (`--delete-namespace` also deletes
413
421
  the namespace and every sandbox in it). Sessions run in a pod when their
414
- Environment has kind `pod` (`client.environments.put(id, { kind: "pod" })`).
422
+ Agent's manifest has `runtime.kind` `pod`.
415
423
 
416
424
  ## Host root
417
425
 
@@ -431,14 +439,14 @@ containers, volumes and Host root: the vault key (KEK) and all its data go with
431
439
 
432
440
  ## Remote installations
433
441
 
434
- The `agents`, `sessions`, `environments`, `artifacts` and `tenant` groups,
442
+ The `apply`, `agent-manifests`, `agents`, `sessions`, `artifacts` and `tenant` commands,
435
443
  `status` and `doctor sandbox` act on a Tenant over its APIs. Without `--tenant`, they act on the installation the
436
444
  environment names, when it names one for their API:
437
445
 
438
446
  | Variables | Acts on |
439
447
  | --- | --- |
440
448
  | `NYLORUN_RUNTIME_URL` and `NYLORUN_MANAGEMENT_KEY` | `status`, `doctor sandbox` and `tenant` (the Management API) |
441
- | `NYLORUN_RUNTIME_URL` and `NYLORUN_SERVER_KEY` | `agents`, `sessions`, `environments` and `artifacts` (the Runtime API) |
449
+ | `NYLORUN_RUNTIME_URL` and `NYLORUN_SERVER_KEY` | `apply`, `agent-manifests`, `agents`, `sessions` and `artifacts` (the Runtime API) |
442
450
  | `NYLORUN_RUNTIME_URL` and `NYLORUN_TOKEN` | the same, with an identity provider's token in place of the key: the person it names, with the scopes it grants |
443
451
 
444
452
  `NYLORUN_RUNTIME_URL` alone is an app's and names nothing, as for
@@ -459,16 +467,52 @@ sessions and to the scopes given (`--scope`, repeatable; default
459
467
  `sessions:own`). Use it to see what one person sees, or to act on their sessions
460
468
  from a terminal.
461
469
 
462
- ### Saving an agent from its manifest
470
+ ### Agent manifests: `apply`
463
471
 
464
- `nylorun agents save agent.json --files skills/` saves the agent a manifest
465
- describes, as `saveAgent` does from code. A manifest names each definition file
466
- (a skill folder's files) by the SHA-256 of its bytes, so the files under the
467
- `--files` folders are matched by content, whatever their paths; the ones the
468
- Runtime does not hold are uploaded first (`PUT /v1/files/sha256:…`). A file the
469
- manifest names but no folder holds stops the save before any request, naming
470
- where the manifest names it. `nylorun agents get <id>` prints a saved agent's
471
- manifest; the Runtime does not hand files back, so keep them with the manifest.
472
+ An agent runs from a saved **agent manifest** (protocol 16): one named, versioned
473
+ document with a harness section (instructions, tools, skills, MCP servers,
474
+ plugins) and a runtime section (kind, image, network, setup, files, secret
475
+ slots). Author it as files, one folder per agent:
476
+
477
+ ```
478
+ agents/triage/agent.manifest.json # { "manifestSchemaVersion": 8, "name": "triage",
479
+ # "harness": "./harness.manifest.json",
480
+ # "runtime": "../../shared/runtime.manifest.json" }
481
+ agents/triage/harness.manifest.json # instructions, tools, "skills": "./skills",
482
+ # "mcpServers": "./mcp.json", "plugins": ["../../plugins/github"],
483
+ # "credentials": { "linear": "linear" }, "requires": { "sandbox": "any" }
484
+ agents/triage/skills/<skill>/SKILL.md
485
+ shared/runtime.manifest.json # kind, image, "files": [{ "path": "/workspace/kit", "from": "./kit" }], secrets
486
+ ```
487
+
488
+ `nylorun apply agents/triage` composes the folder as `composeManifest` of
489
+ `@nylorun/agents` does (each path relative to the file that names it; skills,
490
+ plugins and `from` folders hashed; `credentials` set on the servers and HTTP
491
+ tools it names; `requires` checked against the runtime and left out), prints the
492
+ plan (`triage: version 2 → 3`, then each change as `section path op`, warnings
493
+ and errors) and saves it under `If-Match` set to the version it planned
494
+ against, uploading the files the Runtime does not hold (`PUT /v1/files/sha256:…`).
495
+ A manifest whose sections do not fit, or whose runtime misses what its harness
496
+ `requires`, is an error: nothing is saved and the command exits 1. `--dry-run`
497
+ prints the plans only; `--if-match <n>` saves only over version `n`.
498
+ `nylorun apply agents/` applies every subfolder with an `agent.manifest.json`;
499
+ every folder composes before anything is sent.
500
+
501
+ `nylorun agent-manifests list` shows each manifest's latest version, runtime
502
+ kind, harness and the Agents made from it; `get <name>[@<n>]` prints a version,
503
+ `versions <name>` its history and `rm <name>` deletes it (refused while an Agent
504
+ was made from it). Make an Agent from it with `nylorun agents put <id> --manifest
505
+ <name>` (tracking its latest version) or `--manifest <name>@<n>` (pinned), and
506
+ open sessions on it with `nylorun sessions create --agent <id> --owner <user>`.
507
+
508
+ `nylorun migrate v8 agent.json [--runtime box.json] [--out agents/triage]`
509
+ writes the three files from an agent manifest v7 (as `nylorun agents save` took
510
+ it) and the environment manifest v1 its sessions ran in: the environment
511
+ manifest's fields become the runtime file, its `harness` the harness file's `id`,
512
+ and v7's `requires` stays in the harness file for `apply` to check. With no
513
+ environment manifest the kind is `pod` when the agent requires one, `virtual`
514
+ when it has skills or requires a sandbox, else `none`. It overwrites no file and
515
+ prints the gaps to fix before `apply`.
472
516
 
473
517
  ### `local reset` or `tenant reset`
474
518
 
@@ -477,7 +521,7 @@ Both reset a Tenant, in different ways:
477
521
  | | `nylorun local reset` | `nylorun tenant reset` |
478
522
  | --- | --- | --- |
479
523
  | Acts on | the local Tenant on this machine, through Docker | the Tenant, local or remote, through the Management API with a management key |
480
- | Deletes | all the Tenant's data: volumes, `tenant/` and the vault key; the next `start` creates it anew, with a new id, and relinks the project | the sessions (the default), the Environments (`--environments`) or all the data (`--all`) after draining work in flight; the Tenant, its keys and the Project link are kept |
524
+ | Deletes | all the Tenant's data: volumes, `tenant/` and the vault key; the next `start` creates it anew, with a new id, and relinks the project | the sessions (the default), the Agents with their vaults, disks and sessions (`--agents`) or all the data (`--all`) after draining work in flight; the Tenant, its keys and the Project link are kept |
481
525
 
482
526
  `nylorun tenant reset --all` asks first; pass `--yes` when not in a terminal.
483
527
  `nylorun local reset` asks too, or takes `--yes`.
@@ -510,13 +554,14 @@ already has a credential, keeping its model (or `--model`) and endpoint.
510
554
 
511
555
  ### Files in, files out
512
556
 
513
- `budgets`, `tool-policy`, `settings sandbox` and `settings artifacts` are
514
- documents: `get` (the default) prints one as JSON, and `put <file>` (or `put -`
515
- for stdin) replaces the whole document with the JSON body in the file, the
516
- Management API's request body (`PUT /v1/tenant/budgets`, `/tool-policy`,
517
- `/sandbox`, `/artifacts`). The body is checked against its schema before
518
- anything is sent; one that does not parse exits 2. What `budgets`, `tool-policy`
519
- and `settings artifacts` print, `put` takes back (their `updatedAt` and
557
+ `budgets`, `tool-policy`, `settings sandbox`, `settings artifacts`,
558
+ `settings skills` and `settings limits` are documents: `get` (the default)
559
+ prints one as JSON, and `put <file>` (or `put -` for stdin) replaces the whole
560
+ document with the JSON body in the file, the Management API's request body
561
+ (`PUT /v1/tenant/budgets`, `/tool-policy`, `/sandbox`, `/artifacts`, `/skills`,
562
+ `/limits`). The body is checked against its schema before anything is sent; one
563
+ that does not parse exits 2. What `budgets`, `tool-policy`, `settings artifacts`,
564
+ `settings skills` and `settings limits` print, `put` takes back (their `updatedAt` and
520
565
  `usedBytes` are dropped), so they can be kept in a repository and applied from
521
566
  CI:
522
567
 
@@ -528,11 +573,28 @@ nylorun tenant tool-policy put tool-policy.json
528
573
  `settings sandbox get` prints the effective settings and what the Host offers;
529
574
  its `put` takes the settings alone (`limits`, `lifecycle`, `placement`).
530
575
 
576
+ `settings limits` is the Tenant's Runtime limits: the sizes, counts and
577
+ deadlines the Runtime holds what crosses it to, such as `recordEntryBytes`,
578
+ `requestBodyBytes`, `environmentLabels`, `pageItems`, `modelRequestMs` and
579
+ `httpToolTimeoutMs` (each one, with its default and ceiling, in DEPLOYMENT.md's
580
+ Runtime limits). A
581
+ limit left out of a `put` takes its default; one above its ceiling (S2's 1 MiB
582
+ record, the Harness API's 64 MiB frame, a JavaScript timer) is refused, and the
583
+ error names the ceiling.
584
+
531
585
  `nylorun tenant calls` prints each recorded model call as one JSON line, page
532
586
  after page, until it is caught up, then the cursor on stderr: pass it as
533
587
  `--after` to read only the newer calls. A call may come twice across runs;
534
588
  deduplicate by `id`.
535
589
 
590
+ ### The CLI's own waits
591
+
592
+ How long `nylorun start` waits for the stack, how often it polls, the healthchecks
593
+ it writes into the Compose file and the waits of `nylorun local sandbox` are the
594
+ CLI's tuning: a JSON object in `NYLORUN_CLI_TUNING`, each value left out keeping
595
+ its default (`{"stack":{"healthWaitMs":120000}}`). DEPLOYMENT.md ("The CLI") lists
596
+ them. The Runtime's own are `NYLORUN_TUNING`, which `nylorun start` passes on.
597
+
536
598
  ## Exit codes
537
599
 
538
600
  | Code | Meaning |
@@ -540,7 +602,7 @@ deduplicate by `id`.
540
602
  | 0 | Success |
541
603
  | 1 | Generic failure, including a missing Docker or Compose v2 |
542
604
  | 2 | Usage error (including no Tenant selected, or `local delete` without `--yes`), or a removed or moved command |
543
- | 3 | `status`: the Runtime is not answering; `tenant`, `environments`, `local sandbox`: the local Tenant is not running; `stop`/`local logs`: no Tenant yet; `local delete`: no such Tenant; `start`: a Tenant created by nylorun 0.5 (reset it) |
605
+ | 3 | `status`: the Runtime is not answering; `tenant`, `agents`, `apply`, `local sandbox`: the local Tenant is not running; `stop`/`local logs`: no Tenant yet; `local delete`: no such Tenant; `start`: a Tenant created by nylorun 0.5 (reset it) |
544
606
  | 4 | The Runtime port is held by another Host |
545
607
  | 5 | `up`/`start`/`studio`: this nylorun pins a Runtime older than the one that last ran the Tenant; update nylorun, or `start --allow-downgrade` |
546
608
  | 7 | The containers, the Tenant or Studio did not become ready (an unavailable Tenant's cause is printed) |
@@ -559,7 +621,7 @@ deduplicate by `id`.
559
621
  | Studio login expired | `nylorun studio` |
560
622
  | Which Studio is which | `nylorun local ls` lists each Tenant's Studio URL; `nylorun studio --tenant <name>` opens one signed in |
561
623
  | `Tenant … was created by nylorun 0.5` (exit 3) | `nylorun local reset --tenant <name>` (its data starts fresh) |
562
- | `tenant` or `environments`: the Tenant is not running or not open | `npx nylorun start`, then `npx nylorun status`, which shows the cause and its `repair` |
624
+ | `tenant`, `agents` or `apply`: the Tenant is not running or not open | `npx nylorun start`, then `npx nylorun status`, which shows the cause and its `repair` |
563
625
  | No management key for a remote installation | Set `NYLORUN_MANAGEMENT_KEY`; on the Runtime's machine `nylorun tenant keys put <id> --management` issues one |
564
626
  | `403 key_role_mismatch` | The key belongs to the other API: a management key for the Management API, an application key for the Runtime API |
565
627
  | Old Project link refused | `npx nylorun start` in the project |