@komputer-ai/sdk 0.11.7 → 0.11.8
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/README.md +17 -0
- package/dist/client.d.ts +13 -1
- package/dist/client.js +12 -2
- package/dist/esm/client.d.ts +13 -1
- package/dist/esm/client.js +12 -2
- package/dist/esm/watch.d.ts +1 -1
- package/dist/esm/watch.js +6 -2
- package/dist/watch.d.ts +1 -1
- package/dist/watch.js +6 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -127,6 +127,23 @@ for await (const event of stream) {
|
|
|
127
127
|
}
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
+
#### Distributed consumers — `{ group }`
|
|
131
|
+
|
|
132
|
+
By default, `watchAgent` opens a **broadcast** subscription: every connected client receives every event. If you run multiple instances of your service (e.g. 3 replicas of a Slack bot) and they all call `client.watchAgent("my-agent")` without further options, **each instance will process every event** — duplicate work.
|
|
133
|
+
|
|
134
|
+
To get queue-style delivery (each event handled by exactly one instance across your fleet), pass `{ group }`:
|
|
135
|
+
|
|
136
|
+
```ts
|
|
137
|
+
const stream = await client.watchAgent("my-agent", { group: "my-bot" });
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The API uses Redis-coordinated routing to deliver each event to exactly one client per group, regardless of how many replicas connect or which API replica they hit. Pick any string for the group name (`my-bot`, `audit-pipeline`, `prod-webhook-fwd`).
|
|
141
|
+
|
|
142
|
+
**Use broadcast** for: dashboards, debugging, single-instance workers, anywhere "see everything" is the goal.
|
|
143
|
+
**Use `{ group }`** for: distributed services, webhook forwarders, anywhere you'd otherwise dedupe events yourself.
|
|
144
|
+
|
|
145
|
+
On write failure, the API retries delivery to other group members on the same replica before giving up — an event is only lost when all members on the routing replica fail simultaneously. Use `client.getAgentEvents({ name, limit: ... })` to backfill on reconnect if you need strict exactly-once guarantees.
|
|
146
|
+
|
|
130
147
|
### Direct API access
|
|
131
148
|
|
|
132
149
|
For advanced use cases, the underlying generated API clients are available:
|
package/dist/client.d.ts
CHANGED
|
@@ -171,5 +171,17 @@ export declare class KomputerClient {
|
|
|
171
171
|
listTemplates(): Promise<{
|
|
172
172
|
[key: string]: any;
|
|
173
173
|
}>;
|
|
174
|
-
|
|
174
|
+
/**
|
|
175
|
+
* Stream live agent events.
|
|
176
|
+
*
|
|
177
|
+
* @param name Agent name.
|
|
178
|
+
* @param options.group Optional consumer group name. When set, this watcher joins
|
|
179
|
+
* a group and each event is delivered to exactly one client per group across all
|
|
180
|
+
* API replicas — useful when running multiple SDK instances in a distributed system
|
|
181
|
+
* that should not each process the same event. Without `group`, every connected
|
|
182
|
+
* client receives every event (broadcast).
|
|
183
|
+
*/
|
|
184
|
+
watchAgent(name: string, options?: {
|
|
185
|
+
group?: string;
|
|
186
|
+
}): Promise<AgentEventStream>;
|
|
175
187
|
}
|
package/dist/client.js
CHANGED
|
@@ -268,7 +268,17 @@ class KomputerClient {
|
|
|
268
268
|
});
|
|
269
269
|
}
|
|
270
270
|
// --- WebSocket ---
|
|
271
|
-
|
|
271
|
+
/**
|
|
272
|
+
* Stream live agent events.
|
|
273
|
+
*
|
|
274
|
+
* @param name Agent name.
|
|
275
|
+
* @param options.group Optional consumer group name. When set, this watcher joins
|
|
276
|
+
* a group and each event is delivered to exactly one client per group across all
|
|
277
|
+
* API replicas — useful when running multiple SDK instances in a distributed system
|
|
278
|
+
* that should not each process the same event. Without `group`, every connected
|
|
279
|
+
* client receives every event (broadcast).
|
|
280
|
+
*/
|
|
281
|
+
watchAgent(name, options) {
|
|
272
282
|
return __awaiter(this, void 0, void 0, function* () {
|
|
273
283
|
const wsUrl = this._baseUrl.replace("http://", "ws://").replace("https://", "wss://");
|
|
274
284
|
let history = [];
|
|
@@ -286,7 +296,7 @@ class KomputerClient {
|
|
|
286
296
|
catch (_a) {
|
|
287
297
|
// History fetch failed — proceed with live-only.
|
|
288
298
|
}
|
|
289
|
-
return new watch_1.AgentEventStream(wsUrl, name, history);
|
|
299
|
+
return new watch_1.AgentEventStream(wsUrl, name, history, options === null || options === void 0 ? void 0 : options.group);
|
|
290
300
|
});
|
|
291
301
|
}
|
|
292
302
|
}
|
package/dist/esm/client.d.ts
CHANGED
|
@@ -171,5 +171,17 @@ export declare class KomputerClient {
|
|
|
171
171
|
listTemplates(): Promise<{
|
|
172
172
|
[key: string]: any;
|
|
173
173
|
}>;
|
|
174
|
-
|
|
174
|
+
/**
|
|
175
|
+
* Stream live agent events.
|
|
176
|
+
*
|
|
177
|
+
* @param name Agent name.
|
|
178
|
+
* @param options.group Optional consumer group name. When set, this watcher joins
|
|
179
|
+
* a group and each event is delivered to exactly one client per group across all
|
|
180
|
+
* API replicas — useful when running multiple SDK instances in a distributed system
|
|
181
|
+
* that should not each process the same event. Without `group`, every connected
|
|
182
|
+
* client receives every event (broadcast).
|
|
183
|
+
*/
|
|
184
|
+
watchAgent(name: string, options?: {
|
|
185
|
+
group?: string;
|
|
186
|
+
}): Promise<AgentEventStream>;
|
|
175
187
|
}
|
package/dist/esm/client.js
CHANGED
|
@@ -265,7 +265,17 @@ export class KomputerClient {
|
|
|
265
265
|
});
|
|
266
266
|
}
|
|
267
267
|
// --- WebSocket ---
|
|
268
|
-
|
|
268
|
+
/**
|
|
269
|
+
* Stream live agent events.
|
|
270
|
+
*
|
|
271
|
+
* @param name Agent name.
|
|
272
|
+
* @param options.group Optional consumer group name. When set, this watcher joins
|
|
273
|
+
* a group and each event is delivered to exactly one client per group across all
|
|
274
|
+
* API replicas — useful when running multiple SDK instances in a distributed system
|
|
275
|
+
* that should not each process the same event. Without `group`, every connected
|
|
276
|
+
* client receives every event (broadcast).
|
|
277
|
+
*/
|
|
278
|
+
watchAgent(name, options) {
|
|
269
279
|
return __awaiter(this, void 0, void 0, function* () {
|
|
270
280
|
const wsUrl = this._baseUrl.replace("http://", "ws://").replace("https://", "wss://");
|
|
271
281
|
let history = [];
|
|
@@ -283,7 +293,7 @@ export class KomputerClient {
|
|
|
283
293
|
catch (_a) {
|
|
284
294
|
// History fetch failed — proceed with live-only.
|
|
285
295
|
}
|
|
286
|
-
return new AgentEventStream(wsUrl, name, history);
|
|
296
|
+
return new AgentEventStream(wsUrl, name, history, options === null || options === void 0 ? void 0 : options.group);
|
|
287
297
|
});
|
|
288
298
|
}
|
|
289
299
|
}
|
package/dist/esm/watch.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export declare class AgentEventStream implements AsyncIterable<AgentEvent> {
|
|
|
25
25
|
private resolve;
|
|
26
26
|
private done;
|
|
27
27
|
private seen;
|
|
28
|
-
constructor(wsUrl: string, agentName: string, historyEvents?: AgentEvent[]);
|
|
28
|
+
constructor(wsUrl: string, agentName: string, historyEvents?: AgentEvent[], group?: string);
|
|
29
29
|
private dedupKey;
|
|
30
30
|
[Symbol.asyncIterator](): AsyncIterator<AgentEvent>;
|
|
31
31
|
close(): void;
|
package/dist/esm/watch.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* }
|
|
14
14
|
*/
|
|
15
15
|
export class AgentEventStream {
|
|
16
|
-
constructor(wsUrl, agentName, historyEvents) {
|
|
16
|
+
constructor(wsUrl, agentName, historyEvents, group) {
|
|
17
17
|
this.queue = [];
|
|
18
18
|
this.resolve = null;
|
|
19
19
|
this.done = false;
|
|
@@ -27,7 +27,11 @@ export class AgentEventStream {
|
|
|
27
27
|
this.queue.push(e);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
|
|
30
|
+
let endpoint = `${wsUrl}/api/v1/agents/${agentName}/ws`;
|
|
31
|
+
if (group) {
|
|
32
|
+
endpoint += `?group=${encodeURIComponent(group)}`;
|
|
33
|
+
}
|
|
34
|
+
this.ws = new WebSocket(endpoint);
|
|
31
35
|
this.ws.onmessage = (event) => {
|
|
32
36
|
const data = JSON.parse(event.data);
|
|
33
37
|
const agentEvent = {
|
package/dist/watch.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export declare class AgentEventStream implements AsyncIterable<AgentEvent> {
|
|
|
25
25
|
private resolve;
|
|
26
26
|
private done;
|
|
27
27
|
private seen;
|
|
28
|
-
constructor(wsUrl: string, agentName: string, historyEvents?: AgentEvent[]);
|
|
28
|
+
constructor(wsUrl: string, agentName: string, historyEvents?: AgentEvent[], group?: string);
|
|
29
29
|
private dedupKey;
|
|
30
30
|
[Symbol.asyncIterator](): AsyncIterator<AgentEvent>;
|
|
31
31
|
close(): void;
|
package/dist/watch.js
CHANGED
|
@@ -16,7 +16,7 @@ exports.AgentEventStream = void 0;
|
|
|
16
16
|
* }
|
|
17
17
|
*/
|
|
18
18
|
class AgentEventStream {
|
|
19
|
-
constructor(wsUrl, agentName, historyEvents) {
|
|
19
|
+
constructor(wsUrl, agentName, historyEvents, group) {
|
|
20
20
|
this.queue = [];
|
|
21
21
|
this.resolve = null;
|
|
22
22
|
this.done = false;
|
|
@@ -30,7 +30,11 @@ class AgentEventStream {
|
|
|
30
30
|
this.queue.push(e);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
let endpoint = `${wsUrl}/api/v1/agents/${agentName}/ws`;
|
|
34
|
+
if (group) {
|
|
35
|
+
endpoint += `?group=${encodeURIComponent(group)}`;
|
|
36
|
+
}
|
|
37
|
+
this.ws = new WebSocket(endpoint);
|
|
34
38
|
this.ws.onmessage = (event) => {
|
|
35
39
|
const data = JSON.parse(event.data);
|
|
36
40
|
const agentEvent = {
|