@nylorun/runtime 0.41.0-beta → 0.42.0-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.42.0-beta
4
+
5
+ ### Minor Changes
6
+
7
+ - 2afa44d: The Runtime's primitives as its own Agent Plugins (ADR-106, D84). An `agent-folder/3` folder lists them under `plugins:` (`nylorun-memory`, `nylorun-triggers`, `nylorun-plan`, `nylorun-interactions`, `nylorun-artifacts`, `nylorun-sandbox`, which needs a computer), with no versions, and turns one of their tools off with `mcpServers.nylorun.tools.<tool>.enabled: false`. The compiler reads them as the `agent-folder/2` declarations they stand for (`memory`, `loop`, `engine.sandbox`, `engine.artifacts`, `engine.triggers`, which v3 refuses) and records them in `harness.engine.plugins`, each with its tools and the hash of its files. The engine presents their tools as the reserved server `nylorun`: the model reads `nylorun__memory` and the declared plugins' words as one text, with their skills (`memory`, `triggers`) in the catalog, served from the bundle; every effect keeps its target and `toolName`, so the record, tool policy (`kind: "runtime"` rules) and dispatch are unchanged. New: `ask` (`nylorun-interactions`, `harness.loop.ask`), a question that pauses the turn as an A2A `question`; `removeTools` takes `nylorun__<tool>`; `triggers` answers carry `now`; under `nylorun-triggers`, an agent-made trigger's run starts with a `[trigger <id> · <title> · nobody is watching]` line, and a turn a trigger started may set a one-off follow-up (`in` or `at`, `session: "this"`); the sandbox's instructions name the hosts `runtime.json` allows. `nylorun migrate folder <dir> --to 3` writes the plugins that keep an agent's tools and features, and `nylorun check --explain` names the plugin behind each. The JSON Schemas are republished as `agent-manifest/v8.4`, `harness-manifest/v1.4` and `agent-folder/v1/agent-md.4`.
8
+
9
+ ### Patch Changes
10
+
11
+ - Pin core to the tested release.
12
+ - Pin harness to the tested release.
13
+ - Updated dependencies [2afa44d]
14
+ - Updated dependencies
15
+ - @nylorun/core@0.36.0-beta
16
+ - @nylorun/harness@0.33.0-beta
17
+
3
18
  ## 0.41.0-beta
4
19
 
