@0xmaxma/claude-gateway 1.7.6 → 1.7.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 +1 -1
- package/dist/agent/builtin-commands.d.ts +2 -1
- package/dist/agent/builtin-commands.d.ts.map +1 -1
- package/dist/agent/builtin-commands.js.map +1 -1
- package/dist/agent/incident.d.ts +1 -1
- package/dist/agent/incident.d.ts.map +1 -1
- package/dist/agent/runner.d.ts +7 -2
- package/dist/agent/runner.d.ts.map +1 -1
- package/dist/agent/runner.js +141 -9
- package/dist/agent/runner.js.map +1 -1
- package/dist/api/line-webhook-router.js +8 -8
- package/dist/api/line-webhook-router.js.map +1 -1
- package/dist/api/{line-pending-senders.d.ts → pending-senders.d.ts} +13 -13
- package/dist/api/pending-senders.d.ts.map +1 -0
- package/dist/api/pending-senders.js +128 -0
- package/dist/api/pending-senders.js.map +1 -0
- package/dist/api/router.d.ts.map +1 -1
- package/dist/api/router.js +296 -10
- package/dist/api/router.js.map +1 -1
- package/dist/api/slack-access.d.ts +74 -0
- package/dist/api/slack-access.d.ts.map +1 -0
- package/dist/api/slack-access.js +78 -0
- package/dist/api/slack-access.js.map +1 -0
- package/dist/api/slack-client.d.ts +68 -0
- package/dist/api/slack-client.d.ts.map +1 -0
- package/dist/api/slack-client.js +121 -0
- package/dist/api/slack-client.js.map +1 -0
- package/dist/api/slack-webhook-router.d.ts +34 -0
- package/dist/api/slack-webhook-router.d.ts.map +1 -0
- package/dist/api/slack-webhook-router.js +280 -0
- package/dist/api/slack-webhook-router.js.map +1 -0
- package/dist/api/webhooks-router.d.ts +18 -9
- package/dist/api/webhooks-router.d.ts.map +1 -1
- package/dist/api/webhooks-router.js +12 -7
- package/dist/api/webhooks-router.js.map +1 -1
- package/dist/cli-viewer/pairing-store.d.ts +3 -2
- package/dist/cli-viewer/pairing-store.d.ts.map +1 -1
- package/dist/cli-viewer/pairing-store.js +3 -5
- package/dist/cli-viewer/pairing-store.js.map +1 -1
- package/dist/history/types.d.ts +29 -1
- package/dist/history/types.d.ts.map +1 -1
- package/dist/history/types.js +32 -0
- package/dist/history/types.js.map +1 -1
- package/dist/session/compactor.d.ts +2 -1
- package/dist/session/compactor.d.ts.map +1 -1
- package/dist/session/compactor.js.map +1 -1
- package/dist/session/process.d.ts +17 -2
- package/dist/session/process.d.ts.map +1 -1
- package/dist/session/process.js +102 -9
- package/dist/session/process.js.map +1 -1
- package/dist/session/store.d.ts +14 -13
- package/dist/session/store.d.ts.map +1 -1
- package/dist/session/store.js +7 -2
- package/dist/session/store.js.map +1 -1
- package/dist/shell/claude-pty-shell.js +13 -0
- package/dist/shell/claude-pty-shell.js.map +1 -1
- package/dist/types.d.ts +37 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/cli-viewer-ui.d.ts +2 -1
- package/dist/ui/cli-viewer-ui.d.ts.map +1 -1
- package/dist/ui/cli-viewer-ui.js.map +1 -1
- package/mcp/server.ts +2 -0
- package/mcp/tools/slack/module.ts +113 -0
- package/package.json +1 -1
- package/dist/api/line-pending-senders.d.ts.map +0 -1
- package/dist/api/line-pending-senders.js +0 -112
- package/dist/api/line-pending-senders.js.map +0 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ A self-hosted multi-agent gateway for Claude Code — with agents that improve t
|
|
|
15
15
|
- 📚 **Knowledge base (two-lane memory)** — per-agent SQLite/FTS5 searchable archive exposed through `memory_search` / `memory_get` MCP tools, so agents recall notes that don't fit the always-injected core; chunks carry fail-closed provenance and the index is refreshed off the gateway event loop. See [`gateway.knowledge`](#gatewayknowledge)
|
|
16
16
|
- 🌙 **Nightly dreaming** — background consolidation of long-term memory: a print-only reviewer proposes ops that a safe applier writes to `MEMORY.md` / `USER.md` (backup, bounded-loss, net-negative when over budget). Deterministic compaction, budget-scaled pruning, and staleness GC keep memory near budget without forgetting — archived entries stay searchable. See [`gateway.dreaming`](#gatewaydreaming)
|
|
17
17
|
- 🤖 **Multi-agent** — run multiple bots from a single gateway, each with isolated sessions
|
|
18
|
-
- 🔌 **Multi-channel MCP** — modular tool system per channel (Telegram, Discord, Cron, Skills, extensible to
|
|
18
|
+
- 🔌 **Multi-channel MCP** — modular tool system per channel (Telegram, Discord, LINE, Slack, Cron, Skills, extensible to more)
|
|
19
19
|
- 🧩 **Agent skills** — extensible skill system via SKILL.md files; agents can create, delete, and install skills from URLs at runtime with hot-reload
|
|
20
20
|
- 🎭 **Agent identity** — define personality, tone, and rules via workspace markdown files
|
|
21
21
|
- 📡 **Live status messages** — real-time status updates showing tool usage, thinking, and progress
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
import type { ChatChannelOrApi } from '../history/types';
|
|
2
|
+
export type CommandChannel = ChatChannelOrApi;
|
|
2
3
|
interface CommandDef {
|
|
3
4
|
channels: CommandChannel[];
|
|
4
5
|
/** word-boundary check: true (default) = /^\/cmd\b/, false = /^\/cmd(\s|$)/ */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtin-commands.d.ts","sourceRoot":"","sources":["../../src/agent/builtin-commands.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"builtin-commands.d.ts","sourceRoot":"","sources":["../../src/agent/builtin-commands.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,MAAM,MAAM,cAAc,GAAG,gBAAgB,CAAC;AAE9C,UAAU,UAAU;IAClB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,+EAA+E;IAC/E,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAcvD,CAAC;AA0BF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAElF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtin-commands.js","sourceRoot":"","sources":["../../src/agent/builtin-commands.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"builtin-commands.js","sourceRoot":"","sources":["../../src/agent/builtin-commands.ts"],"names":[],"mappings":";;;AAkDA,4CAEC;AA1CY,QAAA,gBAAgB,GAA+B;IAC1D,OAAO,EAAG,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE;IACtD,QAAQ,EAAE,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE;IACtD,GAAG,EAAO,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE;IACpE,MAAM,EAAI,EAAE,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE;IACzD,KAAK,EAAK,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE;IAC3C,OAAO,EAAG,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE;IAC3C,IAAI,EAAM,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE;IAChE,KAAK,EAAK,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE;IACtD,MAAM,EAAI,EAAE,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE;IACpC,OAAO,EAAG,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE;IAChE,KAAK,EAAK,EAAE,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE;IACpC,IAAI,EAAM,EAAE,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE;IACpC,MAAM,EAAI,EAAE,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE;CACrC,CAAC;AAEF,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;AAEjD,SAAS,UAAU,CAAC,OAAuB;IACzC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,wBAAgB,CAAC;SAC3C,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;SACnD,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CAClB,GAAG,CAAC,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,CACjE,CAAC;IACJ,yEAAyE;IACzE,2EAA2E;IAC3E,4DAA4D;IAC5D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IACtC,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,SAAS,QAAQ,CAAC,OAAuB;IACvC,IAAI,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7B,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;QACzB,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAgB,gBAAgB,CAAC,OAAe,EAAE,OAAuB;IACvE,OAAO,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AAChD,CAAC"}
|
package/dist/agent/incident.d.ts
CHANGED
|
@@ -51,7 +51,7 @@ export interface IncidentManifest {
|
|
|
51
51
|
cliVersion: string;
|
|
52
52
|
/** Gateway version at capture time, or 'unknown'. Context only. */
|
|
53
53
|
gatewayVersion: string;
|
|
54
|
-
/** Transport name only: 'telegram' | 'discord' | 'line' | 'api'. */
|
|
54
|
+
/** Transport name only: 'telegram' | 'discord' | 'line' | 'slack' | 'api'. */
|
|
55
55
|
channel: string;
|
|
56
56
|
/** First and most-recent occurrence (epoch ms). */
|
|
57
57
|
firstAt: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"incident.d.ts","sourceRoot":"","sources":["../../src/agent/incident.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAE/D,0EAA0E;AAC1E,eAAO,MAAM,SAAS,yBAAe,CAAA;AAErC,4DAA4D;AAC5D,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,QAAQ,GAAG,aAAa,CAAA;AAEhE,gDAAgD;AAChD,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,UAAU,CAAA;AAEhD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,EAAE,EAAE,MAAM,CAAA;IACV,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAA;IACf,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAA;IAChB,2EAA2E;IAC3E,OAAO,EAAE,OAAO,CAAA;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gEAAgE;IAChE,EAAE,EAAE,MAAM,CAAA;IACV,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,SAAS,CAAA;IAChB,YAAY,EAAE,gBAAgB,GAAG,IAAI,CAAA;IACrC,iFAAiF;IACjF,UAAU,EAAE,MAAM,CAAA;IAClB,mEAAmE;IACnE,cAAc,EAAE,MAAM,CAAA;IACtB,
|
|
1
|
+
{"version":3,"file":"incident.d.ts","sourceRoot":"","sources":["../../src/agent/incident.ts"],"names":[],"mappings":"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"}
|
package/dist/agent/runner.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { AgentConfig, GatewayConfig, Logger, ModelConfig, StreamEvent, ApiAttach
|
|
|
3
3
|
import { type SkillRegistry } from '../skills';
|
|
4
4
|
import { type CliChannel } from '../cli-viewer/pairing-store';
|
|
5
5
|
import { HistoryDB } from '../history/db';
|
|
6
|
+
import type { ChatChannel } from '../history/types';
|
|
6
7
|
import type { SkillLearningManager } from './skill-learning';
|
|
7
8
|
export declare const MAX_IMAGE_SIZE_BYTES: number;
|
|
8
9
|
export declare const DEFAULT_MODELS: ModelConfig[];
|
|
@@ -34,9 +35,11 @@ export declare class AgentRunner extends EventEmitter {
|
|
|
34
35
|
private channelFor;
|
|
35
36
|
private readonly sessions;
|
|
36
37
|
private readonly channelSourceMap;
|
|
38
|
+
private readonly slackThreadTs;
|
|
37
39
|
private receiver;
|
|
38
40
|
private discordReceiver;
|
|
39
41
|
private lineReply;
|
|
42
|
+
private slackOutbound;
|
|
40
43
|
private readonly sessionStore;
|
|
41
44
|
private readonly idleTimeoutMs;
|
|
42
45
|
private readonly maxConcurrent;
|
|
@@ -350,6 +353,8 @@ export declare class AgentRunner extends EventEmitter {
|
|
|
350
353
|
private startIdleCleaner;
|
|
351
354
|
start(): Promise<void>;
|
|
352
355
|
updateAgentConfig(newConfig: AgentConfig): void;
|
|
356
|
+
startSlackOutbound(): void;
|
|
357
|
+
stopSlackOutbound(): void;
|
|
353
358
|
startLineReply(): void;
|
|
354
359
|
stopLineReply(): void;
|
|
355
360
|
getAgentConfig(): AgentConfig;
|
|
@@ -452,7 +457,7 @@ export declare class AgentRunner extends EventEmitter {
|
|
|
452
457
|
imageConfig?: ImageParams;
|
|
453
458
|
model?: string;
|
|
454
459
|
}>>;
|
|
455
|
-
listSessionsForChat(chatId: string, channel:
|
|
460
|
+
listSessionsForChat(chatId: string, channel: ChatChannel): Promise<import('../types').SessionIndex>;
|
|
456
461
|
executeApiCommand(sessionId: string, chatId: string, command: string, opts?: {
|
|
457
462
|
skipPersist?: boolean;
|
|
458
463
|
model?: string;
|
|
@@ -477,7 +482,7 @@ export declare class AgentRunner extends EventEmitter {
|
|
|
477
482
|
* The session process receives full history context from the session JSON (Layer 1).
|
|
478
483
|
* The reply is streamed back via SSE callbacks and persisted to history DB.
|
|
479
484
|
*/
|
|
480
|
-
sendMessageToSession(rawChatId: string, channel:
|
|
485
|
+
sendMessageToSession(rawChatId: string, channel: ChatChannel, sessionId: string, message: string, senderName: string | undefined, callbacks: {
|
|
481
486
|
onChunk: (event: StreamEvent) => void;
|
|
482
487
|
onDone: (fullText: string) => void;
|
|
483
488
|
onError: (err: Error) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/agent/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAMtC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,EAAW,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/agent/runner.ts"],"names":[],"mappings":"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"}
|
package/dist/agent/runner.js
CHANGED
|
@@ -47,6 +47,7 @@ const compactor_1 = require("../session/compactor");
|
|
|
47
47
|
const receiver_1 = require("../telegram/receiver");
|
|
48
48
|
const receiver_2 = require("../discord/receiver");
|
|
49
49
|
const line_reply_manager_1 = require("./line-reply-manager");
|
|
50
|
+
const slack_client_1 = require("../api/slack-client");
|
|
50
51
|
const markdown_1 = require("../telegram/markdown");
|
|
51
52
|
const skills_1 = require("../skills");
|
|
52
53
|
const builtin_commands_1 = require("./builtin-commands");
|
|
@@ -193,10 +194,22 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
193
194
|
// Session pool
|
|
194
195
|
this.sessions = new Map();
|
|
195
196
|
this.channelSourceMap = new Map();
|
|
197
|
+
// Slack only: the thread_ts of the most recent inbound message per chat, so
|
|
198
|
+
// the auto-forward fallback path (command replies, socket-drop notices, the
|
|
199
|
+
// no-tool-call assistant fallback) can reply in-thread the same way the
|
|
200
|
+
// slack_reply tool does. Set when an inbound Slack turn carries thread_ts,
|
|
201
|
+
// cleared when a top-level message arrives so a later fallback doesn't leak
|
|
202
|
+
// into a stale thread.
|
|
203
|
+
this.slackThreadTs = new Map();
|
|
196
204
|
this.receiver = null;
|
|
197
205
|
this.discordReceiver = null;
|
|
198
206
|
// LINE slow-LLM postback button manager (null when LINE disabled or threshold=0).
|
|
199
207
|
this.lineReply = null;
|
|
208
|
+
// Slack has no reply-token TTL to work around (see the plan's "no reply-manager
|
|
209
|
+
// needed" note), so unlike LINE this is a plain client, not a stateful manager —
|
|
210
|
+
// it exists only so writeAutoForward's fallback/command-reply path (below) has
|
|
211
|
+
// somewhere to actually deliver Slack messages instead of silently dropping them.
|
|
212
|
+
this.slackOutbound = null;
|
|
200
213
|
this.idleCleanerTimer = null;
|
|
201
214
|
// Tracks session IDs with an in-flight API request (prevents concurrent turns)
|
|
202
215
|
this.pendingApiSessions = new Set();
|
|
@@ -393,8 +406,21 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
393
406
|
? 'discord'
|
|
394
407
|
: meta['source'] === 'line'
|
|
395
408
|
? 'line'
|
|
396
|
-
: '
|
|
409
|
+
: meta['source'] === 'slack'
|
|
410
|
+
? 'slack'
|
|
411
|
+
: 'telegram');
|
|
397
412
|
this.channelSourceMap.set(chatId, channelSource);
|
|
413
|
+
// Slack: remember the current message's thread context so the
|
|
414
|
+
// auto-forward fallback (writeAutoForward) can stay in-thread. A
|
|
415
|
+
// top-level message clears it so a later fallback isn't misrouted
|
|
416
|
+
// into a thread the user already left.
|
|
417
|
+
if (channelSource === 'slack') {
|
|
418
|
+
const threadTs = meta['thread_ts'];
|
|
419
|
+
if (threadTs)
|
|
420
|
+
this.slackThreadTs.set(chatId, threadTs);
|
|
421
|
+
else
|
|
422
|
+
this.slackThreadTs.delete(chatId);
|
|
423
|
+
}
|
|
398
424
|
// LINE slow-LLM postback: stash this turn's reply token + arm the
|
|
399
425
|
// button timer before the token expires. In groups/rooms the shared
|
|
400
426
|
// button is disabled (armButton:false) — the token is still stashed so
|
|
@@ -1147,6 +1173,10 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
1147
1173
|
'attachment_name',
|
|
1148
1174
|
'user_id', // LINE: the userId the session passes back to line_reply
|
|
1149
1175
|
'reply_token', // LINE: single-use reply token (push is preferred; surfaced for completeness)
|
|
1176
|
+
'thread_ts', // Slack: set when the inbound message is inside a thread — pass back as thread_id to slack_reply to reply in-thread
|
|
1177
|
+
// NOTE: message_id is NOT listed here — the base <channel> template below
|
|
1178
|
+
// already unconditionally emits it; adding it here would duplicate the
|
|
1179
|
+
// attribute in the XML whenever meta.message_id is set (any channel).
|
|
1150
1180
|
]
|
|
1151
1181
|
.filter(k => meta[k])
|
|
1152
1182
|
.map(k => ` ${k}="${meta[k].replace(/"/g, '"')}"`)
|
|
@@ -1183,6 +1213,15 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
1183
1213
|
waitForSessionRestart(proc) {
|
|
1184
1214
|
if (proc.isRunning())
|
|
1185
1215
|
return Promise.resolve();
|
|
1216
|
+
// Dead with no respawn in flight → the restarted/restartFailed/failed events
|
|
1217
|
+
// this waits on will never fire, so blocking for the full timeout only to
|
|
1218
|
+
// reject is pointless. Fail fast so the caller recovers immediately. (The
|
|
1219
|
+
// primary caller, getOrSpawnSession, already guards on isRestartScheduled()
|
|
1220
|
+
// and respawns instead of calling here; this is a defence-in-depth backstop
|
|
1221
|
+
// for any other caller.) See #371.
|
|
1222
|
+
if (!proc.isRestartScheduled()) {
|
|
1223
|
+
return Promise.reject(new Error('Session is not running and no restart is scheduled'));
|
|
1224
|
+
}
|
|
1186
1225
|
return new Promise((resolve, reject) => {
|
|
1187
1226
|
const timer = setTimeout(() => {
|
|
1188
1227
|
cleanup();
|
|
@@ -1228,8 +1267,36 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
1228
1267
|
// but THIS gap is hit before a turn even starts, so that fix can't see
|
|
1229
1268
|
// it). Wait for the pending respawn to actually land before handing the
|
|
1230
1269
|
// session back.
|
|
1231
|
-
|
|
1232
|
-
|
|
1270
|
+
//
|
|
1271
|
+
// But only wait if a respawn is actually in flight. A session can also be
|
|
1272
|
+
// dead with NOTHING coming — permanently failed (max restarts), or stopped
|
|
1273
|
+
// without eviction. Handing that corpse back would wedge the caller:
|
|
1274
|
+
// sendMessage() no-ops on a null child, and waitForSessionRestart would
|
|
1275
|
+
// block for the full timeout waiting on a restarted/failed event that will
|
|
1276
|
+
// never fire. Drop it and spawn a fresh session instead so the message is
|
|
1277
|
+
// served immediately. See #371.
|
|
1278
|
+
if (!existing.isRunning()) {
|
|
1279
|
+
if (existing.isRestartScheduled()) {
|
|
1280
|
+
await this.waitForSessionRestart(existing);
|
|
1281
|
+
}
|
|
1282
|
+
else {
|
|
1283
|
+
this.logger.warn('Mapped session is dead with no restart in flight — respawning fresh', {
|
|
1284
|
+
mapKey, source,
|
|
1285
|
+
});
|
|
1286
|
+
const respawn = (async () => {
|
|
1287
|
+
await existing.stop(); // idempotent on a dead child; closes watchers + signal file
|
|
1288
|
+
this.sessions.delete(mapKey);
|
|
1289
|
+
return this.spawnSession(mapKey, source, sessionId, effectiveOverride);
|
|
1290
|
+
})();
|
|
1291
|
+
this.sessionSpawnLocks.set(mapKey, respawn);
|
|
1292
|
+
try {
|
|
1293
|
+
return await respawn;
|
|
1294
|
+
}
|
|
1295
|
+
finally {
|
|
1296
|
+
this.sessionSpawnLocks.delete(mapKey);
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1233
1300
|
// Restart if model changed (including switching back to the agent default)
|
|
1234
1301
|
if (existing.modelOverride !== effectiveOverride) {
|
|
1235
1302
|
this.logger.info('Model changed, restarting session', { mapKey, oldModel: existing.modelOverride, newModel: effectiveOverride ?? agentDefaultModel });
|
|
@@ -1314,6 +1381,17 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
1314
1381
|
// Forward all session output lines so listeners on AgentRunner (GatewayRouter,
|
|
1315
1382
|
// CronScheduler, tests) receive them without needing individual session references.
|
|
1316
1383
|
proc.on('output', (line) => this.emit('output', line));
|
|
1384
|
+
// API sessions get NONE of the channel lifecycle handlers below (the whole
|
|
1385
|
+
// block is gated to source !== 'api'), so a permanent failure would
|
|
1386
|
+
// otherwise leave the dead SessionProcess in the pool: the next
|
|
1387
|
+
// getOrSpawnSession returns it and, finding no auto-restart in flight, would
|
|
1388
|
+
// block on waitForSessionRestart for the full 20s timeout before rejecting —
|
|
1389
|
+
// the "wedge" #371 describes. Remove it from the pool on failure so the next
|
|
1390
|
+
// message spawns a fresh session instead. (Channel sessions already do this
|
|
1391
|
+
// inside the notify handler below.)
|
|
1392
|
+
if (source === 'api') {
|
|
1393
|
+
proc.once('failed', () => this.sessions.delete(mapKey));
|
|
1394
|
+
}
|
|
1317
1395
|
// Notify typing indicator when session permanently fails (max restarts exceeded)
|
|
1318
1396
|
if (source !== 'api') {
|
|
1319
1397
|
proc.once('failed', () => {
|
|
@@ -1359,7 +1437,9 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
1359
1437
|
? 'mcp__gateway__discord_reply'
|
|
1360
1438
|
: source === 'line'
|
|
1361
1439
|
? 'mcp__gateway__line_reply'
|
|
1362
|
-
: '
|
|
1440
|
+
: source === 'slack'
|
|
1441
|
+
? 'mcp__gateway__slack_reply'
|
|
1442
|
+
: 'mcp__gateway__telegram_reply';
|
|
1363
1443
|
proc.on('output', (line) => {
|
|
1364
1444
|
try {
|
|
1365
1445
|
const obj = JSON.parse(line);
|
|
@@ -1629,7 +1709,12 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
1629
1709
|
if (channelSrcForResult === 'line' && this.lineReply) {
|
|
1630
1710
|
void this.lineReply.onAnswer(mapKey, channelText);
|
|
1631
1711
|
}
|
|
1632
|
-
else if (channelSrcForResult !== 'discord' &&
|
|
1712
|
+
else if (channelSrcForResult !== 'discord' &&
|
|
1713
|
+
channelSrcForResult !== 'slack' &&
|
|
1714
|
+
((0, markdown_1.hasMarkdown)(channelText) || (0, markdown_1.containsTelegramHtml)(channelText))) {
|
|
1715
|
+
// Telegram HTML entities — Slack has its own mrkdwn format and
|
|
1716
|
+
// would display these tags literally, so Slack skips this and
|
|
1717
|
+
// falls through to the plain-text branch below.
|
|
1633
1718
|
this.writeAutoForward(mapKey, (0, markdown_1.toTelegramHtml)(channelText), 'html');
|
|
1634
1719
|
}
|
|
1635
1720
|
else {
|
|
@@ -2247,6 +2332,25 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
2247
2332
|
void this.lineReply.onAnswer(chatId, text);
|
|
2248
2333
|
return;
|
|
2249
2334
|
}
|
|
2335
|
+
// Slack likewise has no .forward consumer (only Telegram/Discord receivers
|
|
2336
|
+
// poll that directory) — post directly via the outbound client instead.
|
|
2337
|
+
// Without this branch every command reply (/stop, /rename, /sessions,
|
|
2338
|
+
// /compact), the Anthropic-socket-drop notice, and the plain-text
|
|
2339
|
+
// assistant-fallback path (no tool call) silently vanished for Slack.
|
|
2340
|
+
if (this.channelFor(chatId) === 'slack') {
|
|
2341
|
+
if (this.slackOutbound) {
|
|
2342
|
+
// Reply in-thread when the last inbound message was threaded (mirrors
|
|
2343
|
+
// the slack_reply tool's thread_id behavior); top-level otherwise.
|
|
2344
|
+
const threadTs = this.slackThreadTs.get(chatId);
|
|
2345
|
+
void this.slackOutbound.postMessage(chatId, text, threadTs).catch((err) => {
|
|
2346
|
+
this.logger.warn('Slack auto-forward failed', {
|
|
2347
|
+
chatId,
|
|
2348
|
+
error: err instanceof Error ? err.message : String(err),
|
|
2349
|
+
});
|
|
2350
|
+
});
|
|
2351
|
+
}
|
|
2352
|
+
return;
|
|
2353
|
+
}
|
|
2250
2354
|
const typingDir = this.getTypingDir(chatId);
|
|
2251
2355
|
try {
|
|
2252
2356
|
fs.mkdirSync(typingDir, { recursive: true });
|
|
@@ -2304,6 +2408,7 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
2304
2408
|
// Enabled for any LINE agent unless its threshold is 0 (then the MCP
|
|
2305
2409
|
// line_reply tool keeps the plain reply-first → push-fallback path).
|
|
2306
2410
|
this.startLineReply();
|
|
2411
|
+
this.startSlackOutbound();
|
|
2307
2412
|
this.startIdleCleaner();
|
|
2308
2413
|
this._startCleanupScheduler();
|
|
2309
2414
|
this.logger.info('AgentRunner started', { agentId: this.agentConfig.id });
|
|
@@ -2314,6 +2419,23 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
2314
2419
|
// picks up a new access token, threshold, or labels without a full restart.
|
|
2315
2420
|
this.stopLineReply();
|
|
2316
2421
|
this.startLineReply();
|
|
2422
|
+
// Slack token/secret may have changed (or been cleared) — rebuild to pick
|
|
2423
|
+
// it up, same reasoning as LineReplyManager above.
|
|
2424
|
+
this.stopSlackOutbound();
|
|
2425
|
+
this.startSlackOutbound();
|
|
2426
|
+
}
|
|
2427
|
+
startSlackOutbound() {
|
|
2428
|
+
if (!this.agentConfig.slack?.botToken || !this.agentConfig.slack?.signingSecret)
|
|
2429
|
+
return;
|
|
2430
|
+
if (this.slackOutbound)
|
|
2431
|
+
return; // already running
|
|
2432
|
+
this.slackOutbound = new slack_client_1.SlackClient({
|
|
2433
|
+
botToken: this.agentConfig.slack.botToken,
|
|
2434
|
+
logDir: this.gatewayConfig.gateway.logDir,
|
|
2435
|
+
});
|
|
2436
|
+
}
|
|
2437
|
+
stopSlackOutbound() {
|
|
2438
|
+
this.slackOutbound = null;
|
|
2317
2439
|
}
|
|
2318
2440
|
startLineReply() {
|
|
2319
2441
|
const lineThreshold = this.agentConfig.line?.slowResponseThreshold ?? 45;
|
|
@@ -3147,8 +3269,9 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
3147
3269
|
//
|
|
3148
3270
|
// skipPersist (wire param store_user_message=false) suppresses BOTH the user command and
|
|
3149
3271
|
// the assistant reply: programmatic REST callers leave no trace in chat history at all.
|
|
3150
|
-
|
|
3151
|
-
|
|
3272
|
+
// `force` overrides that for notes that must stay visible regardless (see /stop below).
|
|
3273
|
+
const persist = (role, content, force = false) => {
|
|
3274
|
+
if ((skipPersist && !force) || !content)
|
|
3152
3275
|
return;
|
|
3153
3276
|
this.historyDb.insertMessage({ chatId: dbChatId, sessionId, source: 'api', role, content, ts: Date.now() });
|
|
3154
3277
|
};
|
|
@@ -3159,6 +3282,7 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
3159
3282
|
}
|
|
3160
3283
|
let result;
|
|
3161
3284
|
let responseText;
|
|
3285
|
+
let forcePersist = false;
|
|
3162
3286
|
try {
|
|
3163
3287
|
if (cmd === '/model') {
|
|
3164
3288
|
const model = this.agentConfig.claude.model;
|
|
@@ -3172,7 +3296,14 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
3172
3296
|
const session = this.sessions.get(sessionId);
|
|
3173
3297
|
const stopped = session ? session.interrupt() : false;
|
|
3174
3298
|
result = { stopped };
|
|
3175
|
-
responseText = stopped
|
|
3299
|
+
responseText = stopped
|
|
3300
|
+
? 'Session was interrupted before I could respond.'
|
|
3301
|
+
: 'No active session to stop.';
|
|
3302
|
+
// A turn was actually cut off — always leave a visible note in history so the
|
|
3303
|
+
// web Stop button (skipPersist:true, to suppress the "/stop" command echo) and
|
|
3304
|
+
// a typed /stop command show the same outcome instead of the button leaving a
|
|
3305
|
+
// silently-dangling user turn.
|
|
3306
|
+
forcePersist = stopped;
|
|
3176
3307
|
}
|
|
3177
3308
|
else if (cmd === '/restart') {
|
|
3178
3309
|
this.restartProcess(sessionId).catch(() => { });
|
|
@@ -3282,7 +3413,8 @@ class AgentRunner extends events_1.EventEmitter {
|
|
|
3282
3413
|
}
|
|
3283
3414
|
// Persist the human-readable response as an assistant turn so the conversation ends with
|
|
3284
3415
|
// an assistant message (the web's computeIsPendingResponse needs last.role !== 'user').
|
|
3285
|
-
|
|
3416
|
+
// forcePersist writes it even under skipPersist (set only when /stop cut a turn off).
|
|
3417
|
+
persist('assistant', responseText, forcePersist);
|
|
3286
3418
|
return { result, responseText };
|
|
3287
3419
|
}
|
|
3288
3420
|
async setModel(newModel) {
|