@nylorun/agents 0.19.1-beta → 0.20.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 +76 -0
- package/README.md +165 -96
- package/dist/ag-ui/handler.d.ts +4 -4
- package/dist/artifacts.d.ts +14 -1
- package/dist/artifacts.js +28 -0
- package/dist/environments.d.ts +217 -0
- package/dist/environments.js +174 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/reads.d.ts +1 -1
- package/dist/session-client.d.ts +101 -18
- package/dist/session-client.js +36 -16
- package/package.json +4 -4
- package/dist/sandboxes.d.ts +0 -106
- package/dist/sandboxes.js +0 -109
package/dist/session-client.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { SANDBOX_TOOL_NAMES, codeToolRefusal, delegateOf, isBuiltWorkflow, isSandboxToolName, } from "@nylorun/core/define";
|
|
1
|
+
import { SANDBOX_TOOL_NAMES, approvalRefusal, codeToolRefusal, delegateOf, isBuiltWorkflow, isSandboxToolName, } from "@nylorun/core/define";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { SCOPES_HEADER, SUBJECT_HEADER } from "@nylorun/core/compatibility";
|
|
4
|
-
import { SessionManifestViewSchema, SessionUsageTotalsSchema, ModelCallsPageSchema, parseSessionEvent, parseSubjectHeaders, } from "@nylorun/core/contracts";
|
|
4
|
+
import { SessionManifestViewSchema, SessionUsageTotalsSchema, ModelCallsPageSchema, ToolCallsPageSchema, TurnTraceSchema, parseSessionEvent, parseSubjectHeaders, } from "@nylorun/core/contracts";
|
|
5
5
|
import { SessionsReadClient } from "./reads.js";
|
|
6
6
|
import { AccessClient } from "./access.js";
|
|
7
|
-
import {
|
|
7
|
+
import { EnvironmentsClient } from "./environments.js";
|
|
8
8
|
import { ArtifactsClient } from "./artifacts.js";
|
|
9
9
|
import { FilesClient } from "./files.js";
|
|
10
10
|
import { Transport, env, id, segment } from "./http.js";
|
|
@@ -74,7 +74,7 @@ export class AgentsClient {
|
|
|
74
74
|
/**
|
|
75
75
|
* A client that acts for `subject`: every call sends `Nylorun-Subject` and
|
|
76
76
|
* `Nylorun-Scopes`, and the Runtime limits it to the scopes and to the subject's own sessions
|
|
77
|
-
*
|
|
77
|
+
* (Host feature `subject-headers`). For app servers, which authenticate the person
|
|
78
78
|
* themselves and hold the key; nothing is minted, cached or refreshed.
|
|
79
79
|
*/
|
|
80
80
|
as(subject, options = {}) {
|
|
@@ -98,11 +98,12 @@ export class AgentsClient {
|
|
|
98
98
|
return new AccessClient(this.transport);
|
|
99
99
|
}
|
|
100
100
|
/**
|
|
101
|
-
*
|
|
102
|
-
* label, `delete` one, or give a session its own with
|
|
101
|
+
* Environments (protocol 11): `put` one by id (create, find or change), write its `secrets`,
|
|
102
|
+
* `list` them by label, `stop`, `reset` or `delete` one, or give a session its own with
|
|
103
|
+
* `forSession`.
|
|
103
104
|
*/
|
|
104
|
-
get
|
|
105
|
-
return new
|
|
105
|
+
get environments() {
|
|
106
|
+
return new EnvironmentsClient(this.transport, (options) => this.createSession(options));
|
|
106
107
|
}
|
|
107
108
|
/** File artifacts: upload, list, download with Range, capability links (protocol 6). */
|
|
108
109
|
get artifacts() {
|
|
@@ -132,7 +133,7 @@ export class AgentsClient {
|
|
|
132
133
|
* Registers the agent's definition (`PUT /v1/agents/{id}`), first uploading the skill files
|
|
133
134
|
* it names that the Runtime does not hold. A definition with a tool that runs your code
|
|
134
135
|
* (`tool({ run })`, a flow's tool stage) is refused before anything is sent: the Runtime runs
|
|
135
|
-
*
|
|
136
|
+
* agents from their manifests alone. `implementationVersion` defaults to
|
|
136
137
|
* `NYLORUN_IMPLEMENTATION_VERSION`, else `dev`.
|
|
137
138
|
*/
|
|
138
139
|
async saveAgent(agent, options = {}) {
|
|
@@ -149,7 +150,8 @@ export class AgentsClient {
|
|
|
149
150
|
assertNoMiddlewareClosures(agent);
|
|
150
151
|
skillFilesOf(agent, files);
|
|
151
152
|
}
|
|
152
|
-
const refusal = codeToolRefusal(agent.manifest)
|
|
153
|
+
const refusal = codeToolRefusal(agent.manifest) ??
|
|
154
|
+
approvalRefusal(agent.manifest);
|
|
153
155
|
if (refusal)
|
|
154
156
|
throw new Error(refusal);
|
|
155
157
|
await this.files.ensure(files);
|
|
@@ -166,11 +168,7 @@ export class AgentsClient {
|
|
|
166
168
|
agentId: options.agentId,
|
|
167
169
|
ownerUserId: options.ownerUserId,
|
|
168
170
|
...(options.info ? { info: options.info } : {}),
|
|
169
|
-
...(options.
|
|
170
|
-
...(options.credentialSelections
|
|
171
|
-
? { credentialSelections: options.credentialSelections }
|
|
172
|
-
: {}),
|
|
173
|
-
...(options.sandbox === undefined ? {} : { sandbox: options.sandbox }),
|
|
171
|
+
...(options.environment === undefined ? {} : { environment: options.environment }),
|
|
174
172
|
});
|
|
175
173
|
return this.session(sessionId);
|
|
176
174
|
}
|
|
@@ -274,6 +272,28 @@ export class SessionClient {
|
|
|
274
272
|
query.set("cursor", options.cursor);
|
|
275
273
|
return ModelCallsPageSchema.parse(await this.transport.json(`${this.path}/calls/model?${query}`, "GET", undefined, options.signal));
|
|
276
274
|
}
|
|
275
|
+
/**
|
|
276
|
+
* The session's tool calls (R5, Host feature `tool-calls`), in the order they were first sent:
|
|
277
|
+
* each one's tool, input, status and sends. `attempts` above 1: a crash re-sent it.
|
|
278
|
+
*/
|
|
279
|
+
async toolCalls(options = {}) {
|
|
280
|
+
await this.transport.requireFeature("tool-calls", options.signal);
|
|
281
|
+
const query = new URLSearchParams({ limit: String(options.limit ?? 50) });
|
|
282
|
+
if (options.turnId !== undefined)
|
|
283
|
+
query.set("turnId", options.turnId);
|
|
284
|
+
if (options.cursor !== undefined)
|
|
285
|
+
query.set("cursor", options.cursor);
|
|
286
|
+
return ToolCallsPageSchema.parse(await this.transport.json(`${this.path}/calls/tool?${query}`, "GET", undefined, options.signal));
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* A turn's trace (R7, Host feature `traces`): its spans as OTLP/HTTP JSON (`resourceSpans`), as
|
|
290
|
+
* the Runtime posts them to an OTLP collector. Post it to a collector's `/v1/traces` to backfill
|
|
291
|
+
* one, or read it without one.
|
|
292
|
+
*/
|
|
293
|
+
async trace(turnId, options = {}) {
|
|
294
|
+
await this.transport.requireFeature("traces", options.signal);
|
|
295
|
+
return TurnTraceSchema.parse(await this.transport.json(`${this.path}/turns/${encodeURIComponent(turnId)}/trace`, "GET", undefined, options.signal));
|
|
296
|
+
}
|
|
277
297
|
async history(options = {}) {
|
|
278
298
|
const query = new URLSearchParams();
|
|
279
299
|
if (options.cursor)
|
|
@@ -372,4 +392,4 @@ export class SessionClient {
|
|
|
372
392
|
}
|
|
373
393
|
export { RuntimeError, IncompatibleRuntimeError } from "./http.js";
|
|
374
394
|
export { AccessClient } from "./access.js";
|
|
375
|
-
export {
|
|
395
|
+
export { EnvironmentSecretsClient, EnvironmentsClient } from "./environments.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nylorun/agents",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0-beta",
|
|
4
4
|
"description": "Nylorun agent definitions and session client",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -43,14 +43,14 @@
|
|
|
43
43
|
"test": "vitest run --passWithNoTests"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@nylorun/core": "0.
|
|
46
|
+
"@nylorun/core": "0.20.0-beta",
|
|
47
47
|
"gray-matter": "^4.0.3"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"zod": "^4.6.5"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"@types/node": "^
|
|
53
|
+
"@types/node": "^26.6.4",
|
|
54
54
|
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
|
55
55
|
"vitest": "^5.0.2"
|
|
56
56
|
},
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"repository": {
|
|
61
61
|
"type": "git",
|
|
62
62
|
"url": "git+https://github.com/nylorun/agents.git",
|
|
63
|
-
"directory": "agents"
|
|
63
|
+
"directory": "sdks/agents"
|
|
64
64
|
},
|
|
65
65
|
"publishConfig": {
|
|
66
66
|
"access": "public",
|
package/dist/sandboxes.d.ts
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sandboxes as a resource (Host feature `sandboxes`): `client.sandboxes`. A sandbox has its own
|
|
3
|
-
* id and outlives the sessions attached to it; whether it serves one session, one person or a
|
|
4
|
-
* project is the app's choice, made here:
|
|
5
|
-
*
|
|
6
|
-
* - `sandboxes.forSession(...)`: one sandbox for one session. It creates the sandbox, opens the
|
|
7
|
-
* session attached to it, and `release()` deletes the sandbox when the session is done. It
|
|
8
|
-
* replaces sharing through another session (`sandbox: { session }`, `sandboxOwnerId`).
|
|
9
|
-
* - `sandboxes.ensure(id, spec)`: one sandbox per person or per project, by a deterministic id
|
|
10
|
-
* (`user-42`, `team-a/proj-42`); get-or-create in one call. Attach sessions to it with
|
|
11
|
-
* `createSession({ sandbox: { id } })`.
|
|
12
|
-
*
|
|
13
|
-
* Ids may hold `/`; they are sent percent-encoded as one path segment.
|
|
14
|
-
*/
|
|
15
|
-
import { type DeleteSandboxResponse, type PutSandboxRequest, type SandboxEvent, type SandboxView } from "@nylorun/core/contracts";
|
|
16
|
-
import { type Transport } from "./http.js";
|
|
17
|
-
import type { CreateSessionOptions, SessionClient } from "./session-client.js";
|
|
18
|
-
/** What a sandbox is made of: fixed once it exists, except its labels. */
|
|
19
|
-
export type SandboxSpec = Omit<PutSandboxRequest, "requestId">;
|
|
20
|
-
/** A session opened on a sandbox of its own (`sandboxes.forSession`). */
|
|
21
|
-
export interface SessionSandboxHandle {
|
|
22
|
-
readonly session: SessionClient;
|
|
23
|
-
readonly sandbox: SandboxView;
|
|
24
|
-
/** Deletes the sandbox and its files; call it when the session is done. */
|
|
25
|
-
release(options?: {
|
|
26
|
-
signal?: AbortSignal;
|
|
27
|
-
}): Promise<DeleteSandboxResponse>;
|
|
28
|
-
}
|
|
29
|
-
export interface ForSessionOptions {
|
|
30
|
-
/** The session to open, as `createSession` takes it, without `sandbox`. */
|
|
31
|
-
readonly session: Omit<CreateSessionOptions, "sandbox">;
|
|
32
|
-
/** The sandbox's spec and labels. Default: a virtual sandbox within the Tenant's defaults. */
|
|
33
|
-
readonly spec?: SandboxSpec;
|
|
34
|
-
/** The sandbox's id. Default: `sessions/<session id>`. */
|
|
35
|
-
readonly sandboxId?: string;
|
|
36
|
-
readonly signal?: AbortSignal;
|
|
37
|
-
}
|
|
38
|
-
export declare class SandboxesClient {
|
|
39
|
-
private readonly transport;
|
|
40
|
-
/** `AgentsClient.createSession`, bound. */
|
|
41
|
-
private readonly createSession;
|
|
42
|
-
constructor(transport: Transport,
|
|
43
|
-
/** `AgentsClient.createSession`, bound. */
|
|
44
|
-
createSession: (options: CreateSessionOptions) => Promise<SessionClient>);
|
|
45
|
-
private path;
|
|
46
|
-
/**
|
|
47
|
-
* Creates the sandbox, or finds the one with this id (`PUT /v1/sandboxes/{id}`). Its spec is
|
|
48
|
-
* fixed once it exists: a different one is a 409. Labels, when given, replace its labels.
|
|
49
|
-
*/
|
|
50
|
-
ensure(sandboxId: string, spec?: SandboxSpec, options?: {
|
|
51
|
-
signal?: AbortSignal;
|
|
52
|
-
}): Promise<SandboxView>;
|
|
53
|
-
get(sandboxId: string, options?: {
|
|
54
|
-
signal?: AbortSignal;
|
|
55
|
-
}): Promise<SandboxView>;
|
|
56
|
-
/** The sandboxes with every label in `labels` that this client reaches. */
|
|
57
|
-
list(options?: {
|
|
58
|
-
labels?: Readonly<Record<string, string>>;
|
|
59
|
-
signal?: AbortSignal;
|
|
60
|
-
}): Promise<SandboxView[]>;
|
|
61
|
-
page(options?: {
|
|
62
|
-
labels?: Readonly<Record<string, string>>;
|
|
63
|
-
limit?: number;
|
|
64
|
-
cursor?: string;
|
|
65
|
-
signal?: AbortSignal;
|
|
66
|
-
}): Promise<{
|
|
67
|
-
sandboxes: {
|
|
68
|
-
id: string;
|
|
69
|
-
kind: "pod" | "virtual";
|
|
70
|
-
labels: Record<string, string>;
|
|
71
|
-
spec: Record<string, unknown>;
|
|
72
|
-
state: "creating" | "ready" | "running" | "stopped";
|
|
73
|
-
pod?: {
|
|
74
|
-
desired: "deleted" | "running" | "suspended";
|
|
75
|
-
observed: "creating" | "deleting" | "expired" | "failed" | "lost" | "running" | "suspended";
|
|
76
|
-
volumeGeneration: number;
|
|
77
|
-
hostEpoch: number;
|
|
78
|
-
expiresAt?: string | undefined;
|
|
79
|
-
reason?: string | undefined;
|
|
80
|
-
} | undefined;
|
|
81
|
-
sessions: {
|
|
82
|
-
id: string;
|
|
83
|
-
activeTurnId: string | null;
|
|
84
|
-
}[];
|
|
85
|
-
createdAt: string;
|
|
86
|
-
updatedAt: string;
|
|
87
|
-
}[];
|
|
88
|
-
nextCursor: string | null;
|
|
89
|
-
}>;
|
|
90
|
-
/** Deletes the sandbox and its files; `deleted` is false when there was none. */
|
|
91
|
-
delete(sandboxId: string, options?: {
|
|
92
|
-
signal?: AbortSignal;
|
|
93
|
-
}): Promise<DeleteSandboxResponse>;
|
|
94
|
-
/** The sandbox's lifecycle events, from `from` on. */
|
|
95
|
-
events(sandboxId: string, options?: {
|
|
96
|
-
from?: number;
|
|
97
|
-
signal?: AbortSignal;
|
|
98
|
-
}): Promise<SandboxEvent[]>;
|
|
99
|
-
/**
|
|
100
|
-
* One sandbox for one session: creates the sandbox (`sessions/<session id>` unless
|
|
101
|
-
* `sandboxId` names another), opens the session attached to it, and returns both with
|
|
102
|
-
* `release()`, which deletes the sandbox. If the session cannot be opened, the sandbox is
|
|
103
|
-
* deleted again.
|
|
104
|
-
*/
|
|
105
|
-
forSession(options: ForSessionOptions): Promise<SessionSandboxHandle>;
|
|
106
|
-
}
|
package/dist/sandboxes.js
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sandboxes as a resource (Host feature `sandboxes`): `client.sandboxes`. A sandbox has its own
|
|
3
|
-
* id and outlives the sessions attached to it; whether it serves one session, one person or a
|
|
4
|
-
* project is the app's choice, made here:
|
|
5
|
-
*
|
|
6
|
-
* - `sandboxes.forSession(...)`: one sandbox for one session. It creates the sandbox, opens the
|
|
7
|
-
* session attached to it, and `release()` deletes the sandbox when the session is done. It
|
|
8
|
-
* replaces sharing through another session (`sandbox: { session }`, `sandboxOwnerId`).
|
|
9
|
-
* - `sandboxes.ensure(id, spec)`: one sandbox per person or per project, by a deterministic id
|
|
10
|
-
* (`user-42`, `team-a/proj-42`); get-or-create in one call. Attach sessions to it with
|
|
11
|
-
* `createSession({ sandbox: { id } })`.
|
|
12
|
-
*
|
|
13
|
-
* Ids may hold `/`; they are sent percent-encoded as one path segment.
|
|
14
|
-
*/
|
|
15
|
-
import { SandboxPageSchema, isSandboxId, } from "@nylorun/core/contracts";
|
|
16
|
-
import { id, segment } from "./http.js";
|
|
17
|
-
const FEATURE = "sandboxes";
|
|
18
|
-
export class SandboxesClient {
|
|
19
|
-
transport;
|
|
20
|
-
createSession;
|
|
21
|
-
constructor(transport,
|
|
22
|
-
/** `AgentsClient.createSession`, bound. */
|
|
23
|
-
createSession) {
|
|
24
|
-
this.transport = transport;
|
|
25
|
-
this.createSession = createSession;
|
|
26
|
-
}
|
|
27
|
-
path(sandboxId) {
|
|
28
|
-
if (!isSandboxId(sandboxId))
|
|
29
|
-
throw new TypeError(`${sandboxId} is not a sandbox id: up to 200 characters, /-separated segments of letters, digits, '.', '_' and '-'`);
|
|
30
|
-
return `/v1/sandboxes/${segment(sandboxId)}`;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Creates the sandbox, or finds the one with this id (`PUT /v1/sandboxes/{id}`). Its spec is
|
|
34
|
-
* fixed once it exists: a different one is a 409. Labels, when given, replace its labels.
|
|
35
|
-
*/
|
|
36
|
-
async ensure(sandboxId, spec = {}, options = {}) {
|
|
37
|
-
const path = this.path(sandboxId);
|
|
38
|
-
await this.transport.requireFeature(FEATURE, options.signal);
|
|
39
|
-
return this.transport.json(path, "PUT", { requestId: id(), ...spec }, options.signal);
|
|
40
|
-
}
|
|
41
|
-
async get(sandboxId, options = {}) {
|
|
42
|
-
const path = this.path(sandboxId);
|
|
43
|
-
await this.transport.requireFeature(FEATURE, options.signal);
|
|
44
|
-
return this.transport.json(path, "GET", undefined, options.signal);
|
|
45
|
-
}
|
|
46
|
-
/** The sandboxes with every label in `labels` that this client reaches. */
|
|
47
|
-
async list(options = {}) {
|
|
48
|
-
await this.transport.requireFeature(FEATURE, options.signal);
|
|
49
|
-
const query = new URLSearchParams();
|
|
50
|
-
for (const [key, value] of Object.entries(options.labels ?? {}))
|
|
51
|
-
query.append("label", `${key}=${value}`);
|
|
52
|
-
const search = query.toString();
|
|
53
|
-
const reply = await this.transport.json(`/v1/sandboxes${search ? `?${search}` : ""}`, "GET", undefined, options.signal);
|
|
54
|
-
return reply.sandboxes;
|
|
55
|
-
}
|
|
56
|
-
async page(options = {}) {
|
|
57
|
-
await this.transport.requireFeature("session-reads", options.signal);
|
|
58
|
-
const query = new URLSearchParams({ limit: String(options.limit ?? 50) });
|
|
59
|
-
if (options.cursor !== undefined)
|
|
60
|
-
query.set("cursor", options.cursor);
|
|
61
|
-
for (const [key, value] of Object.entries(options.labels ?? {}))
|
|
62
|
-
query.append("label", `${key}=${value}`);
|
|
63
|
-
return SandboxPageSchema.parse(await this.transport.json(`/v1/sandboxes?${query}`, "GET", undefined, options.signal));
|
|
64
|
-
}
|
|
65
|
-
/** Deletes the sandbox and its files; `deleted` is false when there was none. */
|
|
66
|
-
async delete(sandboxId, options = {}) {
|
|
67
|
-
const path = this.path(sandboxId);
|
|
68
|
-
await this.transport.requireFeature(FEATURE, options.signal);
|
|
69
|
-
return this.transport.json(path, "DELETE", undefined, options.signal);
|
|
70
|
-
}
|
|
71
|
-
/** The sandbox's lifecycle events, from `from` on. */
|
|
72
|
-
async events(sandboxId, options = {}) {
|
|
73
|
-
const path = this.path(sandboxId);
|
|
74
|
-
await this.transport.requireFeature(FEATURE, options.signal);
|
|
75
|
-
const reply = await this.transport.json(`${path}/events${options.from === undefined ? "" : `?from=${options.from}`}`, "GET", undefined, options.signal);
|
|
76
|
-
return reply.events;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* One sandbox for one session: creates the sandbox (`sessions/<session id>` unless
|
|
80
|
-
* `sandboxId` names another), opens the session attached to it, and returns both with
|
|
81
|
-
* `release()`, which deletes the sandbox. If the session cannot be opened, the sandbox is
|
|
82
|
-
* deleted again.
|
|
83
|
-
*/
|
|
84
|
-
async forSession(options) {
|
|
85
|
-
const sessionId = options.session.id ?? id();
|
|
86
|
-
const sandboxId = options.sandboxId ??
|
|
87
|
-
(isSandboxId(`sessions/${sessionId}`) ? `sessions/${sessionId}` : `sessions/${id()}`);
|
|
88
|
-
const sandbox = await this.ensure(sandboxId, options.spec ?? {}, {
|
|
89
|
-
...(options.signal ? { signal: options.signal } : {}),
|
|
90
|
-
});
|
|
91
|
-
let session;
|
|
92
|
-
try {
|
|
93
|
-
session = await this.createSession({
|
|
94
|
-
...options.session,
|
|
95
|
-
id: sessionId,
|
|
96
|
-
sandbox: { id: sandboxId },
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
catch (error) {
|
|
100
|
-
await this.delete(sandboxId).catch(() => undefined);
|
|
101
|
-
throw error;
|
|
102
|
-
}
|
|
103
|
-
return {
|
|
104
|
-
session,
|
|
105
|
-
sandbox,
|
|
106
|
-
release: (release = {}) => this.delete(sandboxId, release),
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
}
|