agents-bridge 0.1.0
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/.env.example +20 -0
- package/LICENSE +21 -0
- package/README.md +259 -0
- package/bin/agent-bridge.mjs +12 -0
- package/config.example.json +117 -0
- package/dist/agents/cli-backends.d.ts +32 -0
- package/dist/agents/cli-backends.d.ts.map +1 -0
- package/dist/agents/cli-backends.js +217 -0
- package/dist/agents/cli-backends.js.map +1 -0
- package/dist/agents/cli-runner.d.ts.map +1 -0
- package/dist/agents/cli-runner.js +524 -0
- package/dist/agents/cli-runner.js.map +1 -0
- package/dist/agents/cli-session-store.d.ts.map +1 -0
- package/dist/agents/cli-session-store.js +127 -0
- package/dist/agents/cli-session-store.js.map +1 -0
- package/dist/agents/model-selection.d.ts +27 -0
- package/dist/agents/model-selection.d.ts.map +1 -0
- package/dist/agents/model-selection.js +40 -0
- package/dist/agents/model-selection.js.map +1 -0
- package/dist/agents/models-config.d.ts +28 -0
- package/dist/agents/models-config.d.ts.map +1 -0
- package/dist/agents/models-config.js +43 -0
- package/dist/agents/models-config.js.map +1 -0
- package/dist/channels/botlink.d.ts.map +1 -0
- package/dist/channels/botlink.js +320 -0
- package/dist/channels/botlink.js.map +1 -0
- package/dist/channels/command-gating.d.ts +20 -0
- package/dist/channels/command-gating.d.ts.map +1 -0
- package/dist/channels/command-gating.js +43 -0
- package/dist/channels/command-gating.js.map +1 -0
- package/dist/channels/draft-stream-controls.d.ts +21 -0
- package/dist/channels/draft-stream-controls.d.ts.map +1 -0
- package/dist/channels/draft-stream-controls.js +43 -0
- package/dist/channels/draft-stream-controls.js.map +1 -0
- package/dist/channels/draft-stream-loop.d.ts +31 -0
- package/dist/channels/draft-stream-loop.d.ts.map +1 -0
- package/dist/channels/draft-stream-loop.js +60 -0
- package/dist/channels/draft-stream-loop.js.map +1 -0
- package/dist/channels/mention-gating.d.ts +18 -0
- package/dist/channels/mention-gating.d.ts.map +1 -0
- package/dist/channels/mention-gating.js +20 -0
- package/dist/channels/mention-gating.js.map +1 -0
- package/dist/channels/registry.d.ts +5 -0
- package/dist/channels/registry.d.ts.map +1 -0
- package/dist/channels/registry.js +14 -0
- package/dist/channels/registry.js.map +1 -0
- package/dist/channels/run-state-machine.d.ts +21 -0
- package/dist/channels/run-state-machine.d.ts.map +1 -0
- package/dist/channels/run-state-machine.js +41 -0
- package/dist/channels/run-state-machine.js.map +1 -0
- package/dist/channels/session-envelope.d.ts +5 -0
- package/dist/channels/session-envelope.d.ts.map +1 -0
- package/dist/channels/session-envelope.js +13 -0
- package/dist/channels/session-envelope.js.map +1 -0
- package/dist/channels/session.d.ts +18 -0
- package/dist/channels/session.d.ts.map +1 -0
- package/dist/channels/session.js +35 -0
- package/dist/channels/session.js.map +1 -0
- package/dist/channels/typing-lifecycle.d.ts +16 -0
- package/dist/channels/typing-lifecycle.d.ts.map +1 -0
- package/dist/channels/typing-lifecycle.js +31 -0
- package/dist/channels/typing-lifecycle.js.map +1 -0
- package/dist/cli/cmd-config.d.ts +3 -0
- package/dist/cli/cmd-config.d.ts.map +1 -0
- package/dist/cli/cmd-config.js +15 -0
- package/dist/cli/cmd-config.js.map +1 -0
- package/dist/cli/cmd-doctor.d.ts +3 -0
- package/dist/cli/cmd-doctor.d.ts.map +1 -0
- package/dist/cli/cmd-doctor.js +80 -0
- package/dist/cli/cmd-doctor.js.map +1 -0
- package/dist/cli/cmd-logs.d.ts +3 -0
- package/dist/cli/cmd-logs.d.ts.map +1 -0
- package/dist/cli/cmd-logs.js +26 -0
- package/dist/cli/cmd-logs.js.map +1 -0
- package/dist/cli/cmd-onboard.d.ts +3 -0
- package/dist/cli/cmd-onboard.d.ts.map +1 -0
- package/dist/cli/cmd-onboard.js +103 -0
- package/dist/cli/cmd-onboard.js.map +1 -0
- package/dist/cli/cmd-start.d.ts +3 -0
- package/dist/cli/cmd-start.d.ts.map +1 -0
- package/dist/cli/cmd-start.js +155 -0
- package/dist/cli/cmd-start.js.map +1 -0
- package/dist/cli/cmd-status.d.ts +3 -0
- package/dist/cli/cmd-status.d.ts.map +1 -0
- package/dist/cli/cmd-status.js +16 -0
- package/dist/cli/cmd-status.js.map +1 -0
- package/dist/cli/cmd-stop.d.ts +3 -0
- package/dist/cli/cmd-stop.d.ts.map +1 -0
- package/dist/cli/cmd-stop.js +30 -0
- package/dist/cli/cmd-stop.js.map +1 -0
- package/dist/cli/pid-file.d.ts +7 -0
- package/dist/cli/pid-file.d.ts.map +1 -0
- package/dist/cli/pid-file.js +51 -0
- package/dist/cli/pid-file.js.map +1 -0
- package/dist/cli/run-main.d.ts +11 -0
- package/dist/cli/run-main.d.ts.map +1 -0
- package/dist/cli/run-main.js +64 -0
- package/dist/cli/run-main.js.map +1 -0
- package/dist/config/agent-dirs.d.ts +12 -0
- package/dist/config/agent-dirs.d.ts.map +1 -0
- package/dist/config/agent-dirs.js +30 -0
- package/dist/config/agent-dirs.js.map +1 -0
- package/dist/config/config.d.ts +3 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +40 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/env-vars.d.ts +15 -0
- package/dist/config/env-vars.d.ts.map +1 -0
- package/dist/config/env-vars.js +16 -0
- package/dist/config/env-vars.js.map +1 -0
- package/dist/config/merge-config.d.ts +7 -0
- package/dist/config/merge-config.d.ts.map +1 -0
- package/dist/config/merge-config.js +32 -0
- package/dist/config/merge-config.js.map +1 -0
- package/dist/config/paths.d.ts +19 -0
- package/dist/config/paths.d.ts.map +1 -0
- package/dist/config/paths.js +22 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/zod-schema.d.ts +1192 -0
- package/dist/config/zod-schema.d.ts.map +1 -0
- package/dist/config/zod-schema.js +107 -0
- package/dist/config/zod-schema.js.map +1 -0
- package/dist/console-encoding.d.ts +6 -0
- package/dist/console-encoding.d.ts.map +1 -0
- package/dist/console-encoding.js +35 -0
- package/dist/console-encoding.js.map +1 -0
- package/dist/entry.d.ts +3 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +47 -0
- package/dist/entry.js.map +1 -0
- package/dist/logger.d.ts +4 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +19 -0
- package/dist/logger.js.map +1 -0
- package/dist/types/index.d.ts +67 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command gating - intercepts slash commands (e.g. /help, /status, /stop)
|
|
3
|
+
* before they reach the agent, handling them locally.
|
|
4
|
+
*
|
|
5
|
+
* Returns null if the message is not a command and should be forwarded to the agent.
|
|
6
|
+
*/
|
|
7
|
+
export interface CommandResult {
|
|
8
|
+
/** The command name (without the leading /) */
|
|
9
|
+
command: string;
|
|
10
|
+
/** Arguments after the command name */
|
|
11
|
+
args: string;
|
|
12
|
+
/** Response text to send back to the user */
|
|
13
|
+
response: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function parseCommand(text: string): {
|
|
16
|
+
command: string;
|
|
17
|
+
args: string;
|
|
18
|
+
} | null;
|
|
19
|
+
export declare function handleCommand(text: string): CommandResult | null;
|
|
20
|
+
//# sourceMappingURL=command-gating.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-gating.d.ts","sourceRoot":"","sources":["../../src/channels/command-gating.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAA;IACf,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAA;IACZ,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAA;CACjB;AAeD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAYnF;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAYhE"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command gating - intercepts slash commands (e.g. /help, /status, /stop)
|
|
3
|
+
* before they reach the agent, handling them locally.
|
|
4
|
+
*
|
|
5
|
+
* Returns null if the message is not a command and should be forwarded to the agent.
|
|
6
|
+
*/
|
|
7
|
+
const BUILT_IN_COMMANDS = {
|
|
8
|
+
help: () => [
|
|
9
|
+
'Available commands:',
|
|
10
|
+
' /help - Show this help',
|
|
11
|
+
' /status - Show agents-bridge status',
|
|
12
|
+
' /stop - Stop the current agent session',
|
|
13
|
+
].join('\n'),
|
|
14
|
+
status: () => 'agents-bridge is running.',
|
|
15
|
+
stop: () => 'Session stop requested.',
|
|
16
|
+
};
|
|
17
|
+
export function parseCommand(text) {
|
|
18
|
+
const trimmed = text.trim();
|
|
19
|
+
if (!trimmed.startsWith('/'))
|
|
20
|
+
return null;
|
|
21
|
+
const spaceIdx = trimmed.indexOf(' ');
|
|
22
|
+
if (spaceIdx === -1) {
|
|
23
|
+
return { command: trimmed.slice(1).toLowerCase(), args: '' };
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
command: trimmed.slice(1, spaceIdx).toLowerCase(),
|
|
27
|
+
args: trimmed.slice(spaceIdx + 1).trim(),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export function handleCommand(text) {
|
|
31
|
+
const parsed = parseCommand(text);
|
|
32
|
+
if (!parsed)
|
|
33
|
+
return null;
|
|
34
|
+
const handler = BUILT_IN_COMMANDS[parsed.command];
|
|
35
|
+
if (!handler)
|
|
36
|
+
return null;
|
|
37
|
+
return {
|
|
38
|
+
command: parsed.command,
|
|
39
|
+
args: parsed.args,
|
|
40
|
+
response: handler(parsed.args),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=command-gating.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-gating.js","sourceRoot":"","sources":["../../src/channels/command-gating.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,MAAM,iBAAiB,GAA6C;IAClE,IAAI,EAAE,GAAG,EAAE,CAAC;QACV,qBAAqB;QACrB,4BAA4B;QAC5B,uCAAuC;QACvC,4CAA4C;KAC7C,CAAC,IAAI,CAAC,IAAI,CAAC;IAEZ,MAAM,EAAE,GAAG,EAAE,CAAC,2BAA2B;IAEzC,IAAI,EAAE,GAAG,EAAE,CAAC,yBAAyB;CACtC,CAAA;AAED,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAC3B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAEzC,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACrC,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAA;IAC9D,CAAC;IACD,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,WAAW,EAAE;QACjD,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE;KACzC,CAAA;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;IACjC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAExB,MAAM,OAAO,GAAG,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACjD,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAA;IAEzB,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC;KAC/B,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Controls for pausing/resuming/aborting a draft stream.
|
|
3
|
+
* Used by outbound adapters to manage backpressure from the channel API
|
|
4
|
+
* (e.g. rate limiting on editMessageText).
|
|
5
|
+
*/
|
|
6
|
+
export declare class DraftStreamControls {
|
|
7
|
+
private _paused;
|
|
8
|
+
private _aborted;
|
|
9
|
+
private resumeResolve;
|
|
10
|
+
pause(): void;
|
|
11
|
+
resume(): void;
|
|
12
|
+
abort(): void;
|
|
13
|
+
get paused(): boolean;
|
|
14
|
+
get aborted(): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Await this before sending the next chunk.
|
|
17
|
+
* Resolves immediately if not paused, otherwise waits for resume().
|
|
18
|
+
*/
|
|
19
|
+
waitIfPaused(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=draft-stream-controls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draft-stream-controls.d.ts","sourceRoot":"","sources":["../../src/channels/draft-stream-controls.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,aAAa,CAA4B;IAEjD,KAAK,IAAI,IAAI;IAIb,MAAM,IAAI,IAAI;IAQd,KAAK,IAAI,IAAI;IAMb,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;CAMpC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Controls for pausing/resuming/aborting a draft stream.
|
|
3
|
+
* Used by outbound adapters to manage backpressure from the channel API
|
|
4
|
+
* (e.g. rate limiting on editMessageText).
|
|
5
|
+
*/
|
|
6
|
+
export class DraftStreamControls {
|
|
7
|
+
_paused = false;
|
|
8
|
+
_aborted = false;
|
|
9
|
+
resumeResolve = null;
|
|
10
|
+
pause() {
|
|
11
|
+
this._paused = true;
|
|
12
|
+
}
|
|
13
|
+
resume() {
|
|
14
|
+
this._paused = false;
|
|
15
|
+
if (this.resumeResolve) {
|
|
16
|
+
this.resumeResolve();
|
|
17
|
+
this.resumeResolve = null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
abort() {
|
|
21
|
+
this._aborted = true;
|
|
22
|
+
// Also resume to unblock any waiters
|
|
23
|
+
this.resume();
|
|
24
|
+
}
|
|
25
|
+
get paused() {
|
|
26
|
+
return this._paused;
|
|
27
|
+
}
|
|
28
|
+
get aborted() {
|
|
29
|
+
return this._aborted;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Await this before sending the next chunk.
|
|
33
|
+
* Resolves immediately if not paused, otherwise waits for resume().
|
|
34
|
+
*/
|
|
35
|
+
async waitIfPaused() {
|
|
36
|
+
if (!this._paused)
|
|
37
|
+
return;
|
|
38
|
+
return new Promise(resolve => {
|
|
39
|
+
this.resumeResolve = resolve;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=draft-stream-controls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draft-stream-controls.js","sourceRoot":"","sources":["../../src/channels/draft-stream-controls.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,OAAO,mBAAmB;IACtB,OAAO,GAAG,KAAK,CAAA;IACf,QAAQ,GAAG,KAAK,CAAA;IAChB,aAAa,GAAwB,IAAI,CAAA;IAEjD,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAA;IACrB,CAAC;IAED,MAAM;QACJ,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;QACpB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,IAAI,CAAC,aAAa,EAAE,CAAA;YACpB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAA;QAC3B,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;QACpB,qCAAqC;QACrC,IAAI,CAAC,MAAM,EAAE,CAAA;IACf,CAAC;IAED,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAA;IACrB,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAA;IACtB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,YAAY;QAChB,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAM;QACzB,OAAO,IAAI,OAAO,CAAO,OAAO,CAAC,EAAE;YACjC,IAAI,CAAC,aAAa,GAAG,OAAO,CAAA;QAC9B,CAAC,CAAC,CAAA;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Logger } from '../types/index.js';
|
|
2
|
+
/** Returns the message_id of the created message */
|
|
3
|
+
export type SendFn = (text: string) => Promise<number>;
|
|
4
|
+
export type EditFn = (messageId: number, text: string) => Promise<void>;
|
|
5
|
+
export interface DraftStreamOpts {
|
|
6
|
+
/** Initial send function — called once to create the message */
|
|
7
|
+
send: SendFn;
|
|
8
|
+
/** Edit function — called to update the message with new content */
|
|
9
|
+
edit: EditFn;
|
|
10
|
+
/** Debounce interval for edit calls (ms). Default: 1000 */
|
|
11
|
+
debounceMs?: number;
|
|
12
|
+
logger: Logger;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Manages the streaming reply lifecycle:
|
|
16
|
+
* 1. First chunk → sendMessage (creates the message, gets message_id)
|
|
17
|
+
* 2. Subsequent chunks → editMessageText (updates in place, debounced)
|
|
18
|
+
* 3. On complete → final editMessageText with full content
|
|
19
|
+
*/
|
|
20
|
+
export declare class DraftStreamLoop {
|
|
21
|
+
private messageId;
|
|
22
|
+
private buffer;
|
|
23
|
+
private debounceTimer;
|
|
24
|
+
private readonly opts;
|
|
25
|
+
constructor(opts: DraftStreamOpts);
|
|
26
|
+
push(chunk: string): Promise<void>;
|
|
27
|
+
complete(): Promise<void>;
|
|
28
|
+
private scheduleEdit;
|
|
29
|
+
getBuffer(): string;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=draft-stream-loop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draft-stream-loop.d.ts","sourceRoot":"","sources":["../../src/channels/draft-stream-loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAE/C,oDAAoD;AACpD,MAAM,MAAM,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;AACtD,MAAM,MAAM,MAAM,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAEvE,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAA;IACZ,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAA;IACZ,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;;GAKG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,aAAa,CAA8B;IACnD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA2B;gBAEpC,IAAI,EAAE,eAAe;IAO3B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAalC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAa/B,OAAO,CAAC,YAAY;IAgBpB,SAAS,IAAI,MAAM;CAGpB"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manages the streaming reply lifecycle:
|
|
3
|
+
* 1. First chunk → sendMessage (creates the message, gets message_id)
|
|
4
|
+
* 2. Subsequent chunks → editMessageText (updates in place, debounced)
|
|
5
|
+
* 3. On complete → final editMessageText with full content
|
|
6
|
+
*/
|
|
7
|
+
export class DraftStreamLoop {
|
|
8
|
+
messageId = null;
|
|
9
|
+
buffer = '';
|
|
10
|
+
debounceTimer = null;
|
|
11
|
+
opts;
|
|
12
|
+
constructor(opts) {
|
|
13
|
+
this.opts = {
|
|
14
|
+
debounceMs: 1000,
|
|
15
|
+
...opts,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
async push(chunk) {
|
|
19
|
+
this.buffer += chunk;
|
|
20
|
+
if (this.messageId === null) {
|
|
21
|
+
// First chunk: send initial message, capture message_id
|
|
22
|
+
this.messageId = await this.opts.send(this.buffer);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// Schedule debounced edit
|
|
26
|
+
this.scheduleEdit();
|
|
27
|
+
}
|
|
28
|
+
async complete() {
|
|
29
|
+
// Cancel pending debounce
|
|
30
|
+
if (this.debounceTimer) {
|
|
31
|
+
clearTimeout(this.debounceTimer);
|
|
32
|
+
this.debounceTimer = null;
|
|
33
|
+
}
|
|
34
|
+
// Final edit with complete content
|
|
35
|
+
if (this.messageId !== null && this.buffer) {
|
|
36
|
+
await this.opts.edit(this.messageId, this.buffer);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
scheduleEdit() {
|
|
40
|
+
if (this.debounceTimer)
|
|
41
|
+
return;
|
|
42
|
+
if (this.messageId === null)
|
|
43
|
+
return;
|
|
44
|
+
this.debounceTimer = setTimeout(async () => {
|
|
45
|
+
this.debounceTimer = null;
|
|
46
|
+
if (this.messageId !== null) {
|
|
47
|
+
try {
|
|
48
|
+
await this.opts.edit(this.messageId, this.buffer);
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
this.opts.logger.warn({ err }, 'Failed to edit message in stream');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}, this.opts.debounceMs);
|
|
55
|
+
}
|
|
56
|
+
getBuffer() {
|
|
57
|
+
return this.buffer;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=draft-stream-loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"draft-stream-loop.js","sourceRoot":"","sources":["../../src/channels/draft-stream-loop.ts"],"names":[],"mappings":"AAgBA;;;;;GAKG;AACH,MAAM,OAAO,eAAe;IAClB,SAAS,GAAkB,IAAI,CAAA;IAC/B,MAAM,GAAG,EAAE,CAAA;IACX,aAAa,GAA0B,IAAI,CAAA;IAClC,IAAI,CAA2B;IAEhD,YAAY,IAAqB;QAC/B,IAAI,CAAC,IAAI,GAAG;YACV,UAAU,EAAE,IAAI;YAChB,GAAG,IAAI;SACR,CAAA;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa;QACtB,IAAI,CAAC,MAAM,IAAI,KAAK,CAAA;QAEpB,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YAC5B,wDAAwD;YACxD,IAAI,CAAC,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YAClD,OAAM;QACR,CAAC;QAED,0BAA0B;QAC1B,IAAI,CAAC,YAAY,EAAE,CAAA;IACrB,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,0BAA0B;QAC1B,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YAChC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAA;QAC3B,CAAC;QAED,mCAAmC;QACnC,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC3C,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;QACnD,CAAC;IACH,CAAC;IAEO,YAAY;QAClB,IAAI,IAAI,CAAC,aAAa;YAAE,OAAM;QAC9B,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI;YAAE,OAAM;QAEnC,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC,KAAK,IAAI,EAAE;YACzC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAA;YACzB,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;gBAC5B,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,CAAA;gBACnD,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,kCAAkC,CAAC,CAAA;gBACpE,CAAC;YACH,CAAC;QACH,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAC1B,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAA;IACpB,CAAC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detects whether a message is directed at a specific bot via @mention.
|
|
3
|
+
* In group/multi_bot chats, agents should only respond when mentioned.
|
|
4
|
+
*/
|
|
5
|
+
export interface MentionGatingOpts {
|
|
6
|
+
/** The bot's username (without @) */
|
|
7
|
+
botUsername: string;
|
|
8
|
+
/** Chat type */
|
|
9
|
+
chatType: 'private' | 'group' | 'multi_bot';
|
|
10
|
+
/** Extracted @mentions from the message */
|
|
11
|
+
mentions: string[];
|
|
12
|
+
}
|
|
13
|
+
export declare function isMentioned(opts: MentionGatingOpts): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Strip @mention prefix from message text for cleaner agent input.
|
|
16
|
+
*/
|
|
17
|
+
export declare function stripMentions(text: string, mentions: string[]): string;
|
|
18
|
+
//# sourceMappingURL=mention-gating.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mention-gating.d.ts","sourceRoot":"","sources":["../../src/channels/mention-gating.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC,qCAAqC;IACrC,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB;IAChB,QAAQ,EAAE,SAAS,GAAG,OAAO,GAAG,WAAW,CAAA;IAC3C,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAM5D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAQtE"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function isMentioned(opts) {
|
|
2
|
+
// In private chats, always respond
|
|
3
|
+
if (opts.chatType === 'private')
|
|
4
|
+
return true;
|
|
5
|
+
const botUsernameLower = opts.botUsername.toLowerCase();
|
|
6
|
+
return opts.mentions.some(m => m.toLowerCase() === botUsernameLower);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Strip @mention prefix from message text for cleaner agent input.
|
|
10
|
+
*/
|
|
11
|
+
export function stripMentions(text, mentions) {
|
|
12
|
+
let result = text;
|
|
13
|
+
for (const mention of mentions) {
|
|
14
|
+
// Escape special regex characters in username to prevent ReDoS
|
|
15
|
+
const escaped = mention.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
16
|
+
result = result.replace(new RegExp(`@${escaped}\\s*`, 'gi'), '');
|
|
17
|
+
}
|
|
18
|
+
return result.trim();
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=mention-gating.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mention-gating.js","sourceRoot":"","sources":["../../src/channels/mention-gating.ts"],"names":[],"mappings":"AAaA,MAAM,UAAU,WAAW,CAAC,IAAuB;IACjD,mCAAmC;IACnC,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IAE5C,MAAM,gBAAgB,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAA;IACvD,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,gBAAgB,CAAC,CAAA;AACtE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,QAAkB;IAC5D,IAAI,MAAM,GAAG,IAAI,CAAA;IACjB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,+DAA+D;QAC/D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;QAC9D,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,IAAI,OAAO,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAA;IAClE,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,EAAE,CAAA;AACtB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ChannelPlugin } from '../types/index.js';
|
|
2
|
+
export declare function registerChannel(plugin: ChannelPlugin): void;
|
|
3
|
+
export declare function getChannel(id: string): ChannelPlugin | undefined;
|
|
4
|
+
export declare function getAllChannels(): ChannelPlugin[];
|
|
5
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/channels/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AAItD,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAK3D;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAEhE;AAED,wBAAgB,cAAc,IAAI,aAAa,EAAE,CAEhD"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const registry = new Map();
|
|
2
|
+
export function registerChannel(plugin) {
|
|
3
|
+
if (registry.has(plugin.id)) {
|
|
4
|
+
throw new Error(`Channel plugin "${plugin.id}" is already registered`);
|
|
5
|
+
}
|
|
6
|
+
registry.set(plugin.id, plugin);
|
|
7
|
+
}
|
|
8
|
+
export function getChannel(id) {
|
|
9
|
+
return registry.get(id);
|
|
10
|
+
}
|
|
11
|
+
export function getAllChannels() {
|
|
12
|
+
return Array.from(registry.values());
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/channels/registry.ts"],"names":[],"mappings":"AAEA,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAyB,CAAA;AAEjD,MAAM,UAAU,eAAe,CAAC,MAAqB;IACnD,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,CAAC,EAAE,yBAAyB,CAAC,CAAA;IACxE,CAAC;IACD,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;AACjC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EAAU;IACnC,OAAO,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;AACzB,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;AACtC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Logger } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Channel lifecycle states.
|
|
4
|
+
*
|
|
5
|
+
* Transitions:
|
|
6
|
+
* idle → connecting → polling → disconnected → connecting (retry loop)
|
|
7
|
+
* ↓
|
|
8
|
+
* stopped
|
|
9
|
+
*/
|
|
10
|
+
export type ChannelState = 'idle' | 'connecting' | 'polling' | 'disconnected' | 'stopped';
|
|
11
|
+
export type StateChangeHandler = (from: ChannelState, to: ChannelState) => void;
|
|
12
|
+
export declare class ChannelStateMachine {
|
|
13
|
+
private state;
|
|
14
|
+
private readonly logger;
|
|
15
|
+
private readonly handlers;
|
|
16
|
+
constructor(logger: Logger);
|
|
17
|
+
getState(): ChannelState;
|
|
18
|
+
onStateChange(handler: StateChangeHandler): void;
|
|
19
|
+
transition(to: ChannelState): void;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=run-state-machine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-state-machine.d.ts","sourceRoot":"","sources":["../../src/channels/run-state-machine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAE/C;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,YAAY,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,CAAA;AAEzF,MAAM,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,YAAY,KAAK,IAAI,CAAA;AAE/E,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;gBAExC,MAAM,EAAE,MAAM;IAI1B,QAAQ,IAAI,YAAY;IAIxB,aAAa,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI;IAIhD,UAAU,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI;CAqBnC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export class ChannelStateMachine {
|
|
2
|
+
state = 'idle';
|
|
3
|
+
logger;
|
|
4
|
+
handlers = [];
|
|
5
|
+
constructor(logger) {
|
|
6
|
+
this.logger = logger;
|
|
7
|
+
}
|
|
8
|
+
getState() {
|
|
9
|
+
return this.state;
|
|
10
|
+
}
|
|
11
|
+
onStateChange(handler) {
|
|
12
|
+
this.handlers.push(handler);
|
|
13
|
+
}
|
|
14
|
+
transition(to) {
|
|
15
|
+
const from = this.state;
|
|
16
|
+
// Validate transitions
|
|
17
|
+
const valid = TRANSITIONS[from];
|
|
18
|
+
if (!valid?.includes(to)) {
|
|
19
|
+
this.logger.warn({ from, to }, 'Invalid state transition attempted');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
this.state = to;
|
|
23
|
+
this.logger.info({ from, to }, 'Channel state transition');
|
|
24
|
+
for (const handler of this.handlers) {
|
|
25
|
+
try {
|
|
26
|
+
handler(from, to);
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
this.logger.warn({ err }, 'State change handler error');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const TRANSITIONS = {
|
|
35
|
+
idle: ['connecting'],
|
|
36
|
+
connecting: ['polling', 'disconnected', 'stopped'],
|
|
37
|
+
polling: ['disconnected', 'stopped'],
|
|
38
|
+
disconnected: ['connecting', 'stopped'],
|
|
39
|
+
stopped: [],
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=run-state-machine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-state-machine.js","sourceRoot":"","sources":["../../src/channels/run-state-machine.ts"],"names":[],"mappings":"AAcA,MAAM,OAAO,mBAAmB;IACtB,KAAK,GAAiB,MAAM,CAAA;IACnB,MAAM,CAAQ;IACd,QAAQ,GAAyB,EAAE,CAAA;IAEpD,YAAY,MAAc;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAED,aAAa,CAAC,OAA2B;QACvC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC7B,CAAC;IAED,UAAU,CAAC,EAAgB;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAA;QAEvB,uBAAuB;QACvB,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAA;QAC/B,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,oCAAoC,CAAC,CAAA;YACpE,OAAM;QACR,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,EAAE,CAAA;QACf,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,0BAA0B,CAAC,CAAA;QAE1D,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,IAAI,CAAC;gBACH,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;YACnB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,4BAA4B,CAAC,CAAA;YACzD,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAED,MAAM,WAAW,GAAyC;IACxD,IAAI,EAAE,CAAC,YAAY,CAAC;IACpB,UAAU,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,SAAS,CAAC;IAClD,OAAO,EAAE,CAAC,cAAc,EAAE,SAAS,CAAC;IACpC,YAAY,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC;IACvC,OAAO,EAAE,EAAE;CACZ,CAAA"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { SessionEnvelope } from '../types/index.js';
|
|
2
|
+
export type { SessionEnvelope };
|
|
3
|
+
export declare function makeSessionId(botToken: string, chatId: number | string): string;
|
|
4
|
+
export declare function isValidEnvelope(envelope: unknown): envelope is SessionEnvelope;
|
|
5
|
+
//# sourceMappingURL=session-envelope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-envelope.d.ts","sourceRoot":"","sources":["../../src/channels/session-envelope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAExD,YAAY,EAAE,eAAe,EAAE,CAAA;AAE/B,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAE/E;AAED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,IAAI,eAAe,CAS9E"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export function makeSessionId(botToken, chatId) {
|
|
2
|
+
return `${botToken}:${chatId}`;
|
|
3
|
+
}
|
|
4
|
+
export function isValidEnvelope(envelope) {
|
|
5
|
+
if (!envelope || typeof envelope !== 'object')
|
|
6
|
+
return false;
|
|
7
|
+
const e = envelope;
|
|
8
|
+
return (typeof e.sessionId === 'string' &&
|
|
9
|
+
typeof e.source === 'object' &&
|
|
10
|
+
typeof e.content === 'object' &&
|
|
11
|
+
typeof e.meta === 'object');
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=session-envelope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-envelope.js","sourceRoot":"","sources":["../../src/channels/session-envelope.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,MAAuB;IACrE,OAAO,GAAG,QAAQ,IAAI,MAAM,EAAE,CAAA;AAChC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAAiB;IAC/C,IAAI,CAAC,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC3D,MAAM,CAAC,GAAG,QAAmC,CAAA;IAC7C,OAAO,CACL,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ;QAC/B,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ;QAC5B,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ;QAC7B,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAC3B,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Logger, SessionEnvelope } from '../types/index.js';
|
|
2
|
+
export interface Session {
|
|
3
|
+
id: string;
|
|
4
|
+
chatId: number | string;
|
|
5
|
+
chatType: 'private' | 'group' | 'multi_bot';
|
|
6
|
+
createdAt: number;
|
|
7
|
+
lastActivityAt: number;
|
|
8
|
+
}
|
|
9
|
+
export declare class SessionManager {
|
|
10
|
+
private sessions;
|
|
11
|
+
private readonly logger;
|
|
12
|
+
constructor(logger: Logger);
|
|
13
|
+
getOrCreate(envelope: SessionEnvelope): Session;
|
|
14
|
+
get(sessionId: string): Session | undefined;
|
|
15
|
+
delete(sessionId: string): void;
|
|
16
|
+
size(): number;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/channels/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAEhE,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,QAAQ,EAAE,SAAS,GAAG,OAAO,GAAG,WAAW,CAAA;IAC3C,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;gBAEnB,MAAM,EAAE,MAAM;IAI1B,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO;IAoB/C,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAI3C,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAK/B,IAAI,IAAI,MAAM;CAGf"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export class SessionManager {
|
|
2
|
+
sessions = new Map();
|
|
3
|
+
logger;
|
|
4
|
+
constructor(logger) {
|
|
5
|
+
this.logger = logger;
|
|
6
|
+
}
|
|
7
|
+
getOrCreate(envelope) {
|
|
8
|
+
const existing = this.sessions.get(envelope.sessionId);
|
|
9
|
+
if (existing) {
|
|
10
|
+
existing.lastActivityAt = Date.now();
|
|
11
|
+
return existing;
|
|
12
|
+
}
|
|
13
|
+
const session = {
|
|
14
|
+
id: envelope.sessionId,
|
|
15
|
+
chatId: envelope.source.chatId,
|
|
16
|
+
chatType: envelope.source.chatType,
|
|
17
|
+
createdAt: Date.now(),
|
|
18
|
+
lastActivityAt: Date.now(),
|
|
19
|
+
};
|
|
20
|
+
this.sessions.set(session.id, session);
|
|
21
|
+
this.logger.info({ sessionId: session.id, chatType: session.chatType }, 'New session created');
|
|
22
|
+
return session;
|
|
23
|
+
}
|
|
24
|
+
get(sessionId) {
|
|
25
|
+
return this.sessions.get(sessionId);
|
|
26
|
+
}
|
|
27
|
+
delete(sessionId) {
|
|
28
|
+
this.sessions.delete(sessionId);
|
|
29
|
+
this.logger.info({ sessionId }, 'Session deleted');
|
|
30
|
+
}
|
|
31
|
+
size() {
|
|
32
|
+
return this.sessions.size;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/channels/session.ts"],"names":[],"mappings":"AAUA,MAAM,OAAO,cAAc;IACjB,QAAQ,GAAG,IAAI,GAAG,EAAmB,CAAA;IAC5B,MAAM,CAAQ;IAE/B,YAAY,MAAc;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED,WAAW,CAAC,QAAyB;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;QACtD,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;YACpC,OAAO,QAAQ,CAAA;QACjB,CAAC;QAED,MAAM,OAAO,GAAY;YACvB,EAAE,EAAE,QAAQ,CAAC,SAAS;YACtB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM;YAC9B,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,QAAQ;YAClC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE;SAC3B,CAAA;QAED,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;QACtC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,EAAE,qBAAqB,CAAC,CAAA;QAC9F,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,GAAG,CAAC,SAAiB;QACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IACrC,CAAC;IAED,MAAM,CAAC,SAAiB;QACtB,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAC/B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,EAAE,iBAAiB,CAAC,CAAA;IACpD,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAA;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Logger } from '../types/index.js';
|
|
2
|
+
export type SendTypingFn = () => Promise<void>;
|
|
3
|
+
/**
|
|
4
|
+
* Sends periodic "typing" indicators while an agent is working.
|
|
5
|
+
* Most platforms require the typing action to be re-sent every ~5s.
|
|
6
|
+
*/
|
|
7
|
+
export declare class TypingLifecycle {
|
|
8
|
+
private timer;
|
|
9
|
+
private readonly sendTyping;
|
|
10
|
+
private readonly intervalMs;
|
|
11
|
+
private readonly logger;
|
|
12
|
+
constructor(sendTyping: SendTypingFn, intervalMs?: number, logger?: Logger);
|
|
13
|
+
start(): void;
|
|
14
|
+
stop(): void;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=typing-lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typing-lifecycle.d.ts","sourceRoot":"","sources":["../../src/channels/typing-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAE/C,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;AAE9C;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAc;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;gBAEnB,UAAU,EAAE,YAAY,EAAE,UAAU,SAAO,EAAE,MAAM,CAAC,EAAE,MAAM;IAMxE,KAAK,IAAI,IAAI;IASb,IAAI,IAAI,IAAI;CAMb"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sends periodic "typing" indicators while an agent is working.
|
|
3
|
+
* Most platforms require the typing action to be re-sent every ~5s.
|
|
4
|
+
*/
|
|
5
|
+
export class TypingLifecycle {
|
|
6
|
+
timer = null;
|
|
7
|
+
sendTyping;
|
|
8
|
+
intervalMs;
|
|
9
|
+
logger;
|
|
10
|
+
constructor(sendTyping, intervalMs = 4000, logger) {
|
|
11
|
+
this.sendTyping = sendTyping;
|
|
12
|
+
this.intervalMs = intervalMs;
|
|
13
|
+
this.logger = logger ?? { warn: () => { }, info: () => { } };
|
|
14
|
+
}
|
|
15
|
+
start() {
|
|
16
|
+
if (this.timer)
|
|
17
|
+
return;
|
|
18
|
+
// Send immediately, then repeat
|
|
19
|
+
this.sendTyping().catch(err => this.logger.warn({ err }, 'Failed to send typing indicator'));
|
|
20
|
+
this.timer = setInterval(() => {
|
|
21
|
+
this.sendTyping().catch(err => this.logger.warn({ err }, 'Failed to send typing indicator'));
|
|
22
|
+
}, this.intervalMs);
|
|
23
|
+
}
|
|
24
|
+
stop() {
|
|
25
|
+
if (this.timer) {
|
|
26
|
+
clearInterval(this.timer);
|
|
27
|
+
this.timer = null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=typing-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typing-lifecycle.js","sourceRoot":"","sources":["../../src/channels/typing-lifecycle.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,OAAO,eAAe;IAClB,KAAK,GAA0B,IAAI,CAAA;IAC1B,UAAU,CAAc;IACxB,UAAU,CAAQ;IAClB,MAAM,CAAQ;IAE/B,YAAY,UAAwB,EAAE,UAAU,GAAG,IAAI,EAAE,MAAe;QACtE,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,IAAK,EAAE,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC,EAAwB,CAAA;IACnF,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,KAAK;YAAE,OAAM;QACtB,gCAAgC;QAChC,IAAI,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,iCAAiC,CAAC,CAAC,CAAA;QAC5F,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,iCAAiC,CAAC,CAAC,CAAA;QAC9F,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;IACrB,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACzB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;QACnB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cmd-config.d.ts","sourceRoot":"","sources":["../../src/cli/cmd-config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAE5C,wBAAsB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB5D"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { DATA_CONFIG_PATH } from '../config/paths.js';
|
|
3
|
+
export async function cmdConfig(args) {
|
|
4
|
+
const configPath = args.config ?? DATA_CONFIG_PATH;
|
|
5
|
+
if (!existsSync(configPath)) {
|
|
6
|
+
console.log(`No config file found at ${configPath}`);
|
|
7
|
+
console.log('Run `agents-bridge onboard` to create one.');
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
console.log(`--- ${configPath} ---`);
|
|
11
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
12
|
+
const redacted = content.replace(/("bot_token"\s*:\s*)"[^"]*"/g, '$1"***REDACTED***"');
|
|
13
|
+
console.log(redacted);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=cmd-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cmd-config.js","sourceRoot":"","sources":["../../src/cli/cmd-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAGrD,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAa;IAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,IAAI,gBAAgB,CAAA;IAElD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,2BAA2B,UAAU,EAAE,CAAC,CAAA;QACpD,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAA;QACzD,OAAM;IACR,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,OAAO,UAAU,MAAM,CAAC,CAAA;IACpC,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;IACjD,MAAM,QAAQ,GAAG,OAAO,CAAC,OAAO,CAC9B,8BAA8B,EAC9B,oBAAoB,CACrB,CAAA;IACD,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;AACvB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cmd-doctor.d.ts","sourceRoot":"","sources":["../../src/cli/cmd-doctor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAiC5C,wBAAsB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CA6C7D"}
|