@nylorun/agents 0.8.0-beta → 0.10.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 +167 -0
- package/README.md +371 -166
- package/dist/a2a/handler.d.ts +59 -0
- package/dist/a2a/handler.js +178 -0
- package/dist/a2a/index.d.ts +8 -0
- package/dist/a2a/index.js +7 -0
- package/dist/access.d.ts +101 -0
- package/dist/access.js +111 -0
- package/dist/action-handler.d.ts +64 -0
- package/dist/action-handler.js +283 -0
- package/dist/ag-ui/handler.d.ts +12 -4
- package/dist/ag-ui/handler.js +87 -281
- package/dist/ag-ui/index.d.ts +2 -1
- package/dist/ag-ui/index.js +2 -1
- package/dist/browser.d.ts +97 -0
- package/dist/browser.js +277 -0
- package/dist/builder.d.ts +20 -0
- package/dist/builder.js +26 -0
- package/dist/client.d.ts +3 -230
- package/dist/client.js +2 -335
- package/dist/connection.d.ts +0 -1
- package/dist/connection.js +3 -9
- package/dist/delivery-token.d.ts +57 -0
- package/dist/delivery-token.js +150 -0
- package/dist/execute-action.d.ts +6 -0
- package/dist/execute-action.js +24 -0
- package/dist/http.d.ts +31 -1
- package/dist/http.js +74 -14
- package/dist/index.d.ts +13 -9
- package/dist/index.js +5 -4
- package/dist/mcp/index.d.ts +2 -2
- package/dist/mcp/index.js +1 -1
- package/dist/sandbox/client.d.ts +4 -5
- package/dist/sandbox/client.js +4 -8
- package/dist/sandbox/index.d.ts +0 -2
- package/dist/sandbox/index.js +0 -1
- package/dist/served-definitions.d.ts +20 -0
- package/dist/served-definitions.js +100 -0
- package/dist/session-client.d.ts +282 -0
- package/dist/session-client.js +375 -0
- package/dist/sse.js +12 -0
- package/dist/studio-embed.d.ts +9 -0
- package/dist/studio-embed.js +8 -0
- package/dist/token-endpoint.d.ts +23 -0
- package/dist/token-endpoint.js +30 -0
- package/package.json +15 -8
- package/dist/ag-ui/history.d.ts +0 -7
- package/dist/ag-ui/history.js +0 -60
- package/dist/ag-ui/sse.d.ts +0 -9
- package/dist/ag-ui/sse.js +0 -7
- package/dist/ag-ui/translate.d.ts +0 -38
- package/dist/ag-ui/translate.js +0 -222
- package/dist/derived-credentials.d.ts +0 -5
- package/dist/derived-credentials.js +0 -17
- package/dist/executor.d.ts +0 -20
- package/dist/executor.js +0 -353
- package/dist/mcp/mcp.d.ts +0 -30
- package/dist/mcp/mcp.js +0 -80
- package/dist/sandbox/sandbox.d.ts +0 -27
- package/dist/sandbox/sandbox.js +0 -92
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@nylorun/agents/studio-embed`: the contract between Studio and an app that embeds it in an
|
|
3
|
+
* iframe (Studio design §8). Studio's web app and embedders such as Babai import it from here,
|
|
4
|
+
* because Studio may not depend on `@nylorun/core` directly.
|
|
5
|
+
*
|
|
6
|
+
* No Node-only module is imported here or below.
|
|
7
|
+
*/
|
|
8
|
+
export { STUDIO_EMBED_MESSAGE_TYPE, STUDIO_EMBED_PROTOCOLS, StudioEmbedMessageSchema, StudioLoginTokenRequestSchema, StudioLoginTokenResponseSchema, StudioSessionRequestSchema, StudioSessionResponseSchema, StudioThemeSchema, isFrameAncestor, parseFrameAncestors, } from "@nylorun/core/contracts";
|
|
9
|
+
export type { StudioEmbedKind, StudioEmbedMessage, StudioLoginTokenRequest, StudioLoginTokenResponse, StudioSessionRequest, StudioSessionResponse, StudioTheme, } from "@nylorun/core/contracts";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@nylorun/agents/studio-embed`: the contract between Studio and an app that embeds it in an
|
|
3
|
+
* iframe (Studio design §8). Studio's web app and embedders such as Babai import it from here,
|
|
4
|
+
* because Studio may not depend on `@nylorun/core` directly.
|
|
5
|
+
*
|
|
6
|
+
* No Node-only module is imported here or below.
|
|
7
|
+
*/
|
|
8
|
+
export { STUDIO_EMBED_MESSAGE_TYPE, STUDIO_EMBED_PROTOCOLS, StudioEmbedMessageSchema, StudioLoginTokenRequestSchema, StudioLoginTokenResponseSchema, StudioSessionRequestSchema, StudioSessionResponseSchema, StudioThemeSchema, isFrameAncestor, parseFrameAncestors, } from "@nylorun/core/contracts";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A route for app servers that mints a subject token for the signed-in person (Host feature
|
|
3
|
+
* `subject-tokens`). The browser client calls it whenever it needs a token. Mount it on your
|
|
4
|
+
* app's own origin behind your sign-in: `POST` only, no CORS, never cached.
|
|
5
|
+
*
|
|
6
|
+
* export const POST = createTokenEndpoint({
|
|
7
|
+
* client, role: "user", subject: (request) => userFromCookie(request)?.id,
|
|
8
|
+
* });
|
|
9
|
+
*/
|
|
10
|
+
import type { TokenScope } from "@nylorun/core/contracts";
|
|
11
|
+
import type { AgentsClient } from "./session-client.js";
|
|
12
|
+
export interface TokenEndpointOptions {
|
|
13
|
+
/** The application client (the Tenant key stays on the server). */
|
|
14
|
+
client: AgentsClient | Promise<AgentsClient>;
|
|
15
|
+
/** The signed-in person the token is for; `undefined` answers 401. */
|
|
16
|
+
subject(request: Request): string | undefined | Promise<string | undefined>;
|
|
17
|
+
/** The access policy role to mint for, or a function of the request and subject. */
|
|
18
|
+
role: string | ((request: Request, subject: string) => string | Promise<string>);
|
|
19
|
+
scopes?: readonly TokenScope[];
|
|
20
|
+
agents?: readonly string[];
|
|
21
|
+
ttlSeconds?: number;
|
|
22
|
+
}
|
|
23
|
+
export declare function createTokenEndpoint(options: TokenEndpointOptions): (request: Request) => Promise<Response>;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { RuntimeError } from "./http.js";
|
|
2
|
+
const NO_STORE = { "cache-control": "no-store" };
|
|
3
|
+
export function createTokenEndpoint(options) {
|
|
4
|
+
return async (request) => {
|
|
5
|
+
if (request.method !== "POST")
|
|
6
|
+
return new Response(null, { status: 405, headers: { allow: "POST", ...NO_STORE } });
|
|
7
|
+
const subject = await options.subject(request);
|
|
8
|
+
if (!subject)
|
|
9
|
+
return Response.json({ error: "Sign in required" }, { status: 401, headers: NO_STORE });
|
|
10
|
+
const role = typeof options.role === "string"
|
|
11
|
+
? options.role
|
|
12
|
+
: await options.role(request, subject);
|
|
13
|
+
try {
|
|
14
|
+
const client = await options.client;
|
|
15
|
+
const minted = await client.tokens.create({
|
|
16
|
+
subject,
|
|
17
|
+
role,
|
|
18
|
+
...(options.scopes ? { scopes: options.scopes } : {}),
|
|
19
|
+
...(options.agents ? { agents: options.agents } : {}),
|
|
20
|
+
...(options.ttlSeconds === undefined ? {} : { ttlSeconds: options.ttlSeconds }),
|
|
21
|
+
});
|
|
22
|
+
return Response.json({ token: minted.token, expiresAt: minted.expiresAt }, { headers: NO_STORE });
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
// The person sees that a token could not be issued, never the Runtime's details.
|
|
26
|
+
const status = error instanceof RuntimeError && error.status === 400 ? 403 : 502;
|
|
27
|
+
return Response.json({ error: "Could not issue a token" }, { status, headers: NO_STORE });
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nylorun/agents",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Nylorun agent definitions, session client and
|
|
3
|
+
"version": "0.10.0-beta",
|
|
4
|
+
"description": "Nylorun agent definitions, session client and Action endpoint",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"files": [
|
|
@@ -24,13 +24,21 @@
|
|
|
24
24
|
"types": "./dist/client.d.ts",
|
|
25
25
|
"import": "./dist/client.js"
|
|
26
26
|
},
|
|
27
|
-
"./executor": {
|
|
28
|
-
"types": "./dist/executor.d.ts",
|
|
29
|
-
"import": "./dist/executor.js"
|
|
30
|
-
},
|
|
31
27
|
"./ag-ui": {
|
|
32
28
|
"types": "./dist/ag-ui/index.d.ts",
|
|
33
29
|
"import": "./dist/ag-ui/index.js"
|
|
30
|
+
},
|
|
31
|
+
"./browser": {
|
|
32
|
+
"types": "./dist/browser.d.ts",
|
|
33
|
+
"import": "./dist/browser.js"
|
|
34
|
+
},
|
|
35
|
+
"./a2a": {
|
|
36
|
+
"types": "./dist/a2a/index.d.ts",
|
|
37
|
+
"import": "./dist/a2a/index.js"
|
|
38
|
+
},
|
|
39
|
+
"./studio-embed": {
|
|
40
|
+
"types": "./dist/studio-embed.d.ts",
|
|
41
|
+
"import": "./dist/studio-embed.js"
|
|
34
42
|
}
|
|
35
43
|
},
|
|
36
44
|
"scripts": {
|
|
@@ -39,8 +47,7 @@
|
|
|
39
47
|
"test": "vitest run --passWithNoTests"
|
|
40
48
|
},
|
|
41
49
|
"dependencies": {
|
|
42
|
-
"@
|
|
43
|
-
"@nylorun/core": "0.7.0-beta",
|
|
50
|
+
"@nylorun/core": "0.9.0-beta",
|
|
44
51
|
"gray-matter": "^4.0.3"
|
|
45
52
|
},
|
|
46
53
|
"peerDependencies": {
|
package/dist/ag-ui/history.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* An AG-UI transcript rebuilt from a session's log, with the ids a live run gave each
|
|
3
|
-
* message (see `translate.ts`), usable as `HttpAgent`'s `initialMessages`.
|
|
4
|
-
*/
|
|
5
|
-
import type { Message } from "@ag-ui/core";
|
|
6
|
-
import { type LiveEvent } from "@nylorun/core/contracts";
|
|
7
|
-
export declare function messagesFromEvents(items: readonly LiveEvent[]): Message[];
|
package/dist/ag-ui/history.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { parseTranscriptEvent } from "@nylorun/core/contracts";
|
|
2
|
-
import { outputText, toolResultOf } from "./translate.js";
|
|
3
|
-
export function messagesFromEvents(items) {
|
|
4
|
-
const messages = [];
|
|
5
|
-
const results = new Set();
|
|
6
|
-
let sawAssistant = false;
|
|
7
|
-
for (const raw of items) {
|
|
8
|
-
if (raw.type === "command.message") {
|
|
9
|
-
const p = (raw.payload ?? {});
|
|
10
|
-
messages.push({
|
|
11
|
-
// The handler sends the client's message id as the idempotency key.
|
|
12
|
-
id: p.idempotencyKey ?? raw.eventId,
|
|
13
|
-
role: "user",
|
|
14
|
-
content: typeof p.content === "string" ? p.content : JSON.stringify(p.data),
|
|
15
|
-
});
|
|
16
|
-
sawAssistant = false;
|
|
17
|
-
continue;
|
|
18
|
-
}
|
|
19
|
-
const event = parseTranscriptEvent(raw);
|
|
20
|
-
if (!event)
|
|
21
|
-
continue;
|
|
22
|
-
const result = toolResultOf(event);
|
|
23
|
-
if (result) {
|
|
24
|
-
if (results.has(result.callId))
|
|
25
|
-
continue;
|
|
26
|
-
results.add(result.callId);
|
|
27
|
-
messages.push({
|
|
28
|
-
id: `${result.callId}:result`,
|
|
29
|
-
role: "tool",
|
|
30
|
-
toolCallId: result.callId,
|
|
31
|
-
content: result.content,
|
|
32
|
-
});
|
|
33
|
-
continue;
|
|
34
|
-
}
|
|
35
|
-
if (event.type === "message.assistant" && !event.payload.agent) {
|
|
36
|
-
const p = event.payload;
|
|
37
|
-
sawAssistant = true;
|
|
38
|
-
const message = { id: p.invocationId, role: "assistant" };
|
|
39
|
-
if (p.text)
|
|
40
|
-
message.content = p.text;
|
|
41
|
-
if (p.toolCalls.length)
|
|
42
|
-
message.toolCalls = p.toolCalls.map((call) => ({
|
|
43
|
-
id: call.callId,
|
|
44
|
-
type: "function",
|
|
45
|
-
function: { name: call.name, arguments: JSON.stringify(call.input ?? {}) },
|
|
46
|
-
}));
|
|
47
|
-
messages.push(message);
|
|
48
|
-
}
|
|
49
|
-
else if (event.type === "turn.completed" && !sawAssistant) {
|
|
50
|
-
const output = event.payload.output;
|
|
51
|
-
if (output !== undefined && output !== null && outputText(output))
|
|
52
|
-
messages.push({
|
|
53
|
-
id: raw.eventId,
|
|
54
|
-
role: "assistant",
|
|
55
|
-
content: outputText(output),
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return messages;
|
|
60
|
-
}
|
package/dist/ag-ui/sse.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AG-UI over server-sent events: one `data:` line of JSON per event. The last AG-UI event
|
|
3
|
-
* made from a Runtime event carries that event's cursor as `id:`, so a client that resumes
|
|
4
|
-
* from `Last-Event-ID` never lands inside a group.
|
|
5
|
-
*/
|
|
6
|
-
import type { BaseEvent } from "@ag-ui/core";
|
|
7
|
-
export declare const SSE_CONTENT_TYPE = "text/event-stream";
|
|
8
|
-
export declare function sseFrame(event: BaseEvent, id?: string): string;
|
|
9
|
-
export declare const SSE_HEARTBEAT = ": keep-alive\n\n";
|
package/dist/ag-ui/sse.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export const SSE_CONTENT_TYPE = "text/event-stream";
|
|
2
|
-
export function sseFrame(event, id) {
|
|
3
|
-
// Cursors are opaque base64; a line break would end the field early.
|
|
4
|
-
const idLine = id && !/[\r\n]/.test(id) ? `id: ${id}\n` : "";
|
|
5
|
-
return `${idLine}data: ${JSON.stringify(event)}\n\n`;
|
|
6
|
-
}
|
|
7
|
-
export const SSE_HEARTBEAT = ": keep-alive\n\n";
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Runtime transcript events → AG-UI 1.0 events for one run. Ids: an assistant message is its
|
|
3
|
-
* model call's `invocationId`, a tool call is the model's `callId`, a tool result is
|
|
4
|
-
* `<callId>:result`, so live runs and `messagesFromEvents` agree.
|
|
5
|
-
*/
|
|
6
|
-
import { type BaseEvent } from "@ag-ui/core";
|
|
7
|
-
import { type LiveEvent, type TranscriptEvent } from "@nylorun/core/contracts";
|
|
8
|
-
/** The text a tool result shows; `undefined` while there is no result yet. */
|
|
9
|
-
export declare function toolResultText(result: unknown): string | undefined;
|
|
10
|
-
export declare function outputText(output: unknown): string;
|
|
11
|
-
/** One Runtime event's result for a run: AG-UI events, and whether the run ended. */
|
|
12
|
-
export interface Step {
|
|
13
|
-
readonly events: BaseEvent[];
|
|
14
|
-
readonly finished: boolean;
|
|
15
|
-
}
|
|
16
|
-
/** A tool result from any of the three places a call can end. */
|
|
17
|
-
export declare function toolResultOf(event: TranscriptEvent): {
|
|
18
|
-
callId: string;
|
|
19
|
-
content: string;
|
|
20
|
-
} | undefined;
|
|
21
|
-
export declare class RunTranslator {
|
|
22
|
-
private readonly threadId;
|
|
23
|
-
private readonly runId;
|
|
24
|
-
/** Tool invocation → the model's call id, for interrupts that name the invocation. */
|
|
25
|
-
private readonly callIds;
|
|
26
|
-
private readonly closed;
|
|
27
|
-
private sawAssistant;
|
|
28
|
-
/**
|
|
29
|
-
* `reattached`: the run continues from a cursor, so earlier assistant messages already
|
|
30
|
-
* reached the client and a workflow's output is not repeated as text.
|
|
31
|
-
*/
|
|
32
|
-
constructor(threadId: string, runId: string, options?: {
|
|
33
|
-
reattached?: boolean;
|
|
34
|
-
});
|
|
35
|
-
translate(raw: LiveEvent): Step;
|
|
36
|
-
started(): BaseEvent;
|
|
37
|
-
private finished;
|
|
38
|
-
}
|
package/dist/ag-ui/translate.js
DELETED
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Runtime transcript events → AG-UI 1.0 events for one run. Ids: an assistant message is its
|
|
3
|
-
* model call's `invocationId`, a tool call is the model's `callId`, a tool result is
|
|
4
|
-
* `<callId>:result`, so live runs and `messagesFromEvents` agree.
|
|
5
|
-
*/
|
|
6
|
-
import { EventType } from "@ag-ui/core";
|
|
7
|
-
import { parseTranscriptEvent, } from "@nylorun/core/contracts";
|
|
8
|
-
/** The text a tool result shows; `undefined` while there is no result yet. */
|
|
9
|
-
export function toolResultText(result) {
|
|
10
|
-
const value = result;
|
|
11
|
-
switch (value?.kind) {
|
|
12
|
-
case "completed":
|
|
13
|
-
return outputText(value.output ?? null);
|
|
14
|
-
case "failed":
|
|
15
|
-
return JSON.stringify({ error: value.code, message: value.message });
|
|
16
|
-
case "denied":
|
|
17
|
-
return JSON.stringify({ denied: true, reason: value.reason });
|
|
18
|
-
default:
|
|
19
|
-
// interaction-required and deferred: the call is still open.
|
|
20
|
-
return undefined;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
export function outputText(output) {
|
|
24
|
-
return typeof output === "string" ? output : JSON.stringify(output);
|
|
25
|
-
}
|
|
26
|
-
const none = { events: [], finished: false };
|
|
27
|
-
/** A tool result from any of the three places a call can end. */
|
|
28
|
-
export function toolResultOf(event) {
|
|
29
|
-
switch (event.type) {
|
|
30
|
-
case "action.completed": {
|
|
31
|
-
const p = event.payload;
|
|
32
|
-
if (p.kind !== "tool" || !p.callId || p.agent)
|
|
33
|
-
return undefined;
|
|
34
|
-
const content = toolResultText(p.result);
|
|
35
|
-
return content === undefined ? undefined : { callId: p.callId, content };
|
|
36
|
-
}
|
|
37
|
-
case "tool.completed": {
|
|
38
|
-
const p = event.payload;
|
|
39
|
-
if (p.agent)
|
|
40
|
-
return undefined;
|
|
41
|
-
return {
|
|
42
|
-
callId: p.callId,
|
|
43
|
-
content: p.error !== undefined
|
|
44
|
-
? JSON.stringify({ error: p.error.code, message: p.error.message })
|
|
45
|
-
: outputText(p.output ?? null),
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
case "delegation.completed": {
|
|
49
|
-
// An agent used as a tool: its own work stays inside it; the parent sees the result.
|
|
50
|
-
const p = event.payload;
|
|
51
|
-
if (!p.callId)
|
|
52
|
-
return undefined;
|
|
53
|
-
const content = toolResultText(p.outcome);
|
|
54
|
-
return content === undefined ? undefined : { callId: p.callId, content };
|
|
55
|
-
}
|
|
56
|
-
default:
|
|
57
|
-
return undefined;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
export class RunTranslator {
|
|
61
|
-
threadId;
|
|
62
|
-
runId;
|
|
63
|
-
/** Tool invocation → the model's call id, for interrupts that name the invocation. */
|
|
64
|
-
callIds = new Map();
|
|
65
|
-
closed = new Set();
|
|
66
|
-
sawAssistant;
|
|
67
|
-
/**
|
|
68
|
-
* `reattached`: the run continues from a cursor, so earlier assistant messages already
|
|
69
|
-
* reached the client and a workflow's output is not repeated as text.
|
|
70
|
-
*/
|
|
71
|
-
constructor(threadId, runId, options = {}) {
|
|
72
|
-
this.threadId = threadId;
|
|
73
|
-
this.runId = runId;
|
|
74
|
-
this.sawAssistant = options.reattached ?? false;
|
|
75
|
-
}
|
|
76
|
-
translate(raw) {
|
|
77
|
-
const event = parseTranscriptEvent(raw);
|
|
78
|
-
if (!event)
|
|
79
|
-
return none;
|
|
80
|
-
if (event.type === "action.pending" || event.type === "action.completed") {
|
|
81
|
-
const { callId, invocationId } = event.payload;
|
|
82
|
-
if (callId && invocationId)
|
|
83
|
-
this.callIds.set(invocationId, callId);
|
|
84
|
-
}
|
|
85
|
-
const result = toolResultOf(event);
|
|
86
|
-
if (result) {
|
|
87
|
-
if (this.closed.has(result.callId))
|
|
88
|
-
return none;
|
|
89
|
-
this.closed.add(result.callId);
|
|
90
|
-
return {
|
|
91
|
-
events: [
|
|
92
|
-
{
|
|
93
|
-
type: EventType.TOOL_CALL_RESULT,
|
|
94
|
-
messageId: `${result.callId}:result`,
|
|
95
|
-
toolCallId: result.callId,
|
|
96
|
-
content: result.content,
|
|
97
|
-
role: "tool",
|
|
98
|
-
},
|
|
99
|
-
],
|
|
100
|
-
finished: false,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
switch (event.type) {
|
|
104
|
-
case "message.assistant": {
|
|
105
|
-
const p = event.payload;
|
|
106
|
-
if (p.agent)
|
|
107
|
-
return none;
|
|
108
|
-
this.sawAssistant = true;
|
|
109
|
-
return { events: assistantEvents(p), finished: false };
|
|
110
|
-
}
|
|
111
|
-
case "turn.completed": {
|
|
112
|
-
const p = event.payload;
|
|
113
|
-
// Workflows finish without a model step of their own: show their output.
|
|
114
|
-
const text = this.sawAssistant || p.output === undefined || p.output === null
|
|
115
|
-
? []
|
|
116
|
-
: textEvents(raw.eventId, outputText(p.output));
|
|
117
|
-
return {
|
|
118
|
-
events: [...text, this.finished({ type: "success" }, p.output)],
|
|
119
|
-
finished: true,
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
case "turn.paused": {
|
|
123
|
-
const interrupts = event.payload.interactions.map((w) => {
|
|
124
|
-
const interaction = w.interaction;
|
|
125
|
-
const toolCallId = this.callIds.get(w.invocationId);
|
|
126
|
-
return {
|
|
127
|
-
id: interaction.id,
|
|
128
|
-
reason: interaction.kind === "approval" ? "tool_approval" : "input_required",
|
|
129
|
-
...(typeof interaction.prompt === "string"
|
|
130
|
-
? { message: interaction.prompt }
|
|
131
|
-
: {}),
|
|
132
|
-
...(toolCallId ? { toolCallId } : {}),
|
|
133
|
-
...(interaction.kind === "approval"
|
|
134
|
-
? {
|
|
135
|
-
responseSchema: {
|
|
136
|
-
type: "object",
|
|
137
|
-
properties: { approved: { type: "boolean" } },
|
|
138
|
-
required: ["approved"],
|
|
139
|
-
},
|
|
140
|
-
}
|
|
141
|
-
: {}),
|
|
142
|
-
metadata: { nylorun: { kind: interaction.kind } },
|
|
143
|
-
};
|
|
144
|
-
});
|
|
145
|
-
return {
|
|
146
|
-
events: [this.finished({ type: "interrupt", interrupts })],
|
|
147
|
-
finished: true,
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
case "turn.cancelled":
|
|
151
|
-
return { events: [this.finished({ type: "cancelled" })], finished: true };
|
|
152
|
-
case "turn.failed": {
|
|
153
|
-
const p = event.payload;
|
|
154
|
-
return {
|
|
155
|
-
events: [
|
|
156
|
-
{
|
|
157
|
-
type: EventType.RUN_ERROR,
|
|
158
|
-
message: p.error?.message ?? p.message ?? "The agent failed",
|
|
159
|
-
code: p.error?.code ?? "turn.failed",
|
|
160
|
-
},
|
|
161
|
-
],
|
|
162
|
-
finished: true,
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
case "effect.uncertain":
|
|
166
|
-
case "action.uncertain":
|
|
167
|
-
// The Runtime cannot tell whether a side effect happened; the run goes on.
|
|
168
|
-
return {
|
|
169
|
-
events: [
|
|
170
|
-
{
|
|
171
|
-
type: EventType.CUSTOM,
|
|
172
|
-
name: "nylorun.uncertain",
|
|
173
|
-
value: event.payload,
|
|
174
|
-
},
|
|
175
|
-
],
|
|
176
|
-
finished: false,
|
|
177
|
-
};
|
|
178
|
-
default:
|
|
179
|
-
return none;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
started() {
|
|
183
|
-
return {
|
|
184
|
-
type: EventType.RUN_STARTED,
|
|
185
|
-
threadId: this.threadId,
|
|
186
|
-
runId: this.runId,
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
finished(outcome, result) {
|
|
190
|
-
return {
|
|
191
|
-
type: EventType.RUN_FINISHED,
|
|
192
|
-
threadId: this.threadId,
|
|
193
|
-
runId: this.runId,
|
|
194
|
-
outcome,
|
|
195
|
-
...(result === undefined ? {} : { result }),
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
function textEvents(messageId, text) {
|
|
200
|
-
if (!text)
|
|
201
|
-
return [];
|
|
202
|
-
return [
|
|
203
|
-
{ type: EventType.TEXT_MESSAGE_START, messageId, role: "assistant" },
|
|
204
|
-
{ type: EventType.TEXT_MESSAGE_CONTENT, messageId, delta: text },
|
|
205
|
-
{ type: EventType.TEXT_MESSAGE_END, messageId },
|
|
206
|
-
];
|
|
207
|
-
}
|
|
208
|
-
function assistantEvents(p) {
|
|
209
|
-
const events = textEvents(p.invocationId, p.text);
|
|
210
|
-
for (const call of p.toolCalls)
|
|
211
|
-
events.push({
|
|
212
|
-
type: EventType.TOOL_CALL_START,
|
|
213
|
-
toolCallId: call.callId,
|
|
214
|
-
toolCallName: call.name,
|
|
215
|
-
parentMessageId: p.invocationId,
|
|
216
|
-
}, {
|
|
217
|
-
type: EventType.TOOL_CALL_ARGS,
|
|
218
|
-
toolCallId: call.callId,
|
|
219
|
-
delta: JSON.stringify(call.input ?? {}),
|
|
220
|
-
}, { type: EventType.TOOL_CALL_END, toolCallId: call.callId });
|
|
221
|
-
return events;
|
|
222
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { createHmac } from "node:crypto";
|
|
2
|
-
/**
|
|
3
|
-
* Deterministic executor token from an application key (D§7.3).
|
|
4
|
-
* Same key, Tenant and agent always produce the same token.
|
|
5
|
-
*/
|
|
6
|
-
export function deriveExecutorToken(applicationKey, tenantId, agentId) {
|
|
7
|
-
const message = Buffer.concat([
|
|
8
|
-
Buffer.from("nylorun/executor/v1", "utf8"),
|
|
9
|
-
Buffer.from([0]),
|
|
10
|
-
Buffer.from(tenantId, "utf8"),
|
|
11
|
-
Buffer.from([0]),
|
|
12
|
-
Buffer.from(agentId, "utf8"),
|
|
13
|
-
]);
|
|
14
|
-
return createHmac("sha256", Buffer.from(applicationKey, "utf8"))
|
|
15
|
-
.update(message)
|
|
16
|
-
.digest("hex");
|
|
17
|
-
}
|
package/dist/executor.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { type BuiltWorkflow } from "@nylorun/core/define";
|
|
2
|
-
import { AgentsClient, type AgentSource } from "./client.js";
|
|
3
|
-
import { deriveExecutorToken } from "./derived-credentials.js";
|
|
4
|
-
import { type Destination } from "./http.js";
|
|
5
|
-
export interface ConnectOptions {
|
|
6
|
-
agents: readonly (AgentSource | BuiltWorkflow)[];
|
|
7
|
-
/** Application-mode client; when set, connectAgents uses application mode (D§7.2). */
|
|
8
|
-
application?: AgentsClient;
|
|
9
|
-
runtime?: Destination;
|
|
10
|
-
implementationVersion?: string;
|
|
11
|
-
onError?: (error: unknown) => void;
|
|
12
|
-
}
|
|
13
|
-
export interface AgentConnection {
|
|
14
|
-
/** Settles after authenticated SSE is established and initial discovery succeeds. */
|
|
15
|
-
readonly ready: Promise<void>;
|
|
16
|
-
/** Abort subscriptions and leases. Running user code receives an AbortSignal. */
|
|
17
|
-
close(): Promise<void>;
|
|
18
|
-
}
|
|
19
|
-
export declare function connectAgents(options: ConnectOptions): AgentConnection;
|
|
20
|
-
export { deriveExecutorToken };
|