@nylorun/agents 0.30.0-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 +29 -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/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/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": {
|