@cotal-ai/core 0.1.0 → 0.1.2
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/dist/channels.d.ts +68 -0
- package/dist/channels.d.ts.map +1 -0
- package/dist/channels.js +140 -0
- package/dist/channels.js.map +1 -0
- package/dist/endpoint.d.ts +97 -3
- package/dist/endpoint.d.ts.map +1 -1
- package/dist/endpoint.js +381 -29
- package/dist/endpoint.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/provision.d.ts.map +1 -1
- package/dist/provision.js +33 -3
- package/dist/provision.js.map +1 -1
- package/dist/streams.d.ts.map +1 -1
- package/dist/streams.js +11 -4
- package/dist/streams.js.map +1 -1
- package/dist/subjects.d.ts +11 -0
- package/dist/subjects.d.ts.map +1 -1
- package/dist/subjects.js +13 -2
- package/dist/subjects.js.map +1 -1
- package/dist/types.d.ts +30 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -1
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channel registry — the read/write helpers over the per-space channels KV bucket.
|
|
3
|
+
*
|
|
4
|
+
* The bucket holds one {@link ChannelConfig} per channel (key = the concrete channel token)
|
|
5
|
+
* plus the space-wide defaults under {@link CHANNEL_DEFAULTS_KEY}. Writes are **privileged**
|
|
6
|
+
* (manager / `cotal up` / `cotal channels`); agents read it (the live cache lives on the
|
|
7
|
+
* endpoint). Because description/instructions reach the model, both text fields are bounded
|
|
8
|
+
* here and oversize is **rejected at the write path** — never silently truncated.
|
|
9
|
+
*/
|
|
10
|
+
import { type KV } from "@nats-io/kv";
|
|
11
|
+
import { type NatsConnection } from "@nats-io/transport-node";
|
|
12
|
+
import type { ChannelConfig, ChannelDefaults } from "./types.js";
|
|
13
|
+
/** The declarative channel-config file read at `cotal up` to seed the registry. */
|
|
14
|
+
export interface ChannelRegistryFile {
|
|
15
|
+
defaults?: ChannelDefaults;
|
|
16
|
+
/** Map of channel token → its config. */
|
|
17
|
+
channels?: Record<string, ChannelConfig>;
|
|
18
|
+
}
|
|
19
|
+
/** Length caps on the model-facing registry text — unbounded text would stuff every agent's
|
|
20
|
+
* context and bloat the KV, so a write past these throws rather than clamps. */
|
|
21
|
+
export declare const MAX_CHANNEL_DESCRIPTION = 200;
|
|
22
|
+
export declare const MAX_CHANNEL_INSTRUCTIONS = 2000;
|
|
23
|
+
/** Throw if a config is invalid: oversize text (rejected, never clamped — a write past the cap
|
|
24
|
+
* is a caller bug) or an unparseable `replayWindow`. */
|
|
25
|
+
export declare function validateChannelConfig(cfg: ChannelConfig): void;
|
|
26
|
+
/** Parse a duration like `"24h"`, `"30m"`, `"7d"`, `"90s"` into milliseconds. Throws on a bad
|
|
27
|
+
* format — a typo'd window must fail loud, not silently mean "no window". */
|
|
28
|
+
export declare function parseDuration(s: string): number;
|
|
29
|
+
/** Effective replay-on-join policy for a channel: per-channel override ?? space default ??
|
|
30
|
+
* `true`. Default-true preserves Cotal's original always-replay behavior. */
|
|
31
|
+
export declare function effectiveReplay(cfg: ChannelConfig | undefined, defaults: ChannelDefaults | undefined): boolean;
|
|
32
|
+
/** Effective backfill window in ms (per-channel ?? space default), or undefined for "the full
|
|
33
|
+
* retained window". Only meaningful when {@link effectiveReplay} is true. */
|
|
34
|
+
export declare function effectiveReplayWindowMs(cfg: ChannelConfig | undefined, defaults: ChannelDefaults | undefined): number | undefined;
|
|
35
|
+
/** Open the channels registry bucket. Auth mode (creds present) OPENs the bucket pre-created
|
|
36
|
+
* at `cotal up`; open dev mode lazily CREATEs it. Mirrors the presence-bucket open/create
|
|
37
|
+
* split (and, like presence, agents are denied KV stream-create so they must OPEN). */
|
|
38
|
+
export declare function openChannelRegistry(nc: NatsConnection, space: string, opts?: {
|
|
39
|
+
create?: boolean;
|
|
40
|
+
}): Promise<KV>;
|
|
41
|
+
/** Read one channel's config (or undefined if unset/deleted). */
|
|
42
|
+
export declare function readChannelConfig(kv: KV, channel: string): Promise<ChannelConfig | undefined>;
|
|
43
|
+
/** Read the space-wide defaults (or undefined if unset). */
|
|
44
|
+
export declare function readChannelDefaults(kv: KV): Promise<ChannelDefaults | undefined>;
|
|
45
|
+
/** Privileged write of a channel's config. **Merges** over any existing entry so a partial
|
|
46
|
+
* set (e.g. `--desc` only) doesn't wipe `replay`. Validated before the put. */
|
|
47
|
+
export declare function writeChannelConfig(kv: KV, channel: string, patch: ChannelConfig): Promise<void>;
|
|
48
|
+
/** Privileged write of the space-wide defaults (merged over any existing). */
|
|
49
|
+
export declare function writeChannelDefaults(kv: KV, patch: ChannelDefaults): Promise<void>;
|
|
50
|
+
/** Connect (with the given privileged creds, or open if none), seed the registry from a
|
|
51
|
+
* declarative {@link ChannelRegistryFile} (defaults + per-channel config, merged), disconnect.
|
|
52
|
+
* Used by `cotal up` to seed once at setup, and by `cotal channels` for runtime writes.
|
|
53
|
+
* Each field in the file overwrites that field in the registry; unspecified fields are kept. */
|
|
54
|
+
export declare function seedChannelRegistry(opts: {
|
|
55
|
+
servers: string;
|
|
56
|
+
space: string;
|
|
57
|
+
creds?: string;
|
|
58
|
+
file: ChannelRegistryFile;
|
|
59
|
+
}): Promise<void>;
|
|
60
|
+
/** Connect, read the whole registry (defaults + every channel entry) into a
|
|
61
|
+
* {@link ChannelRegistryFile}, disconnect. The read side of {@link seedChannelRegistry},
|
|
62
|
+
* used by `cotal channels list`. */
|
|
63
|
+
export declare function readChannelRegistry(opts: {
|
|
64
|
+
servers: string;
|
|
65
|
+
space: string;
|
|
66
|
+
creds?: string;
|
|
67
|
+
}): Promise<ChannelRegistryFile>;
|
|
68
|
+
//# sourceMappingURL=channels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.d.ts","sourceRoot":"","sources":["../src/channels.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAO,KAAK,EAAE,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAA+B,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE3F,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEjE,mFAAmF;AACnF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,yCAAyC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CAC1C;AAED;iFACiF;AACjF,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C;yDACyD;AACzD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAU9D;AAED;8EAC8E;AAC9E,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED;8EAC8E;AAC9E,wBAAgB,eAAe,CAC7B,GAAG,EAAE,aAAa,GAAG,SAAS,EAC9B,QAAQ,EAAE,eAAe,GAAG,SAAS,GACpC,OAAO,CAET;AAED;8EAC8E;AAC9E,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,aAAa,GAAG,SAAS,EAC9B,QAAQ,EAAE,eAAe,GAAG,SAAS,GACpC,MAAM,GAAG,SAAS,CAGpB;AAED;;wFAEwF;AACxF,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,cAAc,EAClB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAC9B,OAAO,CAAC,EAAE,CAAC,CAGb;AAED,iEAAiE;AACjE,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,EAAE,EACN,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAEpC;AAED,4DAA4D;AAC5D,wBAAsB,mBAAmB,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAEtF;AAED;gFACgF;AAChF,wBAAsB,kBAAkB,CACtC,EAAE,EAAE,EAAE,EACN,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,8EAA8E;AAC9E,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAGxF;AAYD;;;iGAGiG;AACjG,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,mBAAmB,CAAC;CAC3B,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBhB;AAED;;qCAEqC;AACrC,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAuB/B"}
|
package/dist/channels.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channel registry — the read/write helpers over the per-space channels KV bucket.
|
|
3
|
+
*
|
|
4
|
+
* The bucket holds one {@link ChannelConfig} per channel (key = the concrete channel token)
|
|
5
|
+
* plus the space-wide defaults under {@link CHANNEL_DEFAULTS_KEY}. Writes are **privileged**
|
|
6
|
+
* (manager / `cotal up` / `cotal channels`); agents read it (the live cache lives on the
|
|
7
|
+
* endpoint). Because description/instructions reach the model, both text fields are bounded
|
|
8
|
+
* here and oversize is **rejected at the write path** — never silently truncated.
|
|
9
|
+
*/
|
|
10
|
+
import { Kvm } from "@nats-io/kv";
|
|
11
|
+
import { connect, credsAuthenticator } from "@nats-io/transport-node";
|
|
12
|
+
import { channelBucket, CHANNEL_DEFAULTS_KEY } from "./subjects.js";
|
|
13
|
+
/** Length caps on the model-facing registry text — unbounded text would stuff every agent's
|
|
14
|
+
* context and bloat the KV, so a write past these throws rather than clamps. */
|
|
15
|
+
export const MAX_CHANNEL_DESCRIPTION = 200;
|
|
16
|
+
export const MAX_CHANNEL_INSTRUCTIONS = 2000;
|
|
17
|
+
/** Throw if a config is invalid: oversize text (rejected, never clamped — a write past the cap
|
|
18
|
+
* is a caller bug) or an unparseable `replayWindow`. */
|
|
19
|
+
export function validateChannelConfig(cfg) {
|
|
20
|
+
if (cfg.description !== undefined && cfg.description.length > MAX_CHANNEL_DESCRIPTION)
|
|
21
|
+
throw new Error(`channel description too long (${cfg.description.length} > ${MAX_CHANNEL_DESCRIPTION} chars)`);
|
|
22
|
+
if (cfg.instructions !== undefined && cfg.instructions.length > MAX_CHANNEL_INSTRUCTIONS)
|
|
23
|
+
throw new Error(`channel instructions too long (${cfg.instructions.length} > ${MAX_CHANNEL_INSTRUCTIONS} chars)`);
|
|
24
|
+
if (cfg.replayWindow !== undefined)
|
|
25
|
+
parseDuration(cfg.replayWindow); // throws if unparseable
|
|
26
|
+
}
|
|
27
|
+
/** Parse a duration like `"24h"`, `"30m"`, `"7d"`, `"90s"` into milliseconds. Throws on a bad
|
|
28
|
+
* format — a typo'd window must fail loud, not silently mean "no window". */
|
|
29
|
+
export function parseDuration(s) {
|
|
30
|
+
const m = /^(\d+)(s|m|h|d)$/.exec(s.trim());
|
|
31
|
+
if (!m)
|
|
32
|
+
throw new Error(`invalid duration "${s}" — expected <number><s|m|h|d>, e.g. "24h"`);
|
|
33
|
+
const n = Number(m[1]);
|
|
34
|
+
const unit = { s: 1_000, m: 60_000, h: 3_600_000, d: 86_400_000 }[m[2]];
|
|
35
|
+
return n * unit;
|
|
36
|
+
}
|
|
37
|
+
/** Effective replay-on-join policy for a channel: per-channel override ?? space default ??
|
|
38
|
+
* `true`. Default-true preserves Cotal's original always-replay behavior. */
|
|
39
|
+
export function effectiveReplay(cfg, defaults) {
|
|
40
|
+
return cfg?.replay ?? defaults?.replay ?? true;
|
|
41
|
+
}
|
|
42
|
+
/** Effective backfill window in ms (per-channel ?? space default), or undefined for "the full
|
|
43
|
+
* retained window". Only meaningful when {@link effectiveReplay} is true. */
|
|
44
|
+
export function effectiveReplayWindowMs(cfg, defaults) {
|
|
45
|
+
const w = cfg?.replayWindow ?? defaults?.replayWindow;
|
|
46
|
+
return w === undefined ? undefined : parseDuration(w);
|
|
47
|
+
}
|
|
48
|
+
/** Open the channels registry bucket. Auth mode (creds present) OPENs the bucket pre-created
|
|
49
|
+
* at `cotal up`; open dev mode lazily CREATEs it. Mirrors the presence-bucket open/create
|
|
50
|
+
* split (and, like presence, agents are denied KV stream-create so they must OPEN). */
|
|
51
|
+
export async function openChannelRegistry(nc, space, opts = {}) {
|
|
52
|
+
const kvm = new Kvm(nc);
|
|
53
|
+
return opts.create ? kvm.create(channelBucket(space)) : kvm.open(channelBucket(space));
|
|
54
|
+
}
|
|
55
|
+
/** Read one channel's config (or undefined if unset/deleted). */
|
|
56
|
+
export async function readChannelConfig(kv, channel) {
|
|
57
|
+
return decode(kv, channel);
|
|
58
|
+
}
|
|
59
|
+
/** Read the space-wide defaults (or undefined if unset). */
|
|
60
|
+
export async function readChannelDefaults(kv) {
|
|
61
|
+
return decode(kv, CHANNEL_DEFAULTS_KEY);
|
|
62
|
+
}
|
|
63
|
+
/** Privileged write of a channel's config. **Merges** over any existing entry so a partial
|
|
64
|
+
* set (e.g. `--desc` only) doesn't wipe `replay`. Validated before the put. */
|
|
65
|
+
export async function writeChannelConfig(kv, channel, patch) {
|
|
66
|
+
validateChannelConfig(patch);
|
|
67
|
+
const merged = { ...(await readChannelConfig(kv, channel)), ...patch };
|
|
68
|
+
await kv.put(channel, JSON.stringify(merged));
|
|
69
|
+
}
|
|
70
|
+
/** Privileged write of the space-wide defaults (merged over any existing). */
|
|
71
|
+
export async function writeChannelDefaults(kv, patch) {
|
|
72
|
+
const merged = { ...(await readChannelDefaults(kv)), ...patch };
|
|
73
|
+
await kv.put(CHANNEL_DEFAULTS_KEY, JSON.stringify(merged));
|
|
74
|
+
}
|
|
75
|
+
async function decode(kv, key) {
|
|
76
|
+
const e = await kv.get(key);
|
|
77
|
+
if (!e || e.operation === "DEL" || e.operation === "PURGE")
|
|
78
|
+
return undefined;
|
|
79
|
+
try {
|
|
80
|
+
return e.json();
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** Connect (with the given privileged creds, or open if none), seed the registry from a
|
|
87
|
+
* declarative {@link ChannelRegistryFile} (defaults + per-channel config, merged), disconnect.
|
|
88
|
+
* Used by `cotal up` to seed once at setup, and by `cotal channels` for runtime writes.
|
|
89
|
+
* Each field in the file overwrites that field in the registry; unspecified fields are kept. */
|
|
90
|
+
export async function seedChannelRegistry(opts) {
|
|
91
|
+
const nc = await connect({
|
|
92
|
+
servers: opts.servers,
|
|
93
|
+
...(opts.creds
|
|
94
|
+
? { authenticator: credsAuthenticator(new TextEncoder().encode(opts.creds)) }
|
|
95
|
+
: {}),
|
|
96
|
+
});
|
|
97
|
+
try {
|
|
98
|
+
// The seed path is privileged (manager creds or open) so it may CREATE the bucket — this
|
|
99
|
+
// makes `cotal channels` work on a space whose bucket wasn't pre-created (e.g. one set up
|
|
100
|
+
// before this feature). Idempotent when `cotal up` already created it.
|
|
101
|
+
const kv = await openChannelRegistry(nc, opts.space, { create: true });
|
|
102
|
+
if (opts.file.defaults)
|
|
103
|
+
await writeChannelDefaults(kv, opts.file.defaults);
|
|
104
|
+
for (const [channel, cfg] of Object.entries(opts.file.channels ?? {}))
|
|
105
|
+
await writeChannelConfig(kv, channel, cfg);
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
await nc.drain();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/** Connect, read the whole registry (defaults + every channel entry) into a
|
|
112
|
+
* {@link ChannelRegistryFile}, disconnect. The read side of {@link seedChannelRegistry},
|
|
113
|
+
* used by `cotal channels list`. */
|
|
114
|
+
export async function readChannelRegistry(opts) {
|
|
115
|
+
const nc = await connect({
|
|
116
|
+
servers: opts.servers,
|
|
117
|
+
...(opts.creds
|
|
118
|
+
? { authenticator: credsAuthenticator(new TextEncoder().encode(opts.creds)) }
|
|
119
|
+
: {}),
|
|
120
|
+
});
|
|
121
|
+
try {
|
|
122
|
+
const kv = await openChannelRegistry(nc, opts.space, { create: true });
|
|
123
|
+
const channels = {};
|
|
124
|
+
let defaults;
|
|
125
|
+
for await (const key of await kv.keys()) {
|
|
126
|
+
if (key === CHANNEL_DEFAULTS_KEY) {
|
|
127
|
+
defaults = await readChannelDefaults(kv);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
const cfg = await readChannelConfig(kv, key);
|
|
131
|
+
if (cfg)
|
|
132
|
+
channels[key] = cfg;
|
|
133
|
+
}
|
|
134
|
+
return { defaults, channels };
|
|
135
|
+
}
|
|
136
|
+
finally {
|
|
137
|
+
await nc.drain();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=channels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.js","sourceRoot":"","sources":["../src/channels.ts"],"names":[],"mappings":"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"}
|
package/dist/endpoint.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EventEmitter } from "node:events";
|
|
2
|
-
import type { AgentCard, ControlReply, ControlRequest, EndpointRef, Part, Presence, PresenceStatus, CotalMessage } from "./types.js";
|
|
2
|
+
import type { AgentCard, ChannelConfig, ControlReply, ControlRequest, EndpointRef, Part, Presence, PresenceStatus, CotalMessage } from "./types.js";
|
|
3
3
|
export declare const DEFAULT_SERVER = "nats://127.0.0.1:4222";
|
|
4
4
|
export interface EndpointOptions {
|
|
5
5
|
/** The collaboration to join. */
|
|
@@ -36,6 +36,15 @@ export interface EndpointOptions {
|
|
|
36
36
|
/** Retire this instance's durable consumers after it's been gone this long (ms). */
|
|
37
37
|
inactiveThresholdMs?: number;
|
|
38
38
|
}
|
|
39
|
+
/** A peer subscribed to a channel — broker truth (a chat-stream consumer) joined with
|
|
40
|
+
* presence for liveness. `live: false` is a stale ghost: the durable lingers (reconnect
|
|
41
|
+
* grace) but presence says the peer is gone/offline. */
|
|
42
|
+
export interface ChannelMember {
|
|
43
|
+
id: string;
|
|
44
|
+
name: string;
|
|
45
|
+
role?: string;
|
|
46
|
+
live: boolean;
|
|
47
|
+
}
|
|
39
48
|
/**
|
|
40
49
|
* Events: "message" (CotalMessage), "presence" (PresenceEvent), "roster" (Presence[]), "error" (Error).
|
|
41
50
|
*
|
|
@@ -65,6 +74,15 @@ export declare class CotalEndpoint extends EventEmitter {
|
|
|
65
74
|
private js?;
|
|
66
75
|
private jsm?;
|
|
67
76
|
private kv?;
|
|
77
|
+
private channelKv?;
|
|
78
|
+
/** Live local cache of the channel registry (key = channel token), kept by a KV watch. */
|
|
79
|
+
private readonly channelConfigs;
|
|
80
|
+
private channelDefaults;
|
|
81
|
+
/** Per-subscription join watermark: the stream frontier captured when a channel was joined.
|
|
82
|
+
* The tail ack-drops chat messages with `seq <= watermark` (suppresses pre-join history for
|
|
83
|
+
* a lagging joiner + dedups the backfill overlap). Keyed by the subscription pattern (may be
|
|
84
|
+
* wildcard), so the drop matches every concrete channel the pattern subsumes. */
|
|
85
|
+
private readonly joinSeq;
|
|
68
86
|
private readonly subs;
|
|
69
87
|
private readonly streamMsgs;
|
|
70
88
|
private heartbeatTimer?;
|
|
@@ -110,12 +128,56 @@ export declare class CotalEndpoint extends EventEmitter {
|
|
|
110
128
|
getRoster(): Presence[];
|
|
111
129
|
setActivity(activity: string): Promise<void>;
|
|
112
130
|
setStatus(status: PresenceStatus): Promise<void>;
|
|
113
|
-
/**
|
|
114
|
-
|
|
131
|
+
/** This channel's registry config from the live local cache (undefined if unset). */
|
|
132
|
+
getChannelConfig(channel: string): ChannelConfig | undefined;
|
|
133
|
+
/** Effective replay-on-join policy for a channel: per-channel override ?? space default ??
|
|
134
|
+
* true. Reads the live cache, so it reflects runtime registry edits. */
|
|
135
|
+
channelReplay(channel: string): boolean;
|
|
136
|
+
/** The channels this endpoint is currently subscribed to (live — reflects join/leave). */
|
|
137
|
+
joinedChannels(): string[];
|
|
138
|
+
/**
|
|
139
|
+
* Join a channel mid-session: add it to our chat durable's `filter_subjects` (same durable,
|
|
140
|
+
* same ack-floor, no teardown — `update` rides the self-scoped create grant), capture the
|
|
141
|
+
* stream frontier as this channel's join watermark, and backfill its history if replay is on.
|
|
142
|
+
* Idempotent: re-joining a channel already in our filter is a no-op (no re-backfill). Returns
|
|
143
|
+
* the number of historical messages backfilled (emitted as `historical` "message" events).
|
|
144
|
+
*/
|
|
145
|
+
joinChannel(channel: string): Promise<{
|
|
146
|
+
joined: boolean;
|
|
147
|
+
backfilled: number;
|
|
148
|
+
}>;
|
|
149
|
+
/** Leave a channel mid-session: drop it from the durable's `filter_subjects`. Refuses to leave
|
|
150
|
+
* the *last* channel (an empty filter would match every chat subject — the opposite of
|
|
151
|
+
* leaving). Returns whether anything changed. */
|
|
152
|
+
leaveChannel(channel: string): Promise<{
|
|
153
|
+
left: boolean;
|
|
154
|
+
}>;
|
|
155
|
+
/** One coherent channel model for dashboards: every channel that has messages OR a registry
|
|
156
|
+
* entry (configured-but-empty), each tagged with its {@link ChannelConfig}. Works even on
|
|
157
|
+
* observer endpoints (no consumers needed). */
|
|
115
158
|
listChannels(): Promise<{
|
|
116
159
|
channel: string;
|
|
117
160
|
messages: number;
|
|
161
|
+
config?: ChannelConfig;
|
|
118
162
|
}[]>;
|
|
163
|
+
/**
|
|
164
|
+
* Who is subscribed to a channel — **broker truth, not self-report**. In Cotal a peer
|
|
165
|
+
* joins a channel by creating a chat-stream durable consumer (`chat_<id>`,
|
|
166
|
+
* `filter_subjects` = its channels), so `consumers.list(CHAT)` already records the real
|
|
167
|
+
* membership; we join it with presence so a lingering durable for a gone peer shows as a
|
|
168
|
+
* stale ghost (`live: false`) rather than a phantom listener.
|
|
169
|
+
*
|
|
170
|
+
* `channelMembers("review")` → that channel's members; `channelMembers()` → every channel
|
|
171
|
+
* mapped to its members. A member on a wildcard (`team.>`) counts for every concrete
|
|
172
|
+
* channel it subsumes (`team.backend`) — membership is the *effective subscription*.
|
|
173
|
+
*
|
|
174
|
+
* Privileged read: `consumers.list` needs `$JS.API.CONSUMER.LIST.<chat stream>`, which only
|
|
175
|
+
* the allow-all manager profile holds today (agents, observer, and admin are all denied), so
|
|
176
|
+
* this is not an agent-facing capability — serving it from a dashboard profile is a one-line
|
|
177
|
+
* ACL grant away.
|
|
178
|
+
*/
|
|
179
|
+
channelMembers(channel: string): Promise<ChannelMember[]>;
|
|
180
|
+
channelMembers(): Promise<Map<string, ChannelMember[]>>;
|
|
119
181
|
/** Fetch recent messages from a channel's JetStream backlog. */
|
|
120
182
|
channelHistory(channel: string, opts?: {
|
|
121
183
|
limit?: number;
|
|
@@ -165,8 +227,40 @@ export declare class CotalEndpoint extends EventEmitter {
|
|
|
165
227
|
private startConsumers;
|
|
166
228
|
/** Drive one consumer: decode, drop our own echo, and hand each message to listeners with ack control. */
|
|
167
229
|
private pump;
|
|
230
|
+
/** The highest join watermark among the joined subscriptions that cover `concreteChannel`
|
|
231
|
+
* (a wildcard sub like `team.>` covers `team.backend`), or undefined if none — the tail
|
|
232
|
+
* drops a chat message with `seq <= ` this. */
|
|
233
|
+
private dropWatermark;
|
|
234
|
+
/** The durable's info (rebind) or null (fresh — 404). Gates create/backfill to the join event
|
|
235
|
+
* and exposes the current `filter_subjects` for restart reconciliation. */
|
|
236
|
+
private consumerInfo;
|
|
237
|
+
/** Current frontier (last sequence) of the chat stream — a channel's join watermark. */
|
|
238
|
+
private chatFrontier;
|
|
239
|
+
/** Phase 1 of a join — arm each channel's tail-drop watermark at the current frontier. MUST run
|
|
240
|
+
* BEFORE the filter flip (consumers.update, or pump on a fresh create) so the tail can never
|
|
241
|
+
* carry a just-joined message un-watermarked — which would double-emit it (live + backfill).
|
|
242
|
+
* Returns the per-channel frontiers for {@link backfillArmed}. */
|
|
243
|
+
private armJoin;
|
|
244
|
+
/** Phase 2 of a join — backfill each armed channel's history up to its frontier (replay-gated),
|
|
245
|
+
* AFTER the filter flip. Returns the total backfilled. */
|
|
246
|
+
private backfillArmed;
|
|
247
|
+
/** Replay policy + backfill window read straight from the registry bucket (vs the watch cache)
|
|
248
|
+
* — the authoritative read for a join decision (a join is infrequent, and at startup the async
|
|
249
|
+
* cache may not have caught up). Falls to the built-in default only with no registry open. */
|
|
250
|
+
private joinPolicyFresh;
|
|
251
|
+
/** Read a channel's retained history up to `upToSeq` via JetStream **Direct Get** (a read
|
|
252
|
+
* verb — no consumer create, so it rides a read-only grant) and emit each message as a
|
|
253
|
+
* `historical` "message" event. `sinceMs` bounds how far back via a native Direct-Get
|
|
254
|
+
* `start_time` (now − window); unset ⇒ the full retained window. New messages (`seq > upToSeq`)
|
|
255
|
+
* are skipped — the live tail owns them. Pages the batch API; the ack handle is a no-op. */
|
|
256
|
+
private backfillChannel;
|
|
168
257
|
private publishPresence;
|
|
169
258
|
private startPresenceWatch;
|
|
259
|
+
/** Watch the channel registry: replay existing keys, then stream updates, into the local
|
|
260
|
+
* cache. Best-effort — a registry the endpoint can't read leaves the cache empty (effective
|
|
261
|
+
* policy then falls back to the default), never a fault. */
|
|
262
|
+
private startChannelWatch;
|
|
263
|
+
private handleChannelEntry;
|
|
170
264
|
private handleKvEntry;
|
|
171
265
|
private applyPresence;
|
|
172
266
|
/** Mark a known peer offline (on KV delete/purge), keeping it in the roster. */
|
package/dist/endpoint.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"endpoint.d.ts","sourceRoot":"","sources":["../src/endpoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"endpoint.d.ts","sourceRoot":"","sources":["../src/endpoint.ts"],"names":[],"mappings":"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"}
|