@nylorun/agents 0.29.1-beta → 0.31.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 +45 -0
- package/README.md +134 -6
- package/dist/a2a/client-api.d.ts +10 -0
- package/dist/a2a/client-api.js +7 -0
- package/dist/a2a/client.d.ts +178 -0
- package/dist/a2a/client.js +227 -0
- package/dist/a2a/handler.js +7 -1
- package/dist/a2a/index.d.ts +5 -2
- package/dist/a2a/index.js +4 -2
- package/dist/a2a/profile.d.ts +88 -0
- package/dist/a2a/profile.js +133 -0
- package/dist/a2a/push.d.ts +35 -0
- package/dist/a2a/push.js +96 -0
- package/dist/a2a/types.d.ts +145 -0
- package/dist/a2a/types.js +7 -0
- package/dist/compose.js +1 -0
- package/dist/files.d.ts +15 -3
- package/dist/files.js +36 -4
- package/dist/http.js +7 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/session-client.d.ts +5 -0
- package/dist/session-client.js +9 -1
- package/dist/sse.d.ts +19 -2
- package/dist/sse.js +41 -3
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -23,3 +23,5 @@ export { RuntimeError, IncompatibleRuntimeError } from "./http.js";
|
|
|
23
23
|
export { loadMcpServers, loadPlugin, PluginError } from "./plugins/load.js";
|
|
24
24
|
export { hashFolder, loadSkillsFromDirectory, resolveSkillsRoot, parseSkill, SkillsError, } from "./skills/index.js";
|
|
25
25
|
export { McpError } from "./mcp/index.js";
|
|
26
|
+
// The A2A client (`@nylorun/agents/a2a` also has the gateway handler).
|
|
27
|
+
export * from "./a2a/client-api.js";
|
package/dist/session-client.d.ts
CHANGED
|
@@ -439,10 +439,15 @@ export declare class SessionClient {
|
|
|
439
439
|
agent?: string;
|
|
440
440
|
signal?: AbortSignal;
|
|
441
441
|
}): Promise<SessionItemsResponse>;
|
|
442
|
+
/**
|
|
443
|
+
* The session's events from `cursor` on, reconnecting from the last one when the connection
|
|
444
|
+
* drops or sends nothing, keepalives included, for `idleTimeoutMs` (default 45 s; `0` never).
|
|
445
|
+
*/
|
|
442
446
|
observe(options?: {
|
|
443
447
|
cursor?: string;
|
|
444
448
|
signal?: AbortSignal;
|
|
445
449
|
follow?: boolean;
|
|
450
|
+
idleTimeoutMs?: number;
|
|
446
451
|
}): AsyncGenerator<{
|
|
447
452
|
schema: "nylorun.event/2";
|
|
448
453
|
eventId: string;
|
package/dist/session-client.js
CHANGED
|
@@ -279,6 +279,10 @@ export class SessionClient {
|
|
|
279
279
|
...("tail" in page ? { tail: page.tail } : {}),
|
|
280
280
|
};
|
|
281
281
|
}
|
|
282
|
+
/**
|
|
283
|
+
* The session's events from `cursor` on, reconnecting from the last one when the connection
|
|
284
|
+
* drops or sends nothing, keepalives included, for `idleTimeoutMs` (default 45 s; `0` never).
|
|
285
|
+
*/
|
|
282
286
|
async *observe(options = {}) {
|
|
283
287
|
if (!options.follow) {
|
|
284
288
|
yield* this.observeOne(this.id, options);
|
|
@@ -318,7 +322,11 @@ export class SessionClient {
|
|
|
318
322
|
};
|
|
319
323
|
const pump = async (sessionId, cursor) => {
|
|
320
324
|
try {
|
|
321
|
-
for await (const event of this.observeOne(sessionId, {
|
|
325
|
+
for await (const event of this.observeOne(sessionId, {
|
|
326
|
+
cursor,
|
|
327
|
+
signal,
|
|
328
|
+
...(options.idleTimeoutMs !== undefined ? { idleTimeoutMs: options.idleTimeoutMs } : {}),
|
|
329
|
+
})) {
|
|
322
330
|
push(event);
|
|
323
331
|
const link = linkedSessionId(event);
|
|
324
332
|
if (link && link !== this.id && !linked.has(link)) {
|
package/dist/sse.d.ts
CHANGED
|
@@ -4,9 +4,26 @@ export interface SSEEvent {
|
|
|
4
4
|
data: string;
|
|
5
5
|
id?: string;
|
|
6
6
|
}
|
|
7
|
-
/**
|
|
8
|
-
|
|
7
|
+
/**
|
|
8
|
+
* How long a stream may send nothing before the client takes it for dead: the Runtime sends a
|
|
9
|
+
* `: keepalive` comment every 15 s, so three missed ones.
|
|
10
|
+
*/
|
|
11
|
+
export declare const SSE_IDLE_TIMEOUT_MS = 45000;
|
|
12
|
+
/** A stream sent no byte, not even a keepalive, for `idleTimeoutMs`. */
|
|
13
|
+
export declare class SSEIdleTimeoutError extends Error {
|
|
14
|
+
readonly idleTimeoutMs: number;
|
|
15
|
+
constructor(idleTimeoutMs: number);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Fetch-based SSE supports Authorization headers and works in browsers and Node. Any byte,
|
|
19
|
+
* keepalive comments included, counts as liveness; after `idleTimeoutMs` without one the read
|
|
20
|
+
* stops with `SSEIdleTimeoutError` (`0` waits forever).
|
|
21
|
+
*/
|
|
22
|
+
export declare function readSSE(response: Response, signal: AbortSignal, options?: {
|
|
23
|
+
idleTimeoutMs?: number;
|
|
24
|
+
}): AsyncGenerator<SSEEvent>;
|
|
9
25
|
export declare function observeSSE(transport: Transport, path: string, options?: {
|
|
10
26
|
signal?: AbortSignal;
|
|
11
27
|
cursor?: string;
|
|
28
|
+
idleTimeoutMs?: number;
|
|
12
29
|
}): AsyncGenerator<SSEEvent>;
|
package/dist/sse.js
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
import { delay, RuntimeError } from "./http.js";
|
|
2
|
-
/**
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* How long a stream may send nothing before the client takes it for dead: the Runtime sends a
|
|
4
|
+
* `: keepalive` comment every 15 s, so three missed ones.
|
|
5
|
+
*/
|
|
6
|
+
export const SSE_IDLE_TIMEOUT_MS = 45_000;
|
|
7
|
+
/** A stream sent no byte, not even a keepalive, for `idleTimeoutMs`. */
|
|
8
|
+
export class SSEIdleTimeoutError extends Error {
|
|
9
|
+
idleTimeoutMs;
|
|
10
|
+
constructor(idleTimeoutMs) {
|
|
11
|
+
super(`The event stream sent nothing for ${idleTimeoutMs} ms`);
|
|
12
|
+
this.idleTimeoutMs = idleTimeoutMs;
|
|
13
|
+
this.name = "SSEIdleTimeoutError";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Fetch-based SSE supports Authorization headers and works in browsers and Node. Any byte,
|
|
18
|
+
* keepalive comments included, counts as liveness; after `idleTimeoutMs` without one the read
|
|
19
|
+
* stops with `SSEIdleTimeoutError` (`0` waits forever).
|
|
20
|
+
*/
|
|
21
|
+
export async function* readSSE(response, signal, options = {}) {
|
|
4
22
|
if (!response.headers.get("content-type")?.includes("text/event-stream"))
|
|
5
23
|
throw new Error("Expected an SSE response");
|
|
6
24
|
if (!response.body)
|
|
@@ -15,9 +33,22 @@ export async function* readSSE(response, signal) {
|
|
|
15
33
|
void reader.cancel().catch(() => { });
|
|
16
34
|
};
|
|
17
35
|
signal.addEventListener("abort", abort, { once: true });
|
|
36
|
+
const idleTimeoutMs = options.idleTimeoutMs ?? SSE_IDLE_TIMEOUT_MS;
|
|
37
|
+
let idle = false;
|
|
38
|
+
let timer;
|
|
18
39
|
try {
|
|
19
40
|
while (!signal.aborted) {
|
|
41
|
+
// Only the wait for bytes counts, never the time the consumer holds an event. Cancelling
|
|
42
|
+
// the reader ends the pending read, as an abort does.
|
|
43
|
+
if (idleTimeoutMs > 0)
|
|
44
|
+
timer = setTimeout(() => {
|
|
45
|
+
idle = true;
|
|
46
|
+
abort();
|
|
47
|
+
}, idleTimeoutMs);
|
|
20
48
|
const result = await reader.read();
|
|
49
|
+
clearTimeout(timer);
|
|
50
|
+
if (idle)
|
|
51
|
+
throw new SSEIdleTimeoutError(idleTimeoutMs);
|
|
21
52
|
if (result.done)
|
|
22
53
|
break;
|
|
23
54
|
buffer += decoder.decode(result.value, { stream: true });
|
|
@@ -55,6 +86,7 @@ export async function* readSSE(response, signal) {
|
|
|
55
86
|
}
|
|
56
87
|
}
|
|
57
88
|
finally {
|
|
89
|
+
clearTimeout(timer);
|
|
58
90
|
signal.removeEventListener("abort", abort);
|
|
59
91
|
await reader.cancel().catch(() => { });
|
|
60
92
|
reader.releaseLock();
|
|
@@ -78,7 +110,10 @@ export async function* observeSSE(transport, path, options = {}) {
|
|
|
78
110
|
...(cursor ? { "Last-Event-ID": cursor } : {}),
|
|
79
111
|
},
|
|
80
112
|
});
|
|
81
|
-
|
|
113
|
+
const read = readSSE(response, signal, {
|
|
114
|
+
...(options.idleTimeoutMs !== undefined ? { idleTimeoutMs: options.idleTimeoutMs } : {}),
|
|
115
|
+
});
|
|
116
|
+
for await (const event of read) {
|
|
82
117
|
if (event.event === "nylorun.closed") {
|
|
83
118
|
closedByRuntime += 1;
|
|
84
119
|
reconnectNow = closedByRuntime === 1;
|
|
@@ -94,6 +129,9 @@ export async function* observeSSE(transport, path, options = {}) {
|
|
|
94
129
|
catch (error) {
|
|
95
130
|
if (signal.aborted)
|
|
96
131
|
return;
|
|
132
|
+
// A silent stream is a dead connection: open a new one from the last event at once.
|
|
133
|
+
if (error instanceof SSEIdleTimeoutError)
|
|
134
|
+
continue;
|
|
97
135
|
if (error instanceof RuntimeError &&
|
|
98
136
|
error.status >= 400 &&
|
|
99
137
|
error.status < 500 &&
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nylorun/agents",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0-beta",
|
|
4
4
|
"description": "Nylorun agent definitions and session client",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"test": "vitest run --passWithNoTests"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@nylorun/core": "0.
|
|
46
|
+
"@nylorun/core": "0.32.0-beta",
|
|
47
47
|
"gray-matter": "^4.0.3"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|