5
20
  ### Minor Changes
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.2.0",
3
3
  "info": {
4
4
  "title": "Nylorun Management API",
5
- "version": "0.41.0-beta",
5
+ "version": "0.42.0-beta",
6
6
  "x-nylorun-protocol": {
7
7
  "min": 16,
8
8
  "max": 18,
package/dist/openapi.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "openapi": "3.2.0",
3
3
  "info": {
4
4
  "title": "Nylorun Runtime API",
5
- "version": "0.41.0-beta",
5
+ "version": "0.42.0-beta",
6
6
  "x-nylorun-protocol": {
7
7
  "min": 16,
8
8
  "max": 18,
@@ -8726,6 +8726,50 @@
8726
8726
  "additionalProperties": false
8727
8727
  },
8728
8728
  "description": "The engine text blocks the agent gets, with their hashes"
8729
+ },
8730
+ "plugins": {
8731
+ "type": "array",
8732
+ "items": {
8733
+ "type": "object",
8734
+ "properties": {
8735
+ "name": {
8736
+ "type": "string",
8737
+ "enum": [
8738
+ "nylorun-memory",
8739
+ "nylorun-triggers",
8740
+ "nylorun-plan",
8741
+ "nylorun-interactions",
8742
+ "nylorun-artifacts",
8743
+ "nylorun-sandbox"
8744
+ ]
8745
+ },
8746
+ "tools": {
8747
+ "type": "array",
8748
+ "items": {
8749
+ "type": "string",
8750
+ "minLength": 1
8751
+ }
8752
+ },
8753
+ "sha256": {
8754
+ "type": "string",
8755
+ "pattern": "^sha256:[0-9a-f]{64}$"
8756
+ },
8757
+ "hosts": {
8758
+ "type": "array",
8759
+ "items": {
8760
+ "type": "string",
8761
+ "minLength": 1
8762
+ }
8763
+ }
8764
+ },
8765
+ "required": [
8766
+ "name",
8767
+ "tools",
8768
+ "sha256"
8769
+ ],
8770
+ "additionalProperties": false
8771
+ },
8772
+ "description": "The Runtime's plugins the agent declares (agent-folder/3, ADR-106): each with the tools left on and the hash of its files"
8729
8773
  }
8730
8774
  },
8731
8775
  "additionalProperties": false
@@ -45,6 +45,14 @@ function reaches(row, sessionId) {
45
45
  return false;
46
46
  return row.createdSessionId === sessionId || row.definition?.session === sessionId;
47
47
  }
48
+ /** Whether the version session `s` runs declares the Runtime's `nylorun-triggers` plugin (ADR-106). */
49
+ async function declaresTriggersPlugin(t, s) {
50
+ if (!s.definition)
51
+ return false;
52
+ const body = (await t.agentManifest(s.definition.name, s.definition.version))?.body;
53
+ const plugins = body?.harness?.engine?.plugins;
54
+ return Array.isArray(plugins) && plugins.some((plugin) => plugin?.name === "nylorun-triggers");
55
+ }
48
56
  /** Whether the version session `s` runs declares `harness.engine.triggers`. */
49
57
  async function declaresTriggers(t, s) {
50
58
  if (!s.definition)
@@ -86,6 +94,7 @@ export async function serveTriggersTool(t, s, request) {
86
94
  if (input.command === "list") {
87
95
  const rows = (await t.agentTriggers(s.agentId)).filter((row) => reaches(row, s.id));
88
96
  return completed({
97
+ now: new Date().toISOString(),
89
98
  triggers: rows.map((row) => {
90
99
  const trigger = row.definition;
91
100
  return {
@@ -109,9 +118,17 @@ export async function serveTriggersTool(t, s, request) {
109
118
  await t.agentEvent(s.agentId, "agent.trigger_deleted", { triggerId: input.id, sessionId: s.id });
110
119
  return completed({ id: input.id, deleted: true });
111
120
  }
112
- // create: never from a turn a trigger or a booked wake started.
113
- if (s.turnCause !== undefined)
114
- return failed("tool.forbidden", "A run can't create triggers: this turn was started by a trigger. It may list and delete them.");
121
+ // create: never from a turn a trigger or a booked wake started. Under the `nylorun-triggers`
122
+ // plugin (ADR-106) such a turn may still set a one-off follow-up in its own session, as a woken
123
+ // turn books the next wake: never a schedule, never a session of its own.
124
+ if (s.turnCause !== undefined) {
125
+ const plugin = await declaresTriggersPlugin(t, s);
126
+ const followUp = plugin && input.schedule === undefined && input.session === "this";
127
+ if (!followUp)
128
+ return failed("tool.forbidden", plugin
129
+ ? "A run can't create triggers other than a one-off follow-up here (in or at, with session: this): this turn was started by a trigger. It may list and delete them."
130
+ : "A run can't create triggers: this turn was started by a trigger. It may list and delete them.");
131
+ }
115
132
  const now = new Date();
116
133
  const stamp = now.toISOString();
117
134
  const session = triggerSessionOf(s.id, input.id, input.session);
@@ -175,5 +192,5 @@ export async function serveTriggersTool(t, s, request) {
175
192
  ...(row.title === null ? {} : { title: row.title }),
176
193
  nextRunAt: row.nextFireAt,
177
194
  });
178
- return completed({ id: input.id, status: row.status, nextRunAt: row.nextFireAt, session }, [row]);
195
+ return completed({ id: input.id, status: row.status, nextRunAt: row.nextFireAt, session, now: stamp }, [row]);
179
196
  }
@@ -31,6 +31,11 @@ export declare function nextFireAt(agentId: string, triggerId: string, trigger:
31
31
  export declare function triggerIssues(triggers: Readonly<Record<string, Trigger>> | undefined, limits: RuntimeLimits, now?: Date,
32
32
  /** How an issue names trigger `id`: its place in the manifest by default. */
33
33
  label?: (id: string) => string): string[];
34
+ /**
35
+ * The line an agent-made trigger's run starts with under the `nylorun-triggers` plugin (ADR-106):
36
+ * which trigger woke the turn, and that nobody is watching.
37
+ */
38
+ export declare function triggerFrame(triggerId: string, title: string | null | undefined): string;
34
39
  /** Where a row's definition comes from (D83): its origin, or `wake` for a booked wake written before origins. */
35
40
  export declare function originOf(row: Pick<AgentTriggerRow, "origin" | "kind">): AgentTriggerRow["origin"];
36
41
  /**
@@ -152,7 +152,20 @@ async function triggersOf(t, agent) {
152
152
  async function pinnedOf(t, agent) {
153
153
  const body = (await t.agentManifest(agent.manifestName, agent.manifestVersion))?.body;
154
154
  const harness = body?.harness;
155
- return { triggers: (body?.runtime?.triggers ?? {}), declared: harness?.engine?.triggers === true };
155
+ const plugins = harness?.engine?.plugins;
156
+ return {
157
+ triggers: (body?.runtime?.triggers ?? {}),
158
+ declared: harness?.engine?.triggers === true,
159
+ // The version declares the Runtime's `nylorun-triggers` plugin (ADR-106).
160
+ plugin: Array.isArray(plugins) && plugins.some((item) => item?.name === "nylorun-triggers"),
161
+ };
162
+ }
163
+ /**
164
+ * The line an agent-made trigger's run starts with under the `nylorun-triggers` plugin (ADR-106):
165
+ * which trigger woke the turn, and that nobody is watching.
166
+ */
167
+ export function triggerFrame(triggerId, title) {
168
+ return `[trigger ${triggerId}${title ? ` · ${title}` : ""} · nobody is watching]`;
156
169
  }
157
170
  /** Where a row's definition comes from (D83): its origin, or `wake` for a booked wake written before origins. */
158
171
  export function originOf(row) {
@@ -431,7 +444,9 @@ export async function deliverRun(ctx, t, agent, triggerId, trigger, row, cause)
431
444
  title: row.title ?? null,
432
445
  streamedAt: null,
433
446
  };
434
- const outcome = await runOutcome(ctx, t, agent, triggerId, trigger, row.kind, id, firedAt, cause.payload, row.createdSessionId ?? null);
447
+ // Under the `nylorun-triggers` plugin, an agent-made trigger's run is framed (ADR-106).
448
+ const framed = origin === "agent" && (await pinnedOf(t, agent)).plugin ? { ...trigger, prompt: `${triggerFrame(triggerId, row.title)}\n${trigger.prompt}` } : trigger;
449
+ const outcome = await runOutcome(ctx, t, agent, triggerId, framed, row.kind, id, firedAt, cause.payload, row.createdSessionId ?? null);
435
450
  Object.assign(run, outcome);
436
451
  await t.insertTriggerRun(run);
437
452
  await t.agentEvent(agent.id, "agent.run", {
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const RUNTIME_VERSION = "0.41.0-beta";
1
+ export declare const RUNTIME_VERSION = "0.42.0-beta";
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  // Kept in step with package.json by runtime/server/scripts/check-package.mjs, which runs in npm run check.
2
2
  // release:prepare also rewrites this when it bumps @nylorun/runtime.
3
- export const RUNTIME_VERSION = "0.41.0-beta";
3
+ export const RUNTIME_VERSION = "0.42.0-beta";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nylorun/runtime",
3
- "version": "0.41.0-beta",
3
+ "version": "0.42.0-beta",
4
4
  "description": "Nylorun Runtime: the agent execution Host on Postgres, Restate and S2, and model providers.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -65,8 +65,8 @@
65
65
  "@hono/node-server": "^2.1.5",
66
66
  "@hono/zod-openapi": "^1.6.3",
67
67
  "@modelcontextprotocol/sdk": "^1.32.1",
68
- "@nylorun/core": "0.35.0-beta",
69
- "@nylorun/harness": "0.32.0-beta",
68
+ "@nylorun/core": "0.36.0-beta",
69
+ "@nylorun/harness": "0.33.0-beta",
70
70
  "@restatedev/restate-sdk": "1.17.3",
71
71
  "@restatedev/restate-sdk-clients": "1.17.3",
72
72
  "@s2-dev/streamstore": "0.28.0",