@nylorun/runtime 0.3.0-beta → 0.5.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 +31 -0
- package/README.md +53 -20
- package/dist/adapters/media.d.ts +2 -18
- package/dist/adapters/media.js +2 -52
- package/dist/adapters/observe.js +1 -1
- package/dist/cli.js +11 -6
- package/dist/config.d.ts +17 -10
- package/dist/contracts.d.ts +3 -166
- package/dist/dev-entry.d.ts +1 -0
- package/dist/dev-entry.js +2 -0
- package/dist/dev.js +6 -1
- package/dist/environment.d.ts +2 -0
- package/dist/environment.js +64 -0
- package/dist/index.d.ts +8 -8
- package/dist/index.js +5 -5
- package/dist/launcher.d.ts +1 -0
- package/dist/launcher.js +33 -0
- package/dist/media.d.ts +29 -0
- package/dist/media.js +53 -0
- package/dist/model/auth-store.d.ts +2 -1
- package/dist/model/auth-store.js +9 -2
- package/dist/model/configure.js +60 -30
- package/dist/model/defaults.d.ts +17 -0
- package/dist/model/defaults.js +21 -0
- package/dist/model/http-model.d.ts +12 -0
- package/dist/model/http-model.js +299 -0
- package/dist/model/models.d.ts +2 -2
- package/dist/model/models.js +24 -3
- package/dist/model/pi-model.d.ts +2 -1
- package/dist/model/pi-model.js +53 -8
- package/dist/model/settings.js +35 -13
- package/dist/node/index.d.ts +5 -0
- package/dist/node/index.js +5 -0
- package/dist/node/local-sessions.d.ts +5 -0
- package/dist/node/local-sessions.js +157 -0
- package/dist/redact.d.ts +1 -0
- package/dist/redact.js +14 -0
- package/dist/server/ag-ui.d.ts +1 -1
- package/dist/server/delivery.d.ts +24 -0
- package/dist/server/delivery.js +107 -0
- package/dist/server/host.d.ts +11 -6
- package/dist/server/host.js +236 -305
- package/dist/sessions/host.d.ts +29 -0
- package/dist/sessions/host.js +291 -0
- package/dist/sessions/store.d.ts +40 -0
- package/dist/sessions/store.js +30 -0
- package/package.json +11 -4
- package/dist/adapters/journal.d.ts +0 -35
- package/dist/adapters/journal.js +0 -130
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.0-beta
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Breaking beta: Runtime hosts use Harness `info` (`getInfo` / `SubmitOptions.info`) instead of
|
|
8
|
+
`scope`. Session scheduling stays in Runtime; Node-only adapters remain under
|
|
9
|
+
`@nylorun/runtime/node`. Compatible with Harness capability manifests and ToolDescriptor-only
|
|
10
|
+
model requests.
|
|
11
|
+
- c5bbb1a: Breaking beta: make Harness `run()` a direct async state-in/state-out executor with
|
|
12
|
+
serializable pauses, application `info`, cancellation signals, awaited recording, and
|
|
13
|
+
agent-level output schemas. Runtime owns session scheduling with memory-default or exclusive
|
|
14
|
+
local storage and imports Harness contracts. Isolate Node adapters under `runtime/node`, stream
|
|
15
|
+
observations incrementally, and add opt-in bounded token previews with Studio reconciliation.
|
|
16
|
+
Migrate consumers and deployment guidance together; legacy event records remain archived, not
|
|
17
|
+
automatically replayed.
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Ignore Hono Node `context.env` stream bindings (`incoming`/`outgoing`) when
|
|
22
|
+
resolving model environment so Node `nylorun dev` uses process `.env` /
|
|
23
|
+
`piModel` instead of an empty portable HTTP adapter.
|
|
24
|
+
- Update Runtime's canonical Harness dependency to the tested release.
|
|
25
|
+
- Updated dependencies [c5bbb1a]
|
|
26
|
+
- @nylorun/harness@0.13.0-beta
|
|
27
|
+
|
|
28
|
+
## 0.4.0-beta
|
|
29
|
+
|
|
30
|
+
### Minor Changes
|
|
31
|
+
|
|
32
|
+
- fa1860a: Use standard MODEL_PROVIDER, MODEL, MODEL_PROVIDER_API_KEY, and MODEL_PROVIDER_BASE_URL environment configuration. Export starter Hono apps and provide CLI development and production Node launchers. Existing starters require manual migration. Release preparation must update the creator Runtime compatibility pin with this release.
|
|
33
|
+
|
|
3
34
|
## 0.3.0-beta
|
|
4
35
|
|
|
5
36
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1,46 +1,79 @@
|
|
|
1
1
|
# @nylorun/runtime
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Optional hosting for stateless Harness agents: session coordination, replaceable storage, Hono routes, model adapters, and the Node CLI. Runtime depends directly on canonical Harness types; Harness does not depend on Runtime.
|
|
4
4
|
|
|
5
5
|
```ts
|
|
6
|
+
import { Hono } from "hono";
|
|
6
7
|
import { Runtime, serveAgents } from "@nylorun/runtime";
|
|
7
|
-
|
|
8
8
|
const runtime = new Runtime();
|
|
9
|
-
app
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
const app = new Hono();
|
|
10
|
+
app.route("/agents", serveAgents({ agents, runtime }));
|
|
11
|
+
export default app;
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The default is `memorySessions()` and no file observer. Portable imports do not initialize the filesystem. `httpModel()` supports text/tool/structured-output requests to OpenAI-compatible and Anthropic HTTP endpoints using injected environment values or process variables where available. It requires API keys; media inputs require a supplied media-aware adapter. The Node CLI installs `piModel()` for its broader provider catalog, local credential fallback, OAuth, and media support. Direct portable imports do not load dotenv or local credentials.
|
|
15
|
+
|
|
16
|
+
## Storage and coordination
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import { localSessions, piModel } from "@nylorun/runtime/node";
|
|
20
|
+
const runtime = new Runtime({
|
|
21
|
+
sessions: localSessions({ root: ".data/sessions" }),
|
|
22
|
+
onModelCall: piModel(),
|
|
23
|
+
});
|
|
13
24
|
```
|
|
14
25
|
|
|
15
|
-
`
|
|
26
|
+
A `SessionStore` provides `get(agentId, sessionId)`, atomic `put(agentId, sessionId, document)`, and `list(agentId)`. StoredSession includes Runtime metadata, Harness state, an active marker, and committed event history. Stores implement data operations only. The built-in SessionHost serializes inputs, cancels and awaits active work before replacement, persists accepted inputs before execution, and commits terminal state before reporting success. It restores completed and explicitly paused sessions; active markers found after a crash require reconciliation. Legacy event-only records remain archived history.
|
|
27
|
+
|
|
28
|
+
`localSessions` exclusively owns its root through `.owner.lock`. Multiple owners are rejected, including adapters in the same process. Writes use temporary files and atomic replacement; lost ownership stops writes. Orderly `runtime.close()` releases the matching lock. Locks are never stolen by age or PID: after a crash, confirm the owner stopped before manually removing the lock. No shared-filesystem or multi-replica guarantee is made.
|
|
29
|
+
|
|
30
|
+
The host's scheduling scope is one process. A shared store is not a distributed scheduler. Advanced applications can use `SessionHost` without Hono, reuse `agUiEvents()` protocol translation, or compose Harness with their own host. Managed Cloud Runtime remains future work.
|
|
16
31
|
|
|
17
|
-
|
|
32
|
+
## Info, delivery, and resources
|
|
18
33
|
|
|
19
|
-
Runtime
|
|
20
|
-
mount from each request URL (so a separate consumer `hono` install still works).
|
|
21
|
-
Mount at `/agents` or `/api/agents` without repeating that path in `serveAgents`.
|
|
22
|
-
Pass explicit `basePath` when a reverse proxy rewrites the public prefix.
|
|
34
|
+
Application middleware authorizes every route. `getInfo(context)` supplies extra application data for each invocation; Runtime adds `sessionId`. `getEnvironment(context)` can supply per-request provider bindings without changing process globals. Neither info nor live resources are implicitly model-visible. `getActor` remains a convenience for userId; use `getInfo` for typed application identity.
|
|
23
35
|
|
|
24
|
-
|
|
36
|
+
Runtime delivers ordered observations incrementally, separately from committed history. `tokens: true` enables provisional text previews on compatible model adapters; the default is off. `createModel({ environment, media, onPreview })` supplies preview support for custom adapters. Studio shows drafts separately and discards them on settlement; accepted output remains authoritative. Partial tool arguments never dispatch tools.
|
|
25
37
|
|
|
26
|
-
|
|
38
|
+
Delivery limits default to 64 KiB of preview data per model invocation (also bounding queued previews), and 256 events or 1 MiB of queued execution/control data. Configure them with `delivery: { previewBytes, eventCount, eventBytes }`. Preview overflow suppresses further previews for that model invocation and emits an incomplete marker. Authoritative overflow closes the subscription. Neither path blocks model consumption; request-attached execution is cooperatively cancelled on disconnect. Independent execution/reconnection belongs to a custom host.
|
|
39
|
+
|
|
40
|
+
Runtime owns controllers and its store lifecycle. It does not close application tools, databases, browsers, or subprocesses. The Node launcher drains registered Runtime hosts during orderly shutdown; application resource cleanup remains explicit. Imports never open a listening socket. Root-relative discovery supports ordinary Hono mounts; use `basePath` for a rewriting proxy. Production authentication, CORS, ingress timeouts, and TLS belong to the application and infrastructure.
|
|
27
41
|
|
|
28
42
|
## Commands
|
|
29
43
|
|
|
30
44
|
- `nylorun configure`
|
|
31
45
|
- `nylorun dev [--no-studio] [--no-open]`
|
|
46
|
+
- `nylorun start [entry]` (default: `dist/src/index.js`)
|
|
32
47
|
- `nylorun studio --agent-url http://localhost:3000/agents [--port 4161] [--no-open]`
|
|
33
48
|
|
|
34
|
-
|
|
49
|
+
Export your Hono application with `export default app`. The CLI supplies the Node server adapter. `nylorun dev` watches `src/index.ts`, waits for `/agents/v1/agents`, and starts project-local Studio. `PORT` defaults to 3000. `--no-studio` runs only the application; `--no-open` keeps the browser closed. Ctrl-C stops both processes. `nylorun start` serves the built app without Studio or development CORS.
|
|
50
|
+
|
|
51
|
+
### Environment configuration
|
|
35
52
|
|
|
36
|
-
|
|
53
|
+
Copy `.env.example` to `.env` and fill it in, or run `nylorun configure` before your agent graph is importable:
|
|
54
|
+
|
|
55
|
+
```dotenv
|
|
56
|
+
MODEL_PROVIDER=custom
|
|
57
|
+
MODEL=your-model-id
|
|
58
|
+
MODEL_PROVIDER_API_KEY=your-key
|
|
59
|
+
MODEL_PROVIDER_BASE_URL=https://your-provider.example/v1
|
|
60
|
+
```
|
|
37
61
|
|
|
38
|
-
`
|
|
62
|
+
`MODEL_PROVIDER_BASE_URL` is required only for `MODEL_PROVIDER=custom`; omit it for built-in providers. `configure`, `dev`, and `start` load `.env` before importing the app. Existing process variables win; a missing `.env` is valid. `.env.local` is ignored by Git but is not automatically loaded. Direct imports of Runtime do not load dotenv files.
|
|
63
|
+
|
|
64
|
+
Explicit `piModel({ selection })` options take precedence over environment selection. Environment selection takes precedence over legacy files; incomplete selection produces an error. `MODEL_PROVIDER_API_KEY` overrides provider-native variables such as `OPENAI_API_KEY` and `ANTHROPIC_API_KEY`, which override stored credentials. API-key deployments require no credential files. Supply the same variables through your hosting provider's environment settings.
|
|
65
|
+
|
|
66
|
+
The optional wizard writes selection and entered API keys to `.env`, preserving unrelated configuration. It reuses environment credentials without copying them into the file. OAuth is an alternative where supported; its credentials and refresh state live in ignored `.nylorun/auth.json`. Keep `.env` and `.nylorun/` private.
|
|
39
67
|
|
|
40
68
|
### Upgrading an existing starter
|
|
41
69
|
|
|
42
|
-
|
|
70
|
+
Migration is manual; the CLI will not replace a legacy `.env` directory.
|
|
71
|
+
|
|
72
|
+
1. Back up the existing `.env/` directory to a private location outside the project before replacing it with a file. Preserve any `config/model.json` too.
|
|
73
|
+
2. Translate `model.json` fields `provider`, `model`, and `custom.baseUrl` into `MODEL_PROVIDER`, `MODEL`, and `MODEL_PROVIDER_BASE_URL`. Copy API keys into `MODEL_PROVIDER_API_KEY` or provider-native variables. Replace the old `NYLO_CUSTOM_API_KEY` variable with `MODEL_PROVIDER_API_KEY`.
|
|
74
|
+
3. Merge `integrations.env` variables into `.env`. Move OAuth records into `.nylorun/auth.json`. Add `.env`, `.env.local`, and `.nylorun/` to `.gitignore`; remove the old `.env/` exceptions.
|
|
75
|
+
4. Replace the entrypoint's `serve(...)` call and Node adapter import with `export default app`. Set scripts to `"dev": "nylorun dev"` and `"start": "nylorun start"`. Remove the application's `@hono/node-server` dependency if unused elsewhere. Keep your build and asset-copy steps.
|
|
43
76
|
|
|
44
|
-
|
|
77
|
+
Runtime retains legacy `.env/model.json`, `config/model.json`, and `.env/auth.json` reads for existing applications using their own launcher. It does not automatically move or delete these files. Use the matching Runtime release pinned by the new creator; older releases cannot launch an exported app.
|
|
45
78
|
|
|
46
|
-
The
|
|
79
|
+
The exported app follows Hono composition conventions. See [deployment verification and limits](../DEPLOYMENT.md) and the [breaking migration guide](../MIGRATION.md). Node-only `projectAsset()` resolves bundled assets from source or compiled deployments.
|
package/dist/adapters/media.d.ts
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
export interface MediaAsset {
|
|
4
|
-
readonly id: string;
|
|
5
|
-
readonly mediaType: string;
|
|
6
|
-
readonly bytes: number;
|
|
7
|
-
readonly kind: "input" | "generated";
|
|
8
|
-
}
|
|
9
|
-
/** Opaque reference retained by Harness and resolved by the configured media adapter. */
|
|
10
|
-
export interface MediaReference {
|
|
11
|
-
readonly agentId: string;
|
|
12
|
-
readonly assetId: string;
|
|
13
|
-
}
|
|
1
|
+
import { type MediaAsset, type MediaReference } from "../media.js";
|
|
2
|
+
export * from "../media.js";
|
|
14
3
|
/** Explicit local asset store; agents receive only opaque references. */
|
|
15
4
|
export declare class MediaStore {
|
|
16
5
|
private readonly root;
|
|
@@ -30,11 +19,6 @@ export declare class MediaStore {
|
|
|
30
19
|
private readMetadata;
|
|
31
20
|
private directory;
|
|
32
21
|
}
|
|
33
|
-
/** Decode one canonical base64 image before it is persisted or sent to a provider. */
|
|
34
|
-
export declare function decodeImageBase64(mediaType: string, base64: string): Uint8Array;
|
|
35
|
-
/** Verify the asserted media type and lightweight file signature for a supported image. */
|
|
36
|
-
export declare function validateImageBytes(mediaType: string, bytes: Uint8Array): void;
|
|
37
22
|
export declare function localMedia(options?: {
|
|
38
23
|
root?: string;
|
|
39
24
|
}): MediaStore;
|
|
40
|
-
export type RuntimeMedia = Pick<MediaStore, "saveInput" | "saveGenerated" | "dataUrl" | "latestInput" | "read">;
|
package/dist/adapters/media.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import { mkdir, readFile, readdir, writeFile } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
"image/png",
|
|
7
|
-
"image/webp",
|
|
8
|
-
]);
|
|
9
|
-
export const MAX_IMAGE_BYTES = 8 * 1024 * 1024;
|
|
4
|
+
import { IMAGE_MEDIA_TYPES, MAX_IMAGE_BYTES, decodeImageBase64, validateImageBytes, } from "../media.js";
|
|
5
|
+
export * from "../media.js";
|
|
10
6
|
/** Explicit local asset store; agents receive only opaque references. */
|
|
11
7
|
export class MediaStore {
|
|
12
8
|
root;
|
|
@@ -91,52 +87,6 @@ export class MediaStore {
|
|
|
91
87
|
}
|
|
92
88
|
}
|
|
93
89
|
/** Decode one canonical base64 image before it is persisted or sent to a provider. */
|
|
94
|
-
export function decodeImageBase64(mediaType, base64) {
|
|
95
|
-
if (!IMAGE_MEDIA_TYPES.includes(mediaType))
|
|
96
|
-
throw new Error("Only JPEG, PNG, and WebP images are supported.");
|
|
97
|
-
if (typeof base64 !== "string" || base64 === "")
|
|
98
|
-
throw new Error("Image data is required.");
|
|
99
|
-
if (base64.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/u.test(base64))
|
|
100
|
-
throw new Error("Image data must be canonical base64.");
|
|
101
|
-
const bytes = Buffer.from(base64, "base64");
|
|
102
|
-
if (bytes.toString("base64") !== base64)
|
|
103
|
-
throw new Error("Image data must be canonical base64.");
|
|
104
|
-
validateImageBytes(mediaType, bytes);
|
|
105
|
-
return bytes;
|
|
106
|
-
}
|
|
107
|
-
/** Verify the asserted media type and lightweight file signature for a supported image. */
|
|
108
|
-
export function validateImageBytes(mediaType, bytes) {
|
|
109
|
-
if (!IMAGE_MEDIA_TYPES.includes(mediaType))
|
|
110
|
-
throw new Error("Only JPEG, PNG, and WebP images are supported.");
|
|
111
|
-
if (bytes.byteLength === 0 || bytes.byteLength > MAX_IMAGE_BYTES)
|
|
112
|
-
throw new Error("Images must be no larger than 8 MiB.");
|
|
113
|
-
const signature = mediaType === "image/jpeg"
|
|
114
|
-
? bytes.byteLength >= 3 &&
|
|
115
|
-
bytes[0] === 0xff &&
|
|
116
|
-
bytes[1] === 0xd8 &&
|
|
117
|
-
bytes[2] === 0xff
|
|
118
|
-
: mediaType === "image/png"
|
|
119
|
-
? bytes.byteLength >= 8 &&
|
|
120
|
-
bytes[0] === 0x89 &&
|
|
121
|
-
bytes[1] === 0x50 &&
|
|
122
|
-
bytes[2] === 0x4e &&
|
|
123
|
-
bytes[3] === 0x47 &&
|
|
124
|
-
bytes[4] === 0x0d &&
|
|
125
|
-
bytes[5] === 0x0a &&
|
|
126
|
-
bytes[6] === 0x1a &&
|
|
127
|
-
bytes[7] === 0x0a
|
|
128
|
-
: bytes.byteLength >= 12 &&
|
|
129
|
-
bytes[0] === 0x52 &&
|
|
130
|
-
bytes[1] === 0x49 &&
|
|
131
|
-
bytes[2] === 0x46 &&
|
|
132
|
-
bytes[3] === 0x46 &&
|
|
133
|
-
bytes[8] === 0x57 &&
|
|
134
|
-
bytes[9] === 0x45 &&
|
|
135
|
-
bytes[10] === 0x42 &&
|
|
136
|
-
bytes[11] === 0x50;
|
|
137
|
-
if (!signature)
|
|
138
|
-
throw new Error(`Image bytes do not match ${mediaType}.`);
|
|
139
|
-
}
|
|
140
90
|
function validAsset(value) {
|
|
141
91
|
if (!value || typeof value !== "object")
|
|
142
92
|
return false;
|
package/dist/adapters/observe.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { appendFile, mkdir } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { scrub } from "
|
|
3
|
+
import { scrub } from "../redact.js";
|
|
4
4
|
import { projectSecrets } from "../model/settings.js";
|
|
5
5
|
/** Local JSONL observer. Writes raw engine events beside session durability files. */
|
|
6
6
|
export function jsonlObserver(options) {
|
package/dist/cli.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { existsSync } from "node:fs";
|
|
3
|
-
import { loadEnvFile } from "node:process";
|
|
4
2
|
import { join } from "node:path";
|
|
5
3
|
import { pathToFileURL } from "node:url";
|
|
6
4
|
import { createRequire } from "node:module";
|
|
7
5
|
import { ConfigurationCancelled, configureProvider, } from "./model/configure.js";
|
|
6
|
+
import { loadProjectEnvironment } from "./environment.js";
|
|
8
7
|
import { develop } from "./dev.js";
|
|
9
|
-
const usage = `nylorun <configure|dev|studio>
|
|
8
|
+
const usage = `nylorun <configure|dev|start|studio>
|
|
10
9
|
dev [--no-studio] [--no-open]
|
|
10
|
+
start [entry]
|
|
11
11
|
configure
|
|
12
12
|
studio --agent-url <http(s)-url> [--port <n>] [--no-open]`;
|
|
13
13
|
async function startStudio(agentServerUrl, open, port) {
|
|
@@ -37,6 +37,14 @@ async function main() {
|
|
|
37
37
|
const [command, ...args] = process.argv.slice(2);
|
|
38
38
|
if (!command || command === "--help" || command === "-h")
|
|
39
39
|
return void console.log(usage);
|
|
40
|
+
if (["configure", "dev", "start"].includes(command))
|
|
41
|
+
loadProjectEnvironment();
|
|
42
|
+
if (command === "start") {
|
|
43
|
+
if (args.length > 1 || args[0]?.startsWith("--"))
|
|
44
|
+
throw new Error(usage);
|
|
45
|
+
await (await import("./launcher.js")).start(args[0]);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
40
48
|
if (command === "dev") {
|
|
41
49
|
process.exitCode = await develop(args);
|
|
42
50
|
return;
|
|
@@ -48,9 +56,6 @@ async function main() {
|
|
|
48
56
|
const cancel = (signal) => controller.abort(new ConfigurationCancelled(signal));
|
|
49
57
|
process.once("SIGINT", () => cancel("SIGINT"));
|
|
50
58
|
process.once("SIGTERM", () => cancel("SIGTERM"));
|
|
51
|
-
const integrations = join(process.cwd(), ".env", "integrations.env");
|
|
52
|
-
if (existsSync(integrations))
|
|
53
|
-
loadEnvFile(integrations);
|
|
54
59
|
await configureProvider({ signal: controller.signal });
|
|
55
60
|
return;
|
|
56
61
|
}
|
package/dist/config.d.ts
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type { RuntimeMedia } from "./
|
|
1
|
+
import type { ModelAdapter } from "@nylorun/harness";
|
|
2
|
+
import type { SessionStore } from "./sessions/store.js";
|
|
3
|
+
import type { RuntimeMedia } from "./media.js";
|
|
4
|
+
import type { ModelEnvironment } from "./model/http-model.js";
|
|
4
5
|
export interface RuntimeConfig {
|
|
5
|
-
readonly onModelCall?:
|
|
6
|
-
readonly
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
readonly durability?: RuntimeDurability;
|
|
6
|
+
readonly onModelCall?: ModelAdapter;
|
|
7
|
+
readonly createModel?: (options: import("./model/defaults.js").ModelFactoryOptions) => ModelAdapter;
|
|
8
|
+
readonly observer?: (event: {
|
|
9
|
+
readonly type: string;
|
|
10
|
+
}) => void | Promise<void>;
|
|
11
|
+
readonly sessions?: SessionStore;
|
|
12
12
|
readonly media?: RuntimeMedia;
|
|
13
|
+
readonly environment?: ModelEnvironment;
|
|
14
|
+
readonly tokens?: boolean;
|
|
15
|
+
readonly delivery?: {
|
|
16
|
+
readonly previewBytes?: number;
|
|
17
|
+
readonly eventBytes?: number;
|
|
18
|
+
readonly eventCount?: number;
|
|
19
|
+
};
|
|
13
20
|
}
|
package/dist/contracts.d.ts
CHANGED
|
@@ -1,166 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
export type JsonValue
|
|
3
|
-
export type
|
|
4
|
-
readonly [key: string]: JsonValue;
|
|
5
|
-
};
|
|
6
|
-
export type UserContentPart = {
|
|
7
|
-
readonly type: "text";
|
|
8
|
-
readonly text: string;
|
|
9
|
-
} | {
|
|
10
|
-
readonly type: "media";
|
|
11
|
-
readonly mediaType: string;
|
|
12
|
-
readonly reference: JsonValue;
|
|
13
|
-
};
|
|
14
|
-
export type MessageInput = string | {
|
|
15
|
-
readonly text: string;
|
|
16
|
-
readonly metadata?: JsonObject;
|
|
17
|
-
} | {
|
|
18
|
-
readonly content: readonly UserContentPart[];
|
|
19
|
-
readonly metadata?: JsonObject;
|
|
20
|
-
};
|
|
21
|
-
export type InteractionReply = {
|
|
22
|
-
readonly kind: "approve";
|
|
23
|
-
readonly interactionId: string;
|
|
24
|
-
readonly approved: boolean;
|
|
25
|
-
} | {
|
|
26
|
-
readonly kind: "respond";
|
|
27
|
-
readonly interactionId: string;
|
|
28
|
-
readonly value: JsonValue;
|
|
29
|
-
};
|
|
30
|
-
export type RuntimeInput = MessageInput | InteractionReply;
|
|
31
|
-
export type RuntimeInputEvent = InteractionReply | {
|
|
32
|
-
readonly kind: "user-message" | "interrupt";
|
|
33
|
-
readonly text?: string;
|
|
34
|
-
readonly content?: readonly UserContentPart[];
|
|
35
|
-
};
|
|
36
|
-
/** Lifecycle events are delivered in completion order; other events are diagnostics. */
|
|
37
|
-
export interface RuntimeEvent {
|
|
38
|
-
readonly type: string;
|
|
39
|
-
readonly output?: JsonValue;
|
|
40
|
-
readonly event?: RuntimeInputEvent;
|
|
41
|
-
readonly interaction?: unknown;
|
|
42
|
-
readonly attributes?: unknown;
|
|
43
|
-
readonly tripwire?: {
|
|
44
|
-
readonly code: string;
|
|
45
|
-
readonly message?: string;
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
export interface RuntimeCompletion {
|
|
49
|
-
readonly status: "completed" | "waiting" | "rejected" | "cancelled" | "stopped";
|
|
50
|
-
readonly events: readonly RuntimeEvent[];
|
|
51
|
-
}
|
|
52
|
-
export interface RuntimeSession {
|
|
53
|
-
readonly id: string;
|
|
54
|
-
input(event: RuntimeInput, options?: {
|
|
55
|
-
readonly signal?: AbortSignal;
|
|
56
|
-
}): {
|
|
57
|
-
readonly completed: Promise<RuntimeCompletion>;
|
|
58
|
-
};
|
|
59
|
-
stream(): AsyncIterable<RuntimeEvent>;
|
|
60
|
-
stop(reason?: string): Promise<void>;
|
|
61
|
-
}
|
|
62
|
-
export interface RuntimeRunOptions {
|
|
63
|
-
readonly id?: string;
|
|
64
|
-
readonly userId?: string;
|
|
65
|
-
readonly context?: JsonObject;
|
|
66
|
-
readonly onModelCall: RuntimeModelAdapter;
|
|
67
|
-
readonly observer?: {
|
|
68
|
-
(event: {
|
|
69
|
-
readonly type: string;
|
|
70
|
-
}): void | Promise<void>;
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
export interface RuntimeAgent {
|
|
74
|
-
readonly id: string;
|
|
75
|
-
readonly name: string;
|
|
76
|
-
readonly manifest: {
|
|
77
|
-
readonly id: string;
|
|
78
|
-
readonly name: string;
|
|
79
|
-
};
|
|
80
|
-
run(options: RuntimeRunOptions): RuntimeSession;
|
|
81
|
-
close?(): Promise<void>;
|
|
82
|
-
}
|
|
83
|
-
export type PromptContentPart = Exclude<UserContentPart, {
|
|
84
|
-
readonly type: "text";
|
|
85
|
-
}> | {
|
|
86
|
-
readonly type: "text" | "reasoning";
|
|
87
|
-
readonly text: string;
|
|
88
|
-
readonly providerMetadata?: JsonObject;
|
|
89
|
-
} | {
|
|
90
|
-
readonly type: "tool-call";
|
|
91
|
-
readonly providerMetadata?: JsonObject;
|
|
92
|
-
readonly id: string;
|
|
93
|
-
readonly name: string;
|
|
94
|
-
readonly args: JsonObject;
|
|
95
|
-
};
|
|
96
|
-
export type PromptItem = {
|
|
97
|
-
readonly kind: "instructions";
|
|
98
|
-
readonly role: "system";
|
|
99
|
-
readonly content: readonly PromptContentPart[];
|
|
100
|
-
} | {
|
|
101
|
-
readonly kind: "message";
|
|
102
|
-
readonly role: "user" | "assistant";
|
|
103
|
-
readonly content: readonly PromptContentPart[];
|
|
104
|
-
} | {
|
|
105
|
-
readonly kind: "context";
|
|
106
|
-
readonly role: "user";
|
|
107
|
-
readonly content: readonly PromptContentPart[];
|
|
108
|
-
} | {
|
|
109
|
-
readonly kind: "tool-result";
|
|
110
|
-
readonly toolCallId: string;
|
|
111
|
-
readonly toolName: string;
|
|
112
|
-
readonly status: "completed" | "denied" | "failed";
|
|
113
|
-
readonly content: readonly PromptContentPart[];
|
|
114
|
-
};
|
|
115
|
-
export interface RuntimeModelCall {
|
|
116
|
-
readonly sessionId: string;
|
|
117
|
-
readonly prompt: readonly PromptItem[];
|
|
118
|
-
readonly tools: readonly {
|
|
119
|
-
readonly name: string;
|
|
120
|
-
readonly description?: string;
|
|
121
|
-
readonly inputSchema: JsonObject;
|
|
122
|
-
}[];
|
|
123
|
-
readonly outputSchema?: JsonObject;
|
|
124
|
-
readonly model?: {
|
|
125
|
-
readonly id?: string;
|
|
126
|
-
readonly controls?: {
|
|
127
|
-
readonly temperature?: number;
|
|
128
|
-
readonly maxOutputTokens?: number;
|
|
129
|
-
};
|
|
130
|
-
readonly config?: JsonObject;
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
export interface RuntimeModelCandidate {
|
|
134
|
-
readonly output: readonly ({
|
|
135
|
-
readonly type: "text" | "reasoning";
|
|
136
|
-
readonly text: string;
|
|
137
|
-
readonly providerMetadata?: JsonObject;
|
|
138
|
-
} | {
|
|
139
|
-
readonly type: "json";
|
|
140
|
-
readonly value: JsonValue;
|
|
141
|
-
} | {
|
|
142
|
-
readonly type: "tool-call";
|
|
143
|
-
readonly providerMetadata?: JsonObject;
|
|
144
|
-
readonly id: string;
|
|
145
|
-
readonly name: string;
|
|
146
|
-
readonly args: JsonObject;
|
|
147
|
-
})[];
|
|
148
|
-
readonly finishReason?: "stop" | "length" | "tool-calls" | "content-filter" | "other";
|
|
149
|
-
readonly usage?: {
|
|
150
|
-
readonly inputTokens?: number;
|
|
151
|
-
readonly outputTokens?: number;
|
|
152
|
-
readonly totalTokens?: number;
|
|
153
|
-
readonly costUsd?: number;
|
|
154
|
-
};
|
|
155
|
-
readonly evidence?: {
|
|
156
|
-
readonly resolvedModel?: string;
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
export interface RuntimeModelContext {
|
|
160
|
-
readonly signal: AbortSignal;
|
|
161
|
-
reportPreparedCall?(prepared: {
|
|
162
|
-
readonly adapter: string;
|
|
163
|
-
readonly call: JsonValue;
|
|
164
|
-
}): void;
|
|
165
|
-
}
|
|
166
|
-
export type RuntimeModelAdapter = (call: RuntimeModelCall, context: RuntimeModelContext) => Promise<RuntimeModelCandidate>;
|
|
1
|
+
/** Execution contracts are owned by Harness. */
|
|
2
|
+
export type { JsonValue, JsonObject, MessageInput, UserContentPart, PromptContentPart, PromptItem, ModelCall as RuntimeModelCall, ModelCandidate as RuntimeModelCandidate, ModelAdapter as RuntimeModelAdapter, ModelAdapterContext as RuntimeModelContext, ExecutionInput as RuntimeInput, InputEvent as RuntimeInputEvent, RunResult as RuntimeCompletion, ExecutionEvent as RuntimeEvent, } from "@nylorun/harness";
|
|
3
|
+
export type RuntimeAgent = import("@nylorun/harness").BuiltAgent<any, any>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/dev.js
CHANGED
|
@@ -69,7 +69,12 @@ export async function develop(args) {
|
|
|
69
69
|
}));
|
|
70
70
|
};
|
|
71
71
|
try {
|
|
72
|
-
launch([
|
|
72
|
+
launch([
|
|
73
|
+
tsx,
|
|
74
|
+
"watch",
|
|
75
|
+
fileURLToPath(new URL("./dev-entry.js", import.meta.url)),
|
|
76
|
+
"src/index.ts",
|
|
77
|
+
]);
|
|
73
78
|
if (!args.includes("--no-studio")) {
|
|
74
79
|
const url = `http://127.0.0.1:${port}/agents/v1/agents`;
|
|
75
80
|
const deadline = Date.now() + 20_000;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { writeFile, rename, rm } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
|
+
import { loadEnvFile } from "node:process";
|
|
6
|
+
export function loadProjectEnvironment(root = process.cwd()) {
|
|
7
|
+
const file = join(root, ".env");
|
|
8
|
+
try {
|
|
9
|
+
if (statSync(file).isDirectory())
|
|
10
|
+
throw new Error("The .env directory must be migrated manually: back it up, create a .env file with MODEL_PROVIDER, MODEL and MODEL_PROVIDER_API_KEY, and move OAuth credentials to .nylorun/auth.json. See the Runtime migration guide.");
|
|
11
|
+
}
|
|
12
|
+
catch (error) {
|
|
13
|
+
if (error.code === "ENOENT")
|
|
14
|
+
return;
|
|
15
|
+
throw error;
|
|
16
|
+
}
|
|
17
|
+
loadEnvFile(file);
|
|
18
|
+
}
|
|
19
|
+
// Match complete dotenv assignments, including quoted multiline values.
|
|
20
|
+
const assignment = /^(?:export\s+)?([\w]+)[\t ]*=[\t ]*(?:"[^"]*"|'[^']*'|`[^`]*`|[^#\r\n]*)([^\r\n]*)(?:\r?\n|$)/gm;
|
|
21
|
+
export async function saveEnvironment(root, updates, signal) {
|
|
22
|
+
const file = join(root, ".env");
|
|
23
|
+
let contents = "";
|
|
24
|
+
try {
|
|
25
|
+
contents = readFileSync(file, "utf8");
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
if (error.code !== "ENOENT")
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
const encode = (value) => {
|
|
32
|
+
// Node's dotenv parser has no general quote-escaping syntax. Select a
|
|
33
|
+
// delimiter absent from the value rather than changing the credential.
|
|
34
|
+
for (const quote of ["'", '"', "`"]) {
|
|
35
|
+
if (!value.includes(quote) && !(quote === '"' && /\\[nr]/.test(value)))
|
|
36
|
+
return quote + value + quote;
|
|
37
|
+
}
|
|
38
|
+
throw new Error("This value contains all dotenv quote delimiters; set it through your process environment instead.");
|
|
39
|
+
};
|
|
40
|
+
const remaining = new Set(Object.keys(updates));
|
|
41
|
+
contents = contents.replace(assignment, (whole, key, suffix) => {
|
|
42
|
+
if (!(key in updates))
|
|
43
|
+
return whole;
|
|
44
|
+
if (!remaining.delete(key))
|
|
45
|
+
return "";
|
|
46
|
+
return updates[key] === undefined
|
|
47
|
+
? ""
|
|
48
|
+
: `${key}=${encode(updates[key])}${suffix}\n`;
|
|
49
|
+
});
|
|
50
|
+
if (contents && !contents.endsWith("\n"))
|
|
51
|
+
contents += "\n";
|
|
52
|
+
for (const key of remaining)
|
|
53
|
+
if (updates[key] !== undefined)
|
|
54
|
+
contents += `${key}=${encode(updates[key])}\n`;
|
|
55
|
+
const temporary = join(root, `.env-${randomUUID()}.tmp`);
|
|
56
|
+
try {
|
|
57
|
+
await writeFile(temporary, contents, { mode: 0o600, signal });
|
|
58
|
+
signal?.throwIfAborted();
|
|
59
|
+
await rename(temporary, file);
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
await rm(temporary, { force: true });
|
|
63
|
+
}
|
|
64
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export type { RuntimeConfig } from "./config.js";
|
|
2
2
|
export type * from "./contracts.js";
|
|
3
3
|
export { Runtime, serveAgents, type AgentRouterOptions, type RuntimeActor, type ServeAgentsOptions, } from "./server/host.js";
|
|
4
|
-
export {
|
|
5
|
-
export
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
8
|
-
export type { RuntimeMedia, MediaAsset, MediaReference
|
|
9
|
-
export {
|
|
10
|
-
export
|
|
11
|
-
export {
|
|
4
|
+
export { SessionHost, type SubmitOptions } from "./sessions/host.js";
|
|
5
|
+
export { memorySessions } from "./sessions/store.js";
|
|
6
|
+
export type { SessionStore, ManagedSessionStore, StoredSession, SessionSummary, CanonicalEvent, } from "./sessions/store.js";
|
|
7
|
+
export { IMAGE_MEDIA_TYPES, MAX_IMAGE_BYTES, decodeImageBase64, validateImageBytes, } from "./media.js";
|
|
8
|
+
export type { RuntimeMedia, MediaAsset, MediaReference } from "./media.js";
|
|
9
|
+
export { httpModel, type HttpModelOptions, type ModelEnvironment, } from "./model/http-model.js";
|
|
10
|
+
export { agUiEvents } from "./server/ag-ui.js";
|
|
11
|
+
export type { ModelFactoryOptions, ModelPreview } from "./model/defaults.js";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { Runtime, serveAgents, } from "./server/host.js";
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
2
|
+
export { SessionHost } from "./sessions/host.js";
|
|
3
|
+
export { memorySessions } from "./sessions/store.js";
|
|
4
|
+
export { IMAGE_MEDIA_TYPES, MAX_IMAGE_BYTES, decodeImageBase64, validateImageBytes, } from "./media.js";
|
|
5
|
+
export { httpModel, } from "./model/http-model.js";
|
|
6
|
+
export { agUiEvents } from "./server/ag-ui.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function start(entry?: string, development?: boolean): Promise<void>;
|