@pinecall/agents 0.9.20
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/LICENSE +202 -0
- package/README.md +121 -0
- package/dist/agent/accepts.d.ts +31 -0
- package/dist/agent/accepts.d.ts.map +1 -0
- package/dist/agent/accepts.js +27 -0
- package/dist/agent/accepts.js.map +1 -0
- package/dist/agent/agent.d.ts +151 -0
- package/dist/agent/agent.d.ts.map +1 -0
- package/dist/agent/agent.js +240 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/authors.d.ts +12 -0
- package/dist/agent/authors.d.ts.map +1 -0
- package/dist/agent/authors.js +26 -0
- package/dist/agent/authors.js.map +1 -0
- package/dist/agent/decorators.d.ts +16 -0
- package/dist/agent/decorators.d.ts.map +1 -0
- package/dist/agent/decorators.js +43 -0
- package/dist/agent/decorators.js.map +1 -0
- package/dist/agent/docstrings.d.ts +35 -0
- package/dist/agent/docstrings.d.ts.map +1 -0
- package/dist/agent/docstrings.js +301 -0
- package/dist/agent/docstrings.js.map +1 -0
- package/dist/agent/knowledge.d.ts +9 -0
- package/dist/agent/knowledge.d.ts.map +1 -0
- package/dist/agent/knowledge.js +3 -0
- package/dist/agent/knowledge.js.map +1 -0
- package/dist/agent/lifecycle.d.ts +29 -0
- package/dist/agent/lifecycle.d.ts.map +1 -0
- package/dist/agent/lifecycle.js +9 -0
- package/dist/agent/lifecycle.js.map +1 -0
- package/dist/agent/searching.d.ts +7 -0
- package/dist/agent/searching.d.ts.map +1 -0
- package/dist/agent/searching.js +35 -0
- package/dist/agent/searching.js.map +1 -0
- package/dist/agent/stages.d.ts +23 -0
- package/dist/agent/stages.d.ts.map +1 -0
- package/dist/agent/stages.js +29 -0
- package/dist/agent/stages.js.map +1 -0
- package/dist/agent/state.d.ts +36 -0
- package/dist/agent/state.d.ts.map +1 -0
- package/dist/agent/state.js +93 -0
- package/dist/agent/state.js.map +1 -0
- package/dist/agent/tools.d.ts +61 -0
- package/dist/agent/tools.d.ts.map +1 -0
- package/dist/agent/tools.js +145 -0
- package/dist/agent/tools.js.map +1 -0
- package/dist/agent/view.d.ts +29 -0
- package/dist/agent/view.d.ts.map +1 -0
- package/dist/agent/view.js +29 -0
- package/dist/agent/view.js.map +1 -0
- package/dist/agent/visibility.d.ts +32 -0
- package/dist/agent/visibility.d.ts.map +1 -0
- package/dist/agent/visibility.js +77 -0
- package/dist/agent/visibility.js.map +1 -0
- package/dist/call/call.d.ts +137 -0
- package/dist/call/call.d.ts.map +1 -0
- package/dist/call/call.js +228 -0
- package/dist/call/call.js.map +1 -0
- package/dist/call/history.d.ts +28 -0
- package/dist/call/history.d.ts.map +1 -0
- package/dist/call/history.js +32 -0
- package/dist/call/history.js.map +1 -0
- package/dist/call/room.d.ts +56 -0
- package/dist/call/room.d.ts.map +1 -0
- package/dist/call/room.js +66 -0
- package/dist/call/room.js.map +1 -0
- package/dist/client/agent.d.ts +93 -0
- package/dist/client/agent.d.ts.map +1 -0
- package/dist/client/agent.js +230 -0
- package/dist/client/agent.js.map +1 -0
- package/dist/client/calls.d.ts +87 -0
- package/dist/client/calls.d.ts.map +1 -0
- package/dist/client/calls.js +180 -0
- package/dist/client/calls.js.map +1 -0
- package/dist/client/client.d.ts +112 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +284 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/connection.d.ts +52 -0
- package/dist/client/connection.d.ts.map +1 -0
- package/dist/client/connection.js +157 -0
- package/dist/client/connection.js.map +1 -0
- package/dist/client/endpoints.d.ts +9 -0
- package/dist/client/endpoints.d.ts.map +1 -0
- package/dist/client/endpoints.js +25 -0
- package/dist/client/endpoints.js.map +1 -0
- package/dist/client/frames.d.ts +29 -0
- package/dist/client/frames.d.ts.map +1 -0
- package/dist/client/frames.js +51 -0
- package/dist/client/frames.js.map +1 -0
- package/dist/client/index.d.ts +18 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +13 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/listeners.d.ts +35 -0
- package/dist/client/listeners.d.ts.map +1 -0
- package/dist/client/listeners.js +60 -0
- package/dist/client/listeners.js.map +1 -0
- package/dist/client/lost.d.ts +4 -0
- package/dist/client/lost.d.ts.map +1 -0
- package/dist/client/lost.js +8 -0
- package/dist/client/lost.js.map +1 -0
- package/dist/client/observe.d.ts +50 -0
- package/dist/client/observe.d.ts.map +1 -0
- package/dist/client/observe.js +125 -0
- package/dist/client/observe.js.map +1 -0
- package/dist/client/signed.d.ts +14 -0
- package/dist/client/signed.d.ts.map +1 -0
- package/dist/client/signed.js +18 -0
- package/dist/client/signed.js.map +1 -0
- package/dist/client/testing/gateway.d.ts +58 -0
- package/dist/client/testing/gateway.d.ts.map +1 -0
- package/dist/client/testing/gateway.js +175 -0
- package/dist/client/testing/gateway.js.map +1 -0
- package/dist/client/testing/index.d.ts +4 -0
- package/dist/client/testing/index.d.ts.map +1 -0
- package/dist/client/testing/index.js +4 -0
- package/dist/client/testing/index.js.map +1 -0
- package/dist/client/testing/log.d.ts +24 -0
- package/dist/client/testing/log.d.ts.map +1 -0
- package/dist/client/testing/log.js +106 -0
- package/dist/client/testing/log.js.map +1 -0
- package/dist/client/testing/loopback.d.ts +3 -0
- package/dist/client/testing/loopback.d.ts.map +1 -0
- package/dist/client/testing/loopback.js +3 -0
- package/dist/client/testing/loopback.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime/connect.d.ts +42 -0
- package/dist/runtime/connect.d.ts.map +1 -0
- package/dist/runtime/connect.js +234 -0
- package/dist/runtime/connect.js.map +1 -0
- package/dist/runtime/dispatch.d.ts +32 -0
- package/dist/runtime/dispatch.d.ts.map +1 -0
- package/dist/runtime/dispatch.js +46 -0
- package/dist/runtime/dispatch.js.map +1 -0
- package/dist/runtime/environment.d.ts +7 -0
- package/dist/runtime/environment.d.ts.map +1 -0
- package/dist/runtime/environment.js +30 -0
- package/dist/runtime/environment.js.map +1 -0
- package/dist/runtime/recall.d.ts +9 -0
- package/dist/runtime/recall.d.ts.map +1 -0
- package/dist/runtime/recall.js +13 -0
- package/dist/runtime/recall.js.map +1 -0
- package/dist/runtime/run-tool.d.ts +18 -0
- package/dist/runtime/run-tool.d.ts.map +1 -0
- package/dist/runtime/run-tool.js +70 -0
- package/dist/runtime/run-tool.js.map +1 -0
- package/dist/serve/index.d.ts +5 -0
- package/dist/serve/index.d.ts.map +1 -0
- package/dist/serve/index.js +50 -0
- package/dist/serve/index.js.map +1 -0
- package/dist/serve/io.d.ts +14 -0
- package/dist/serve/io.d.ts.map +1 -0
- package/dist/serve/io.js +6 -0
- package/dist/serve/io.js.map +1 -0
- package/dist/serve/leaving.d.ts +12 -0
- package/dist/serve/leaving.d.ts.map +1 -0
- package/dist/serve/leaving.js +61 -0
- package/dist/serve/leaving.js.map +1 -0
- package/dist/serve/lines.d.ts +7 -0
- package/dist/serve/lines.d.ts.map +1 -0
- package/dist/serve/lines.js +25 -0
- package/dist/serve/lines.js.map +1 -0
- package/dist/serve/load.d.ts +26 -0
- package/dist/serve/load.d.ts.map +1 -0
- package/dist/serve/load.js +61 -0
- package/dist/serve/load.js.map +1 -0
- package/dist/serve/machine.d.ts +4 -0
- package/dist/serve/machine.d.ts.map +1 -0
- package/dist/serve/machine.js +33 -0
- package/dist/serve/machine.js.map +1 -0
- package/dist/serve/prompt.d.ts +7 -0
- package/dist/serve/prompt.d.ts.map +1 -0
- package/dist/serve/prompt.js +51 -0
- package/dist/serve/prompt.js.map +1 -0
- package/dist/serve/start.d.ts +7 -0
- package/dist/serve/start.d.ts.map +1 -0
- package/dist/serve/start.js +95 -0
- package/dist/serve/start.js.map +1 -0
- package/dist/serve/viewing.d.ts +17 -0
- package/dist/serve/viewing.d.ts.map +1 -0
- package/dist/serve/viewing.js +42 -0
- package/dist/serve/viewing.js.map +1 -0
- package/dist/views/built-in-rules.d.ts +9 -0
- package/dist/views/built-in-rules.d.ts.map +1 -0
- package/dist/views/built-in-rules.js +28 -0
- package/dist/views/built-in-rules.js.map +1 -0
- package/dist/views/components.d.ts +17 -0
- package/dist/views/components.d.ts.map +1 -0
- package/dist/views/components.js +33 -0
- package/dist/views/components.js.map +1 -0
- package/dist/views/jsx-dev-runtime.d.ts +3 -0
- package/dist/views/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/views/jsx-dev-runtime.js +4 -0
- package/dist/views/jsx-dev-runtime.js.map +1 -0
- package/dist/views/jsx-runtime.d.ts +46 -0
- package/dist/views/jsx-runtime.d.ts.map +1 -0
- package/dist/views/jsx-runtime.js +63 -0
- package/dist/views/jsx-runtime.js.map +1 -0
- package/dist/views/layout.d.ts +19 -0
- package/dist/views/layout.d.ts.map +1 -0
- package/dist/views/layout.js +58 -0
- package/dist/views/layout.js.map +1 -0
- package/dist/views/nodes.d.ts +48 -0
- package/dist/views/nodes.d.ts.map +1 -0
- package/dist/views/nodes.js +45 -0
- package/dist/views/nodes.js.map +1 -0
- package/dist/views/panels.d.ts +17 -0
- package/dist/views/panels.d.ts.map +1 -0
- package/dist/views/panels.js +62 -0
- package/dist/views/panels.js.map +1 -0
- package/dist/views/render.d.ts +11 -0
- package/dist/views/render.d.ts.map +1 -0
- package/dist/views/render.js +19 -0
- package/dist/views/render.js.map +1 -0
- package/dist/wire/agent-config.d.ts +213 -0
- package/dist/wire/agent-config.d.ts.map +1 -0
- package/dist/wire/agent-config.js +126 -0
- package/dist/wire/agent-config.js.map +1 -0
- package/dist/wire/codec.d.ts +43 -0
- package/dist/wire/codec.d.ts.map +1 -0
- package/dist/wire/codec.js +51 -0
- package/dist/wire/codec.js.map +1 -0
- package/dist/wire/commands.d.ts +443 -0
- package/dist/wire/commands.d.ts.map +1 -0
- package/dist/wire/commands.js +203 -0
- package/dist/wire/commands.js.map +1 -0
- package/dist/wire/defs.d.ts +373 -0
- package/dist/wire/defs.d.ts.map +1 -0
- package/dist/wire/defs.js +212 -0
- package/dist/wire/defs.js.map +1 -0
- package/dist/wire/envelope.d.ts +29 -0
- package/dist/wire/envelope.d.ts.map +1 -0
- package/dist/wire/envelope.js +27 -0
- package/dist/wire/envelope.js.map +1 -0
- package/dist/wire/events-call.d.ts +446 -0
- package/dist/wire/events-call.d.ts.map +1 -0
- package/dist/wire/events-call.js +196 -0
- package/dist/wire/events-call.js.map +1 -0
- package/dist/wire/events.d.ts +946 -0
- package/dist/wire/events.d.ts.map +1 -0
- package/dist/wire/events.js +309 -0
- package/dist/wire/events.js.map +1 -0
- package/dist/wire/index.d.ts +19 -0
- package/dist/wire/index.d.ts.map +1 -0
- package/dist/wire/index.js +19 -0
- package/dist/wire/index.js.map +1 -0
- package/dist/wire/metrics.d.ts +366 -0
- package/dist/wire/metrics.d.ts.map +1 -0
- package/dist/wire/metrics.js +269 -0
- package/dist/wire/metrics.js.map +1 -0
- package/dist/wire/reduce.d.ts +10 -0
- package/dist/wire/reduce.d.ts.map +1 -0
- package/dist/wire/reduce.js +367 -0
- package/dist/wire/reduce.js.map +1 -0
- package/dist/wire/registry.d.ts +1789 -0
- package/dist/wire/registry.d.ts.map +1 -0
- package/dist/wire/registry.js +118 -0
- package/dist/wire/registry.js.map +1 -0
- package/dist/wire/rest-data.d.ts +170 -0
- package/dist/wire/rest-data.d.ts.map +1 -0
- package/dist/wire/rest-data.js +78 -0
- package/dist/wire/rest-data.js.map +1 -0
- package/dist/wire/rest-hosting.d.ts +74 -0
- package/dist/wire/rest-hosting.d.ts.map +1 -0
- package/dist/wire/rest-hosting.js +38 -0
- package/dist/wire/rest-hosting.js.map +1 -0
- package/dist/wire/rest-retrieval.d.ts +214 -0
- package/dist/wire/rest-retrieval.d.ts.map +1 -0
- package/dist/wire/rest-retrieval.js +161 -0
- package/dist/wire/rest-retrieval.js.map +1 -0
- package/dist/wire/rest.d.ts +786 -0
- package/dist/wire/rest.d.ts.map +1 -0
- package/dist/wire/rest.js +238 -0
- package/dist/wire/rest.js.map +1 -0
- package/dist/wire/room.d.ts +106 -0
- package/dist/wire/room.d.ts.map +1 -0
- package/dist/wire/room.js +73 -0
- package/dist/wire/room.js.map +1 -0
- package/dist/wire/state.d.ts +915 -0
- package/dist/wire/state.d.ts.map +1 -0
- package/dist/wire/state.js +189 -0
- package/dist/wire/state.js.map +1 -0
- package/dist/wire/verbs.d.ts +73 -0
- package/dist/wire/verbs.d.ts.map +1 -0
- package/dist/wire/verbs.js +50 -0
- package/dist/wire/verbs.js.map +1 -0
- package/package.json +74 -0
- package/tsconfig.tenant.json +24 -0
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
// The client: one socket, the agents registered on it, and log reads for the key's org.
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { hostname } from "node:os";
|
|
4
|
+
import { eventOf } from "../wire/codec.js";
|
|
5
|
+
import {} from "../wire/envelope.js";
|
|
6
|
+
import {} from "../wire/registry.js";
|
|
7
|
+
import { Agent } from "./agent.js";
|
|
8
|
+
import { Connection } from "./connection.js";
|
|
9
|
+
import { lookupUrl } from "./endpoints.js";
|
|
10
|
+
import { PinecallError, frame } from "./frames.js";
|
|
11
|
+
import { Listeners, asError } from "./listeners.js";
|
|
12
|
+
import { history, observe } from "./observe.js";
|
|
13
|
+
import { signed } from "./signed.js";
|
|
14
|
+
// Two levels up from both dist/client/ and src/client/.
|
|
15
|
+
const { version } = createRequire(import.meta.url)("../../package.json");
|
|
16
|
+
// `error` code sent when an org member stops this app (`POST /v1/apps/{app}/stop`). The client must
|
|
17
|
+
// not reconnect afterwards, or the stop would have no effect.
|
|
18
|
+
const STOPPED = "stopped";
|
|
19
|
+
// Should fit inside the process manager's shutdown grace period.
|
|
20
|
+
const DEFAULT_TOOLS_MS = 30_000;
|
|
21
|
+
/**
|
|
22
|
+
* One app's connection to Pinecall.
|
|
23
|
+
*
|
|
24
|
+
* `url` and `apiKey` must be passed explicitly; nothing is read from the environment, so a stale
|
|
25
|
+
* `PINECALL_API_KEY` (also used by the v1 SDK) can never select the wrong org.
|
|
26
|
+
*/
|
|
27
|
+
export class Pinecall {
|
|
28
|
+
sdk;
|
|
29
|
+
/** This machine's hostname, shown by the gateway next to the app. */
|
|
30
|
+
host = hostname();
|
|
31
|
+
/** The gateway this client talks to. */
|
|
32
|
+
url;
|
|
33
|
+
/** The API key. Sent in a header, never in a URL. */
|
|
34
|
+
apiKey;
|
|
35
|
+
/** The requested world, or undefined to use the key's own. */
|
|
36
|
+
env;
|
|
37
|
+
#agents = new Map();
|
|
38
|
+
#listeners;
|
|
39
|
+
#errors = new Set();
|
|
40
|
+
#connects = new Set();
|
|
41
|
+
#stops = new Set();
|
|
42
|
+
#entries = new Set();
|
|
43
|
+
#connection;
|
|
44
|
+
constructor(options = {}) {
|
|
45
|
+
const { url, apiKey } = options;
|
|
46
|
+
if (url === undefined || apiKey === undefined) {
|
|
47
|
+
throw new PinecallError("new Pinecall({ url, apiKey }): one of the two was not given");
|
|
48
|
+
}
|
|
49
|
+
this.url = url;
|
|
50
|
+
this.apiKey = apiKey;
|
|
51
|
+
this.env = options.env;
|
|
52
|
+
this.sdk = options.sdk ?? `pinecall/${version}`;
|
|
53
|
+
this.#listeners = new Listeners((error) => this.onError(error));
|
|
54
|
+
const dial = { url, apiKey, ...(options.env === undefined ? {} : { env: options.env }) };
|
|
55
|
+
if (options.pingMs !== undefined) {
|
|
56
|
+
dial.pingMs = options.pingMs;
|
|
57
|
+
}
|
|
58
|
+
if (options.backoff !== undefined) {
|
|
59
|
+
dial.backoff = options.backoff;
|
|
60
|
+
}
|
|
61
|
+
this.#connection = new Connection(dial, {
|
|
62
|
+
onOpen: () => this.#declareAll(),
|
|
63
|
+
onEntry: (entry) => this.#take(entry),
|
|
64
|
+
onError: (error) => this.onError(error),
|
|
65
|
+
onHeartbeat: () => this.#pingAll(),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/** Declare an agent this app serves. Nothing is sent until `connect`. */
|
|
69
|
+
agent(slug, options = {}) {
|
|
70
|
+
const agent = new Agent(slug, options, this);
|
|
71
|
+
this.#agents.set(slug, agent);
|
|
72
|
+
return agent;
|
|
73
|
+
}
|
|
74
|
+
/** Open the socket, register every agent and send its declaration. */
|
|
75
|
+
async connect() {
|
|
76
|
+
await this.#connection.start();
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Shut down without cutting calls: each agent drains (live calls move to another holder or are
|
|
80
|
+
* parked) and running tools get up to `toolsMs` to finish. Does not close the socket; call
|
|
81
|
+
* `close()` afterwards.
|
|
82
|
+
*/
|
|
83
|
+
async drain({ answerMs, toolsMs = DEFAULT_TOOLS_MS } = {}) {
|
|
84
|
+
this.#connection.leaving();
|
|
85
|
+
const agents = [...this.#agents.values()];
|
|
86
|
+
const done = { handed: 0, parked: 0, tools: 0, finished: 0 };
|
|
87
|
+
if (!this.connected)
|
|
88
|
+
return done;
|
|
89
|
+
const answers = await Promise.allSettled(agents.map((agent) => agent.drain(answerMs)));
|
|
90
|
+
for (const answer of answers) {
|
|
91
|
+
if (answer.status === "fulfilled") {
|
|
92
|
+
done.handed += answer.value.handed;
|
|
93
|
+
done.parked += answer.value.parked;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
this.onError(asError(answer.reason));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
done.tools = agents.reduce((sum, agent) => sum + agent.inFlight, 0);
|
|
100
|
+
let timer;
|
|
101
|
+
const cap = new Promise((resolve) => {
|
|
102
|
+
timer = setTimeout(resolve, toolsMs);
|
|
103
|
+
});
|
|
104
|
+
await Promise.race([Promise.all(agents.map((agent) => agent.settled())), cap]);
|
|
105
|
+
clearTimeout(timer);
|
|
106
|
+
done.finished = done.tools - agents.reduce((sum, agent) => sum + agent.inFlight, 0);
|
|
107
|
+
return done;
|
|
108
|
+
}
|
|
109
|
+
/** Close the socket without reconnecting. Every agent's slug is released. */
|
|
110
|
+
close() {
|
|
111
|
+
this.#connection.close();
|
|
112
|
+
}
|
|
113
|
+
/** True while the socket is up. */
|
|
114
|
+
get connected() {
|
|
115
|
+
return this.#connection.open;
|
|
116
|
+
}
|
|
117
|
+
/** Listen for one event type across every agent on this client. */
|
|
118
|
+
on(type, listener) {
|
|
119
|
+
return this.#listeners.on(type, listener);
|
|
120
|
+
}
|
|
121
|
+
/** Listen for every event across every agent. */
|
|
122
|
+
onAny(listener) {
|
|
123
|
+
return this.#listeners.onAny(listener);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Called after each (re)connect once every agent is declared. Use it to re-send state the
|
|
127
|
+
* gateway keeps only for a live socket.
|
|
128
|
+
*/
|
|
129
|
+
onConnected(listener) {
|
|
130
|
+
this.#connects.add(listener);
|
|
131
|
+
return () => {
|
|
132
|
+
this.#connects.delete(listener);
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Called when an org member stops this app. The socket is closed for good; the app decides what
|
|
137
|
+
* to do next (usually exit).
|
|
138
|
+
*/
|
|
139
|
+
onStopped(listener) {
|
|
140
|
+
this.#stops.add(listener);
|
|
141
|
+
return () => {
|
|
142
|
+
this.#stops.delete(listener);
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Every entry the socket receives, as the gateway wrote it (snake_case), before any agent takes
|
|
147
|
+
* it — other agents' entries and the client's own errors included.
|
|
148
|
+
*/
|
|
149
|
+
onEntries(listener) {
|
|
150
|
+
this.#entries.add(listener);
|
|
151
|
+
return () => {
|
|
152
|
+
this.#entries.delete(listener);
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
/** Receive errors no caller awaits (bad frames, listener throws, socket loss). Defaults to `console.error`. */
|
|
156
|
+
onErrors(listener) {
|
|
157
|
+
this.#errors.add(listener);
|
|
158
|
+
return () => {
|
|
159
|
+
this.#errors.delete(listener);
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/** Stream a log live, folded by the protocol's reducer. */
|
|
163
|
+
observe(target, options = {}) {
|
|
164
|
+
return observe(target, this.#reading(options));
|
|
165
|
+
}
|
|
166
|
+
/** Read one page of a log and its folded state. */
|
|
167
|
+
async history(target, options = {}) {
|
|
168
|
+
return history(target, this.#reading(options));
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Search the agent's knowledge bases on behalf of a call this client serves. The gateway runs
|
|
172
|
+
* the search and logs it.
|
|
173
|
+
* @param k Number of chunks; defaults to the base's setting.
|
|
174
|
+
*/
|
|
175
|
+
async search(call, query, k) {
|
|
176
|
+
const answered = await fetch(lookupUrl(this.url, call), {
|
|
177
|
+
method: "POST",
|
|
178
|
+
headers: { ...signed(this.apiKey, this.env), "content-type": "application/json" },
|
|
179
|
+
body: JSON.stringify({ tool: "search", input: k === undefined ? { query } : { query, k } }),
|
|
180
|
+
});
|
|
181
|
+
const text = await answered.text();
|
|
182
|
+
if (!answered.ok)
|
|
183
|
+
throw new PinecallError(`search: the gateway answered ${answered.status}: ${detailOf(text)}`);
|
|
184
|
+
return JSON.parse(text).output.chunks;
|
|
185
|
+
}
|
|
186
|
+
// ── what the agents send through ────────────────────────────────────────────
|
|
187
|
+
/** Send one command frame, validated against its schema. */
|
|
188
|
+
send(type, agent, call, data, id) {
|
|
189
|
+
this.#connection.send(frame(type, agent, call, data, id));
|
|
190
|
+
}
|
|
191
|
+
/** Emit an event an agent has handled to the client-wide listeners. */
|
|
192
|
+
seen(event, call) {
|
|
193
|
+
this.#listeners.emit(event, call);
|
|
194
|
+
}
|
|
195
|
+
/** Report an error no caller awaits. */
|
|
196
|
+
onError(error) {
|
|
197
|
+
if (this.#errors.size === 0) {
|
|
198
|
+
console.error(error);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
for (const listener of this.#errors) {
|
|
202
|
+
listener(error);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
#take(entry) {
|
|
206
|
+
for (const listener of this.#entries) {
|
|
207
|
+
try {
|
|
208
|
+
listener(entry);
|
|
209
|
+
}
|
|
210
|
+
catch (failed) {
|
|
211
|
+
this.onError(asError(failed));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (entry.type === "error" && entry.agent === "") {
|
|
215
|
+
const said = eventOf(entry);
|
|
216
|
+
if (said.type === "error" && said.data.code === STOPPED)
|
|
217
|
+
return this.#stopped(said.data.message);
|
|
218
|
+
}
|
|
219
|
+
const agent = this.#agents.get(entry.agent);
|
|
220
|
+
if (agent === undefined) {
|
|
221
|
+
// Not one of ours: the socket may carry other agents' entries.
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
try {
|
|
225
|
+
agent.take(entry);
|
|
226
|
+
}
|
|
227
|
+
catch (failed) {
|
|
228
|
+
this.onError(asError(failed));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// With no stop listener, report the stop as an error so it is not silent.
|
|
232
|
+
#stopped(why) {
|
|
233
|
+
this.#connection.close();
|
|
234
|
+
if (this.#stops.size === 0) {
|
|
235
|
+
this.onError(new PinecallError(why));
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
for (const listener of this.#stops) {
|
|
239
|
+
try {
|
|
240
|
+
listener(why);
|
|
241
|
+
}
|
|
242
|
+
catch (failed) {
|
|
243
|
+
this.onError(asError(failed));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
async #declareAll() {
|
|
248
|
+
for (const agent of this.#agents.values()) {
|
|
249
|
+
await agent.open();
|
|
250
|
+
}
|
|
251
|
+
for (const listener of this.#connects) {
|
|
252
|
+
try {
|
|
253
|
+
listener();
|
|
254
|
+
}
|
|
255
|
+
catch (failed) {
|
|
256
|
+
this.onError(asError(failed));
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
#pingAll() {
|
|
261
|
+
for (const agent of this.#agents.values()) {
|
|
262
|
+
try {
|
|
263
|
+
agent.ping();
|
|
264
|
+
}
|
|
265
|
+
catch (failed) {
|
|
266
|
+
this.onError(asError(failed));
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
#reading(options) {
|
|
271
|
+
return { url: this.url, apiKey: this.apiKey, ...(this.env === undefined ? {} : { env: this.env }), ...options };
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/** The `detail` of an error body, or the raw body. */
|
|
275
|
+
function detailOf(text) {
|
|
276
|
+
try {
|
|
277
|
+
const parsed = JSON.parse(text);
|
|
278
|
+
return typeof parsed.detail === "string" ? parsed.detail : text;
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
return text;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type Command, type Entry } from "../wire/envelope.js";
|
|
2
|
+
import { type World } from "./signed.js";
|
|
3
|
+
/** Reconnect backoff: first delay, cap, and growth factor. */
|
|
4
|
+
export interface Backoff {
|
|
5
|
+
firstMs: number;
|
|
6
|
+
capMs: number;
|
|
7
|
+
factor: number;
|
|
8
|
+
}
|
|
9
|
+
/** Options for a `Connection`. */
|
|
10
|
+
export interface ConnectionOptions {
|
|
11
|
+
url: string;
|
|
12
|
+
apiKey: string;
|
|
13
|
+
/** The world to register agents in; omitted means sandbox. See `signed.ts`. */
|
|
14
|
+
env?: World;
|
|
15
|
+
pingMs?: number;
|
|
16
|
+
backoff?: Partial<Backoff>;
|
|
17
|
+
}
|
|
18
|
+
/** Callbacks a `Connection` drives. */
|
|
19
|
+
export interface ConnectionHandlers {
|
|
20
|
+
/** The socket is up; re-send registrations before anything else. */
|
|
21
|
+
onOpen: () => Promise<void>;
|
|
22
|
+
/** One decoded log entry. */
|
|
23
|
+
onEntry: (entry: Entry) => void;
|
|
24
|
+
/** An unreadable frame, a throwing handler, or a socket failure. */
|
|
25
|
+
onError: (error: Error) => void;
|
|
26
|
+
/** Fired every `pingMs` while the socket is up. */
|
|
27
|
+
onHeartbeat: () => void;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* One gateway connection across reconnects. The key is sent as `Authorization: Bearer` on the
|
|
31
|
+
* upgrade, never in the URL, which would end up in access logs.
|
|
32
|
+
*/
|
|
33
|
+
export declare class Connection {
|
|
34
|
+
#private;
|
|
35
|
+
private readonly options;
|
|
36
|
+
private readonly handlers;
|
|
37
|
+
constructor(options: ConnectionOptions, handlers: ConnectionHandlers);
|
|
38
|
+
/** True while the socket is open. */
|
|
39
|
+
get open(): boolean;
|
|
40
|
+
/** Open the socket and resolve once `onOpen` has run. Later drops reconnect automatically. */
|
|
41
|
+
start(): Promise<void>;
|
|
42
|
+
/** Send one command. Throws if the socket is down; nothing is queued. */
|
|
43
|
+
send(command: Command): void;
|
|
44
|
+
/**
|
|
45
|
+
* Keep the current socket but never reconnect. A reconnect mid-drain would re-register the
|
|
46
|
+
* agents and be handed the calls the drain just moved.
|
|
47
|
+
*/
|
|
48
|
+
leaving(): void;
|
|
49
|
+
/** Close the socket without reconnecting. */
|
|
50
|
+
close(): void;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/client/connection.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAK/D,OAAO,EAAU,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAEjD,8DAA8D;AAC9D,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,kCAAkC;AAClC,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,GAAG,CAAC,EAAE,KAAK,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5B;AAED,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IACjC,oEAAoE;IACpE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,6BAA6B;IAC7B,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAChC,oEAAoE;IACpE,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAChC,mDAAmD;IACnD,WAAW,EAAE,MAAM,IAAI,CAAC;CACzB;AAQD;;;GAGG;AACH,qBAAa,UAAU;;IAYnB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAF3B,YACmB,OAAO,EAAE,iBAAiB,EAC1B,QAAQ,EAAE,kBAAkB,EAI9C;IAED,qCAAqC;IACrC,IAAI,IAAI,IAAI,OAAO,CAElB;IAED,8FAA8F;IACxF,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAa3B;IAED,yEAAyE;IACzE,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAM3B;IAED;;;OAGG;IACH,OAAO,IAAI,IAAI,CAId;IAED,6CAA6C;IAC7C,KAAK,IAAI,IAAI,CAKZ;CAgFF"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// The gateway socket: authentication, reconnect with backoff, and heartbeat pings.
|
|
2
|
+
import { decodeEntry } from "../wire/codec.js";
|
|
3
|
+
import {} from "../wire/envelope.js";
|
|
4
|
+
import WebSocket from "ws";
|
|
5
|
+
import { appsUrl } from "./endpoints.js";
|
|
6
|
+
import { PinecallError } from "./frames.js";
|
|
7
|
+
import { asError } from "./listeners.js";
|
|
8
|
+
import { signed } from "./signed.js";
|
|
9
|
+
const DEFAULT_BACKOFF = { firstMs: 500, capMs: 30_000, factor: 2 };
|
|
10
|
+
const DEFAULT_PING_MS = 30_000;
|
|
11
|
+
// RFC 6455 policy violation: the gateway refused the key for this socket. Reported, not retried.
|
|
12
|
+
const POLICY_VIOLATION = 1008;
|
|
13
|
+
/**
|
|
14
|
+
* One gateway connection across reconnects. The key is sent as `Authorization: Bearer` on the
|
|
15
|
+
* upgrade, never in the URL, which would end up in access logs.
|
|
16
|
+
*/
|
|
17
|
+
export class Connection {
|
|
18
|
+
options;
|
|
19
|
+
handlers;
|
|
20
|
+
#socket = null;
|
|
21
|
+
#reconnect = null;
|
|
22
|
+
#ping = null;
|
|
23
|
+
#attempt = 0;
|
|
24
|
+
#closed = false;
|
|
25
|
+
#failed = null;
|
|
26
|
+
#opened = null;
|
|
27
|
+
#backoff;
|
|
28
|
+
#pingMs;
|
|
29
|
+
constructor(options, handlers) {
|
|
30
|
+
this.options = options;
|
|
31
|
+
this.handlers = handlers;
|
|
32
|
+
this.#backoff = { ...DEFAULT_BACKOFF, ...options.backoff };
|
|
33
|
+
this.#pingMs = options.pingMs ?? DEFAULT_PING_MS;
|
|
34
|
+
}
|
|
35
|
+
/** True while the socket is open. */
|
|
36
|
+
get open() {
|
|
37
|
+
return this.#socket?.readyState === WebSocket.OPEN;
|
|
38
|
+
}
|
|
39
|
+
/** Open the socket and resolve once `onOpen` has run. Later drops reconnect automatically. */
|
|
40
|
+
async start() {
|
|
41
|
+
this.#closed = false;
|
|
42
|
+
return new Promise((resolve, reject) => {
|
|
43
|
+
this.#opened = (error) => {
|
|
44
|
+
this.#opened = null;
|
|
45
|
+
if (error) {
|
|
46
|
+
reject(error);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
resolve();
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
this.#dial();
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/** Send one command. Throws if the socket is down; nothing is queued. */
|
|
56
|
+
send(command) {
|
|
57
|
+
const socket = this.#socket;
|
|
58
|
+
if (socket === null || socket.readyState !== WebSocket.OPEN) {
|
|
59
|
+
throw new PinecallError(`${command.type}: the gateway is not connected`);
|
|
60
|
+
}
|
|
61
|
+
socket.send(JSON.stringify(command));
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Keep the current socket but never reconnect. A reconnect mid-drain would re-register the
|
|
65
|
+
* agents and be handed the calls the drain just moved.
|
|
66
|
+
*/
|
|
67
|
+
leaving() {
|
|
68
|
+
this.#closed = true;
|
|
69
|
+
if (this.#reconnect !== null)
|
|
70
|
+
clearTimeout(this.#reconnect);
|
|
71
|
+
this.#reconnect = null;
|
|
72
|
+
}
|
|
73
|
+
/** Close the socket without reconnecting. */
|
|
74
|
+
close() {
|
|
75
|
+
this.#closed = true;
|
|
76
|
+
this.#stopTimers();
|
|
77
|
+
this.#socket?.close();
|
|
78
|
+
this.#socket = null;
|
|
79
|
+
}
|
|
80
|
+
#dial() {
|
|
81
|
+
const socket = new WebSocket(appsUrl(this.options.url), {
|
|
82
|
+
headers: signed(this.options.apiKey, this.options.env),
|
|
83
|
+
});
|
|
84
|
+
this.#socket = socket;
|
|
85
|
+
socket.on("open", () => void this.#onOpen());
|
|
86
|
+
socket.on("message", (raw) => this.#onMessage(raw));
|
|
87
|
+
socket.on("error", (failed) => {
|
|
88
|
+
this.#failed = failed;
|
|
89
|
+
this.handlers.onError(failed);
|
|
90
|
+
});
|
|
91
|
+
socket.on("close", (code, reason) => this.#onClose(code, reason.toString()));
|
|
92
|
+
}
|
|
93
|
+
async #onOpen() {
|
|
94
|
+
this.#attempt = 0;
|
|
95
|
+
this.#failed = null;
|
|
96
|
+
try {
|
|
97
|
+
await this.handlers.onOpen();
|
|
98
|
+
}
|
|
99
|
+
catch (failed) {
|
|
100
|
+
// Report once: as `start`'s rejection on first connect, otherwise through onError.
|
|
101
|
+
if (this.#opened === null) {
|
|
102
|
+
this.handlers.onError(asError(failed));
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
this.#opened(asError(failed));
|
|
106
|
+
}
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
this.#ping = setInterval(() => this.handlers.onHeartbeat(), this.#pingMs);
|
|
110
|
+
this.#opened?.();
|
|
111
|
+
}
|
|
112
|
+
#onMessage(raw) {
|
|
113
|
+
try {
|
|
114
|
+
this.handlers.onEntry(decodeEntry(JSON.parse(raw.toString())));
|
|
115
|
+
}
|
|
116
|
+
catch (failed) {
|
|
117
|
+
this.handlers.onError(asError(failed));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
#onClose(code, reason) {
|
|
121
|
+
this.#stopTimers();
|
|
122
|
+
this.#socket = null;
|
|
123
|
+
if (this.#closed) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
// Prefer the close reason: the gateway explains refusals there. Fall back to the code.
|
|
127
|
+
const why = new PinecallError(`the gateway refused the socket: ${this.#failed?.message ?? (reason || `closed with ${code}`)}`);
|
|
128
|
+
// A failed first connect rejects `start`; later closes are retried.
|
|
129
|
+
if (this.#opened !== null) {
|
|
130
|
+
this.#opened(why);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
// Except a refusal: retrying a key that lacks the scope would loop silently forever.
|
|
134
|
+
if (code === POLICY_VIOLATION) {
|
|
135
|
+
this.#closed = true;
|
|
136
|
+
this.handlers.onError(why);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
this.#reconnect = setTimeout(() => this.#dial(), this.#waitMs());
|
|
140
|
+
}
|
|
141
|
+
// Full jitter, so clients that lost the same gateway don't reconnect in lockstep.
|
|
142
|
+
#waitMs() {
|
|
143
|
+
const window = Math.min(this.#backoff.capMs, this.#backoff.firstMs * this.#backoff.factor ** this.#attempt);
|
|
144
|
+
this.#attempt += 1;
|
|
145
|
+
return Math.random() * window;
|
|
146
|
+
}
|
|
147
|
+
#stopTimers() {
|
|
148
|
+
for (const timer of [this.#reconnect, this.#ping]) {
|
|
149
|
+
if (timer !== null) {
|
|
150
|
+
clearTimeout(timer);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
this.#reconnect = null;
|
|
154
|
+
this.#ping = null;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/client/connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** `WS /v1/apps`. An http(s) base maps to ws(s). */
|
|
2
|
+
export declare function appsUrl(base: string): string;
|
|
3
|
+
/** `GET /v1/calls/{id}/events`: one call's log, as a JSON page or SSE. */
|
|
4
|
+
export declare function callLogUrl(base: string, call: string): string;
|
|
5
|
+
/** `GET /v1/agents/{slug}/calls`: the agent's own log (registrations, configurations, errors). */
|
|
6
|
+
export declare function agentLogUrl(base: string, agent: string): string;
|
|
7
|
+
/** `POST /v1/calls/{id}/lookup`: a knowledge-base search run by the gateway for this call. */
|
|
8
|
+
export declare function lookupUrl(base: string, call: string): string;
|
|
9
|
+
//# sourceMappingURL=endpoints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoints.d.ts","sourceRoot":"","sources":["../../src/client/endpoints.ts"],"names":[],"mappings":"AAEA,oDAAoD;AACpD,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,0EAA0E;AAC1E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,kGAAkG;AAClG,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,8FAA8F;AAC9F,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5D"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Gateway endpoint URLs, built from the base URL the app configures.
|
|
2
|
+
/** `WS /v1/apps`. An http(s) base maps to ws(s). */
|
|
3
|
+
export function appsUrl(base) {
|
|
4
|
+
return doorAt(base, "/v1/apps", true);
|
|
5
|
+
}
|
|
6
|
+
/** `GET /v1/calls/{id}/events`: one call's log, as a JSON page or SSE. */
|
|
7
|
+
export function callLogUrl(base, call) {
|
|
8
|
+
return doorAt(base, `/v1/calls/${encodeURIComponent(call)}/events`, false);
|
|
9
|
+
}
|
|
10
|
+
/** `GET /v1/agents/{slug}/calls`: the agent's own log (registrations, configurations, errors). */
|
|
11
|
+
export function agentLogUrl(base, agent) {
|
|
12
|
+
return doorAt(base, `/v1/agents/${encodeURIComponent(agent)}/calls`, false);
|
|
13
|
+
}
|
|
14
|
+
/** `POST /v1/calls/{id}/lookup`: a knowledge-base search run by the gateway for this call. */
|
|
15
|
+
export function lookupUrl(base, call) {
|
|
16
|
+
return doorAt(base, `/v1/calls/${encodeURIComponent(call)}/lookup`, false);
|
|
17
|
+
}
|
|
18
|
+
function doorAt(base, path, websocket) {
|
|
19
|
+
const url = new URL(base);
|
|
20
|
+
const secure = url.protocol === "https:" || url.protocol === "wss:";
|
|
21
|
+
url.protocol = websocket ? (secure ? "wss:" : "ws:") : secure ? "https:" : "http:";
|
|
22
|
+
url.pathname = `${url.pathname.replace(/\/$/, "")}${path}`;
|
|
23
|
+
return url.toString();
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=endpoints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoints.js","sourceRoot":"","sources":["../../src/client/endpoints.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAErE,oDAAoD;AACpD,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,IAAY;IACnD,OAAO,MAAM,CAAC,IAAI,EAAE,aAAa,kBAAkB,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AAC7E,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,KAAa;IACrD,OAAO,MAAM,CAAC,IAAI,EAAE,cAAc,kBAAkB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,IAAY;IAClD,OAAO,MAAM,CAAC,IAAI,EAAE,aAAa,kBAAkB,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;AAC7E,CAAC;AAED,SAAS,MAAM,CAAC,IAAY,EAAE,IAAY,EAAE,SAAkB;IAC5D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1B,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAC;IACpE,GAAG,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;IACnF,GAAG,CAAC,QAAQ,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC;IAC3D,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type Camel, type CommandData, type EventData } from "../wire/codec.js";
|
|
2
|
+
import { type Command } from "../wire/envelope.js";
|
|
3
|
+
import { type CommandType } from "../wire/registry.js";
|
|
4
|
+
/** Base error for client-side and gateway refusals. */
|
|
5
|
+
export declare class PinecallError extends Error {
|
|
6
|
+
readonly name = "PinecallError";
|
|
7
|
+
}
|
|
8
|
+
/** A gateway refusal received as an `error` entry; match on `refusal.code`. */
|
|
9
|
+
export declare class Refused extends PinecallError {
|
|
10
|
+
readonly refusal: Camel<EventData<"error">>;
|
|
11
|
+
constructor(refusal: Camel<EventData<"error">>);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Thrown by a dev verb handler to refuse with an HTTP status and a message shown verbatim. Any
|
|
15
|
+
* other error becomes a 500.
|
|
16
|
+
*/
|
|
17
|
+
export declare class DevRefused extends PinecallError {
|
|
18
|
+
readonly status: number;
|
|
19
|
+
readonly detail: string;
|
|
20
|
+
constructor(status: number, detail: string);
|
|
21
|
+
}
|
|
22
|
+
/** Return a command id unique within this process; an `error` carrying it answers that command. */
|
|
23
|
+
export declare function nextId(): string;
|
|
24
|
+
/**
|
|
25
|
+
* Build one command frame: camelCase data in, snake_case on the wire. Validates here so a bad
|
|
26
|
+
* shape throws with the app's stack trace.
|
|
27
|
+
*/
|
|
28
|
+
export declare function frame<K extends CommandType>(type: K, agent: string, call: string | null, data: Camel<CommandData<K>>, id?: string): Command;
|
|
29
|
+
//# sourceMappingURL=frames.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frames.d.ts","sourceRoot":"","sources":["../../src/client/frames.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAW,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,KAAK,OAAO,EAAiB,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAExE,uDAAuD;AACvD,qBAAa,aAAc,SAAQ,KAAK;IACtC,SAAkB,IAAI,mBAAmB;CAC1C;AAED,+EAA+E;AAC/E,qBAAa,OAAQ,SAAQ,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAAvD,YAAqB,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EAEtD;CACF;AAED;;;GAGG;AACH,qBAAa,UAAW,SAAQ,aAAa;IAEzC,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM;IAFzB,YACW,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EAGxB;CACF;AAID,mGAAmG;AACnG,wBAAgB,MAAM,IAAI,MAAM,CAE/B;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,CAAC,SAAS,WAAW,EACzC,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,IAAI,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAC3B,EAAE,GAAE,MAAiB,GACpB,OAAO,CAUT"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Command frames, validated against their schema, and the client's error types.
|
|
2
|
+
import { toSnake } from "../wire/codec.js";
|
|
3
|
+
import { CommandSchema } from "../wire/envelope.js";
|
|
4
|
+
import { COMMAND_SCHEMAS } from "../wire/registry.js";
|
|
5
|
+
/** Base error for client-side and gateway refusals. */
|
|
6
|
+
export class PinecallError extends Error {
|
|
7
|
+
name = "PinecallError";
|
|
8
|
+
}
|
|
9
|
+
/** A gateway refusal received as an `error` entry; match on `refusal.code`. */
|
|
10
|
+
export class Refused extends PinecallError {
|
|
11
|
+
refusal;
|
|
12
|
+
constructor(refusal) {
|
|
13
|
+
super(`${refusal.code}: ${refusal.message}`);
|
|
14
|
+
this.refusal = refusal;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Thrown by a dev verb handler to refuse with an HTTP status and a message shown verbatim. Any
|
|
19
|
+
* other error becomes a 500.
|
|
20
|
+
*/
|
|
21
|
+
export class DevRefused extends PinecallError {
|
|
22
|
+
status;
|
|
23
|
+
detail;
|
|
24
|
+
constructor(status, detail) {
|
|
25
|
+
super(`${status}: ${detail}`);
|
|
26
|
+
this.status = status;
|
|
27
|
+
this.detail = detail;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
let sent = 0;
|
|
31
|
+
/** Return a command id unique within this process; an `error` carrying it answers that command. */
|
|
32
|
+
export function nextId() {
|
|
33
|
+
return `c${(sent += 1)}`;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Build one command frame: camelCase data in, snake_case on the wire. Validates here so a bad
|
|
37
|
+
* shape throws with the app's stack trace.
|
|
38
|
+
*/
|
|
39
|
+
export function frame(type, agent, call, data, id = nextId()) {
|
|
40
|
+
// Typed structurally so this package never depends on a zod version.
|
|
41
|
+
const schema = COMMAND_SCHEMAS[type];
|
|
42
|
+
let checked;
|
|
43
|
+
try {
|
|
44
|
+
checked = schema.parse(toSnake(data));
|
|
45
|
+
}
|
|
46
|
+
catch (bad) {
|
|
47
|
+
throw new PinecallError(`${type}: ${bad instanceof Error ? bad.message : String(bad)}`);
|
|
48
|
+
}
|
|
49
|
+
return CommandSchema.parse({ type, agent, call, id, data: checked });
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=frames.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frames.js","sourceRoot":"","sources":["../../src/client/frames.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAEhF,OAAO,EAAgD,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAgB,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,eAAe,EAAoB,MAAM,qBAAqB,CAAC;AAExE,uDAAuD;AACvD,MAAM,OAAO,aAAc,SAAQ,KAAK;IACpB,IAAI,GAAG,eAAe,CAAC;CAC1C;AAED,+EAA+E;AAC/E,MAAM,OAAO,OAAQ,SAAQ,aAAa;IACnB,OAAO;IAA5B,YAAqB,OAAkC;QACrD,KAAK,CAAC,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;uBAD1B,OAAO;IAE5B,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,UAAW,SAAQ,aAAa;IAEhC,MAAM;IACN,MAAM;IAFjB,YACW,MAAc,EACd,MAAc;QAEvB,KAAK,CAAC,GAAG,MAAM,KAAK,MAAM,EAAE,CAAC,CAAC;sBAHrB,MAAM;sBACN,MAAM;IAGjB,CAAC;CACF;AAED,IAAI,IAAI,GAAG,CAAC,CAAC;AAEb,mGAAmG;AACnG,MAAM,UAAU,MAAM;IACpB,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,KAAK,CACnB,IAAO,EACP,KAAa,EACb,IAAmB,EACnB,IAA2B,EAC3B,EAAE,GAAW,MAAM,EAAE;IAErB,qEAAqE;IACrE,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAuC,CAAC;IAC3E,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,aAAa,CAAC,GAAG,IAAI,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO,aAAa,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AACvE,CAAC"}
|