@geminixiang/mikan 1.0.0-beta.60 → 1.0.0-beta.61
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/CHANGELOG.md +22 -0
- package/dist/adapters/intake.js +12 -2
- package/dist/adapters/intake.js.map +1 -1
- package/dist/adapters/progressive-renderer.d.ts.map +1 -1
- package/dist/adapters/progressive-renderer.js +4 -0
- package/dist/adapters/progressive-renderer.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +2 -0
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +127 -4
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/task-status.d.ts +7 -0
- package/dist/adapters/slack/task-status.d.ts.map +1 -0
- package/dist/adapters/slack/task-status.js +101 -0
- package/dist/adapters/slack/task-status.js.map +1 -0
- package/dist/adapters/web/session-view/portal.js +2 -1
- package/dist/adapters/web/session-view/portal.js.map +1 -1
- package/dist/harness/presenter.d.ts +1 -0
- package/dist/harness/presenter.d.ts.map +1 -1
- package/dist/harness/presenter.js +37 -9
- package/dist/harness/presenter.js.map +1 -1
- package/dist/harness/prompt.d.ts.map +1 -1
- package/dist/harness/prompt.js +5 -0
- package/dist/harness/prompt.js.map +1 -1
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +57 -25
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session.d.ts +3 -0
- package/dist/harness/session.d.ts.map +1 -1
- package/dist/harness/session.js +21 -1
- package/dist/harness/session.js.map +1 -1
- package/dist/harness/tools/index.d.ts +2 -0
- package/dist/harness/tools/index.d.ts.map +1 -1
- package/dist/harness/tools/index.js +4 -0
- package/dist/harness/tools/index.js.map +1 -1
- package/dist/harness/tools/task.d.ts +20 -0
- package/dist/harness/tools/task.d.ts.map +1 -0
- package/dist/harness/tools/task.js +79 -0
- package/dist/harness/tools/task.js.map +1 -0
- package/dist/runtime/conversation-runtime.d.ts.map +1 -1
- package/dist/runtime/conversation-runtime.js +34 -13
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/types.d.ts +2 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sessions/chat-history-sync.js +8 -3
- package/dist/sessions/chat-history-sync.js.map +1 -1
- package/dist/sessions/session-store.d.ts +8 -0
- package/dist/sessions/session-store.d.ts.map +1 -1
- package/dist/sessions/session-store.js +46 -21
- package/dist/sessions/session-store.js.map +1 -1
- package/dist/types.d.ts +20 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,28 @@ any release.
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [1.0.0-beta.61]
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- Ground Slack DM progress replies in runtime/v4 task observations; common task-thread status queries no longer steer work, and ordinary followups do not repeat completion mentions.
|
|
17
|
+
- Slack DM task handoff: independent task threads keep the main conversation free, with text steering in active task threads and continuation after stopping.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- Keep thread stop acknowledgements in the source thread, including shared-channel unmentioned stop controls.
|
|
22
|
+
- Notify Slack DM task requesters with a fresh in-thread mention after normal completion.
|
|
23
|
+
- Finalize stop acknowledgements that arrive after the cancelled run has already settled.
|
|
24
|
+
- Propagate final response delivery failures so rejected updates do not trigger completion notifications.
|
|
25
|
+
- Honor stop during runner preparation and keep older active tasks visible in status queries.
|
|
26
|
+
- Report task admission, asynchronous startup, and status inspection failures through the existing Sentry/OTLP observability path.
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- Publish the already built and verified npm package without rerunning build and repository setup lifecycle scripts.
|
|
31
|
+
- Keep the documented and CI coverage commands as stable entry points while maintaining their shared Vitest invocation in one place.
|
|
32
|
+
- Validate debug Session View selections from their path and header, leaving full parsing to consumers that load session content instead of inspecting the same file twice.
|
|
33
|
+
|
|
12
34
|
## [1.0.0-beta.60]
|
|
13
35
|
|
|
14
36
|
### Fixed
|
package/dist/adapters/intake.js
CHANGED
|
@@ -83,10 +83,20 @@ async function handleStopMagicWord(options) {
|
|
|
83
83
|
target = resolveOnlyScopedStopTarget(handler, address);
|
|
84
84
|
}
|
|
85
85
|
if (target) {
|
|
86
|
-
|
|
86
|
+
if (eventBase.thread_ts) {
|
|
87
|
+
await handler.handleStop(address, target, bot, eventBase.thread_ts);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
await handler.handleStop(address, target, bot);
|
|
91
|
+
}
|
|
87
92
|
}
|
|
88
93
|
else if (magicWord.addressed) {
|
|
89
|
-
|
|
94
|
+
if (eventBase.thread_ts && bot.postInThread) {
|
|
95
|
+
await bot.postInThread(conversationId, eventBase.thread_ts, formatNothingRunning(bot));
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
await bot.postMessage(conversationId, formatNothingRunning(bot));
|
|
99
|
+
}
|
|
90
100
|
}
|
|
91
101
|
}
|
|
92
102
|
function widensToScopedSession(scopeFallback, sessionKey, conversationId) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intake.js","sourceRoot":"","sources":["../../src/adapters/intake.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"intake.js","sourceRoot":"","sources":["../../src/adapters/intake.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n assertSessionKeyBelongsToConversation,\n assertConversationId,\n} from \"../sessions/session-key.js\";\nimport type { ConversationEvent } from \"../adapter.js\";\nimport { formatAlreadyWorking, formatNothingRunning } from \"../platform-messages.js\";\nimport { resolveOnlyScopedStopTarget, resolveStopTarget } from \"./shared.js\";\nimport type { MessageIntakeOptions, MessageIntakeOutcome } from \"./types.js\";\n\n/**\n * Recognize a magic word: a highest-priority chat control phrase that bypasses\n * trigger policy and queueing (see CONTEXT.md). One grammar for every\n * platform: optional leading slash, optional `@botname` suffix, any case.\n */\nexport function matchMagicWord(text: string): \"stop\" | null {\n return /^\\/?stop(?:@\\w+)?$/i.test(text.trim()) ? \"stop\" : null;\n}\n\n/**\n * Shared message ingress pipeline for platform adapters.\n *\n * Platform adapters normalize SDK events; this module owns the ordering for\n * messages that may start an agent run:\n *\n * magic word → trigger policy → attachments → log → busy policy → queue → dispatch\n *\n * Magic words are matched before the trigger gate — `stop` must never wait on\n * trigger filtering or queue behind a running agent turn. Adapters state\n * platform policy as data (`magicWord`, `busyPolicy`) instead of callbacks.\n */\nexport async function processMessageIntake<TEvent extends ConversationEvent>(\n options: MessageIntakeOptions<TEvent>,\n): Promise<MessageIntakeOutcome> {\n assertConversationId(options.eventBase.conversationId);\n if (options.eventBase.sessionKey !== undefined) {\n assertSessionKeyBelongsToConversation(\n options.eventBase.sessionKey,\n options.eventBase.conversationId,\n );\n }\n if (matchMagicWord(options.magicWord.text ?? options.eventBase.text) === \"stop\") {\n options.log?.({ ...options.logEntryBase, attachments: [] });\n await handleStopMagicWord(options);\n return \"magic-word\";\n }\n\n if (!options.addressed) {\n options.log?.({ ...options.logEntryBase, attachments: [] });\n return \"not-triggered\";\n }\n\n function prepareEvent(attachments: unknown[]): TEvent {\n const event = { ...options.eventBase, attachments } as TEvent;\n options.log?.({ ...options.logEntryBase, attachments });\n return event;\n }\n\n async function rejectedWhileBusy(): Promise<boolean> {\n const sessionKey = options.eventBase.sessionKey ?? options.eventBase.conversationId;\n if (!options.handler.isRunning(options.eventBase.address, sessionKey)) return false;\n await options.bot.postMessage(\n options.eventBase.conversationId,\n formatAlreadyWorking(options.bot, \"/stop\"),\n );\n return true;\n }\n\n function dispatch(event: TEvent): Promise<void> {\n const context = options.createContext(event);\n return options.handler.handleEvent(event, options.bot, context);\n }\n\n if (options.deferAttachmentsUntilRun) {\n // Busy rejection happens inside the queued work here, so the outcome is\n // already \"enqueued\" by the time it is evaluated.\n options.enqueue(options.queueKey, async () => {\n const event = prepareEvent(await options.processAttachments());\n if (options.busyPolicy === \"reject\" && (await rejectedWhileBusy())) return;\n return dispatch(event);\n });\n return \"enqueued\";\n }\n\n const event = prepareEvent(await options.processAttachments());\n if (options.busyPolicy === \"reject\" && (await rejectedWhileBusy())) return \"rejected-busy\";\n options.enqueue(options.queueKey, () => dispatch(event));\n return \"enqueued\";\n}\n\n/**\n * Resolve and stop the session a magic-word `stop` targets. When nothing is\n * running, reply only if the message addressed the bot — an unaddressed\n * \"stop\" in a busy channel should never make the bot pipe up.\n */\nasync function handleStopMagicWord<TEvent extends ConversationEvent>(\n options: MessageIntakeOptions<TEvent>,\n): Promise<void> {\n const { handler, bot, eventBase, magicWord } = options;\n const address = eventBase.address;\n const conversationId = eventBase.conversationId;\n const sessionKey = eventBase.sessionKey;\n\n let target = resolveStopTarget({ handler, address, sessionKey });\n if (!target && widensToScopedSession(magicWord.scopeFallback, sessionKey, conversationId)) {\n target = resolveOnlyScopedStopTarget(handler, address);\n }\n\n if (target) {\n if (eventBase.thread_ts) {\n await handler.handleStop(address, target, bot, eventBase.thread_ts);\n } else {\n await handler.handleStop(address, target, bot);\n }\n } else if (magicWord.addressed) {\n if (eventBase.thread_ts && bot.postInThread) {\n await bot.postInThread(conversationId, eventBase.thread_ts, formatNothingRunning(bot));\n } else {\n await bot.postMessage(conversationId, formatNothingRunning(bot));\n }\n }\n}\n\nfunction widensToScopedSession(\n scopeFallback: \"top-level\" | \"always\" | \"never\",\n sessionKey: string | undefined,\n conversationId: string,\n): boolean {\n if (scopeFallback === \"never\") return false;\n if (scopeFallback === \"always\") return true;\n // \"top-level\": only a message aimed at the persistent conversation session\n // may widen to the single running scoped session; thread messages stay put.\n return sessionKey === undefined || sessionKey === conversationId;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progressive-renderer.d.ts","sourceRoot":"","sources":["../../src/adapters/progressive-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EAEtB,MAAM,eAAe,CAAC;AAQvB,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAE9D,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CASvE;
|
|
1
|
+
{"version":3,"file":"progressive-renderer.d.ts","sourceRoot":"","sources":["../../src/adapters/progressive-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EAEtB,MAAM,eAAe,CAAC;AAQvB,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAE9D,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CASvE;AA6hBD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,2BAA2B,GAAG;IAChF,SAAS,EAAE,qBAAqB,CAAC;CAClC,CAEA"}
|
|
@@ -244,6 +244,10 @@ class ProgressiveRenderer {
|
|
|
244
244
|
// A secondary notification must not poison the response queue.
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
|
+
// Incremental/status updates are best effort. Replacements and finalization
|
|
248
|
+
// are delivery boundaries: callers must not mistake a rejected send for success.
|
|
249
|
+
if (label === "replaceResponse" || label === "finishResponse")
|
|
250
|
+
throw err;
|
|
247
251
|
});
|
|
248
252
|
this.queueTail = handled.catch(() => undefined);
|
|
249
253
|
return handled;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progressive-renderer.js","sourceRoot":"","sources":["../../src/adapters/progressive-renderer.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,+BAA+B,EAC/B,cAAc,EACd,SAAS,GAEV,MAAM,aAAa,CAAC;AAGrB,MAAM,UAAU,wBAAwB,CAAC,MAAsB;IAC7D,MAAM,aAAa,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACvD,IAAI,IAAI,GAAG,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ,IAAI,CAAC;IACzE,IAAI,MAAM,CAAC,KAAK;QAAE,IAAI,IAAI,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC;IAC9C,IAAI,IAAI,KAAK,QAAQ,MAAM,CAAC;IAC5B,IAAI,aAAa;QAAE,IAAI,IAAI,WAAW,aAAa,YAAY,CAAC;IAChE,IAAI,IAAI,wBAAwB,MAAM,CAAC,MAAM,UAAU,CAAC;IACxD,OAAO,IAAI,CAAC;AACd,CAAC;AAsBD;;;;;;;;;;;GAWG;AACH,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAEvC,MAAM,mBAAmB;IASvB,YAA6B,QAAqC;QAArC,aAAQ,GAAR,QAAQ,CAA6B;QAJjD,QAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QAExB,cAAS,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;QAGpC,IAAI,CAAC,KAAK,GAAG;YACX,UAAU,EAAE,QAAQ,CAAC,iBAAiB,IAAI,IAAI;YAC9C,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,IAAI;YACb,YAAY,EAAE,KAAK;YACnB,iBAAiB,EAAE,KAAK;YACxB,cAAc,EAAE,EAAE;YAClB,YAAY,EAAE,CAAC;YACf,WAAW,EAAE,CAAC;YACd,UAAU,EAAE,KAAK;YACjB,cAAc,EAAE,IAAI;YACpB,mBAAmB,EAAE,KAAK;YAC1B,QAAQ,EAAE,EAAE;YACZ,eAAe,EAAE,EAAE;SACpB,CAAC;QACF,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;QAC9D,IAAI,CAAC,mBAAmB,GAAG,QAAQ,CAAC,oBAAoB;YACtD,CAAC,CAAC,+BAA+B,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,oBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC9F,CAAC,CAAC,SAAS,CAAC;QACd,IAAI,CAAC,eAAe,GAAG,QAAQ,CAAC,eAAe,IAAI,yBAAyB,CAAC;QAC7E,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;IAC1C,CAAC;IAEO,eAAe;QACrB,OAAO;YACL,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YACrC,mBAAmB,EACjB,IAAI,CAAC,QAAQ,CAAC,cAAc,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM;gBAClD,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;gBACpC,CAAC,CAAC,SAAS;YACf,cAAc,EACZ,IAAI,CAAC,QAAQ,CAAC,cAAc,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM;gBAClD,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC;gBAC/C,CAAC,CAAC,SAAS;YACf,eAAe,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC;YACvE,uBAAuB,EAAE,IAAI,CAAC,QAAQ,CAAC,sBAAsB;gBAC3D,CAAC,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,uBAAuB,CAAC,QAAQ,EAAE,SAAS,CAAC;gBAC5E,CAAC,CAAC,SAAS;YACb,iBAAiB,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC;YAC3E,iBAAiB,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC;YAC7D,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;YACjD,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YACjD,UAAU,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC;YACjE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,EAAE;SAC5C,CAAC;IACJ,CAAC;IAEO,UAAU;QAChB,IAAI,IAAI,CAAC,KAAK,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YACvC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YACzC,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC;QACnC,CAAC;IACH,CAAC;IAEO,WAAW,CAAC,IAAY,EAAE,OAAgB;QAChD,IAAI,IAAI,CAAC,QAAQ,CAAC,iBAAiB;YAAE,OAAO,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC3F,OAAO,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC;IAClG,CAAC;IAEO,KAAK,CAAC,IAAY;QACxB,OAAO,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IACpF,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,IAAY;QACrC,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YACnC,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YACxD,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU;YAAE,IAAI,CAAC,UAAU,EAAE,CAAC;QACxD,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzD,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,IAAY;QAClC,MAAM,CAAC,IAAI,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC9B,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YACnD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC3B,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;gBACnD,SAAS;YACX,CAAC;YACD,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU;gBAAE,IAAI,CAAC,UAAU,EAAE,CAAC;YACxD,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACtE,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,IAAI;gBAAE,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAC9E,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,IAAY;QAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU;YAAE,IAAI,CAAC,UAAU,EAAE,CAAC;QACxD,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC7D,CAAC;IAEO,KAAK,CAAC,gBAAgB;QAC5B,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM;YAAE,OAAO;QAChG,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;QACvC,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC;QAChC,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC;QAC/B,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC;IAEO,KAAK,CAAC,mBAAmB;QAC/B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI;YAAE,OAAO;QACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;QACvC,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC;QAChC,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC;QAC/B,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACjE,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,QAAQ;YAAE,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;IACvE,CAAC;IAEO,KAAK,CAAC,SAAS,CACrB,IAAY,EACZ,SAA+B,EAC/B,OAA+C,EAC/C,aAAa,GAAG,IAAI;QAEpB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC3B,OAAO,aAAa,CAAC;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa;gBAAE,MAAM,GAAG,CAAC;YAC5C,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC;gBAAE,MAAM,GAAG,CAAC;YAClF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC;gBACjD,IAAI,EAAE,aAAa;gBACnB,SAAS;gBACT,OAAO;gBACP,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU;gBACjC,KAAK,EAAE,CAAC,YAAY,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC;gBACrD,aAAa,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU;aAC3C,CAAC,CAAC;YACH,OAAO,QAAQ,CAAC,IAAI,CAAC;QACvB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,IAAY;QACpC,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,OAAO,IAAI,CAAC;QACpD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;QACjF,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QACpC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC/D,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5C,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC7D,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,EAAE,CAAC;YAC/D,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC7D,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,IACE,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI;YAC9B,IAAI,CAAC,KAAK,CAAC,YAAY;YACvB,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,EAC/C,CAAC;YACD,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACjC,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC7D,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;gBACnC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;gBAC/D,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,CAAC,CAAC,EAAE,CAAC;oBACzD,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;oBAClD,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,QAAQ,CAAC;gBACvC,CAAC;gBACD,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YACrD,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;YAC/B,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,QAAQ,CAAC;YACrC,OAAO,QAAQ,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC;YACpC,GAAG,CAAC,UAAU,CACZ,wEAAwE,EACxE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CACjD,CAAC;YACF,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACjC,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC7D,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,IAAY;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QACpC,IAAI,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YACxE,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,IAAI,CAAC;gBACH,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;oBAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;oBAC3D,IAAI,KAAK;wBAAE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;oBAC7D,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;oBACzC,QAAQ,GAAG,IAAI,CAAC;gBAClB,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC;gBACpC,GAAG,CAAC,UAAU,CACZ,wEAAwE,EACxE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CACjD,CAAC;YACJ,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC;YAChC,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC;YAC/B,IAAI,QAAQ,EAAE,CAAC;gBACb,IAAI,IAAI,CAAC,QAAQ,CAAC,oBAAoB,EAAE,CAAC,IAAI,CAAC;oBAAE,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;gBACrF,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACnC,CAAC;QACD,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI,IAAI,IAAI;YAAE,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,GAAG,CACf,KAAa,EACb,SAAqC,EACrC,IAAyB,EACzB,KAAoC;QAEpC,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACnD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,GAAG,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,KAAK,QAAQ,EAAE,OAAO,CAAC,CAAC;YACjE,IAAI,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;YACpD,IAAI,IAAI,CAAC,QAAQ,CAAC,iBAAiB,EAAE,CAAC;gBACpC,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;gBACjD,CAAC;gBAAC,MAAM,CAAC;oBACP,+DAA+D;gBACjE,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAChD,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,KAAa;QACrC,MAAM,IAAI,CAAC,GAAG,CACZ,qBAAqB,EACrB,SAAS,EACT,KAAK,IAAI,EAAE;YACT,IAAI,CAAC,KAAK;gBAAE,OAAO;YACnB,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;gBAC1B,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;gBACvB,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC;YAChC,CAAC;YACD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACvC,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,SAAS,CAAC;YAC/B,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,SAAS,CAAC,MAAM,CAAC;YAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;YACpD,IACE,IAAI,CAAC,KAAK,CAAC,WAAW,KAAK,CAAC;gBAC5B,CAAC,OAAO,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,EAChE,CAAC;gBACD,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC;gBAC5B,IAAI,CAAC;oBACH,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBAChE,CAAC;wBAAS,CAAC;oBACT,kEAAkE;oBAClE,kEAAkE;oBAClE,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACtC,CAAC;YACH,CAAC;QACH,CAAC,EACD,GAAG,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,MAAM,EAAE,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAClF,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,IAAY;QAChC,MAAM,IAAI,CAAC,GAAG,CACZ,SAAS,EACT,SAAS,EACT,KAAK,IAAI,EAAE;YACT,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACtC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;YACzF,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC9D,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,wBAAwB,EAAE,CAAC;gBAC7E,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC9D,CAAC;QACH,CAAC,EACD,GAAG,EAAE,CAAC,CAAC;YACL,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc;YACxD,UAAU,EAAE,IAAI,CAAC,MAAM;YACvB,iBAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;SAC5C,CAAC,CACH,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,SAAkB;QAC7C,MAAM,IAAI,CAAC,GAAG,CACZ,gBAAgB,EAChB,aAAa,EACb,KAAK,IAAI,EAAE;YACT,IAAI,SAAS,KAAK,SAAS;gBAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAC1E,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC;YAC9B,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC;YAC5B,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;YAC3B,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC9D,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;gBACnC,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC3E,CAAC;YACD,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC3E,CAAC,EACD,GAAG,EAAE,CAAC,CAAC,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAC/C,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,eAAe,CAC3B,IAAY,EACZ,OAA+C;QAE/C,MAAM,IAAI,CAAC,GAAG,CACZ,iBAAiB,EACjB,kBAAkB,EAClB,KAAK,IAAI,EAAE;YACT,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC;YAC5B,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;YAC7B,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY;gBAAE,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC3D,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE;gBAAE,OAAO;YAC5D,MAAM,QAAQ,GACZ,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;YAC5F,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CACtC,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAC9C,SAAS,EACT,OAAO,EACP,QAAQ,CACT,CAAC;QACJ,CAAC,EACD,GAAG,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,mBAAmB,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CACzF,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,uBAAuB,CACnC,QAAkC,EAClC,SAAkB;QAElB,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,sBAAuB,CAAC,QAAQ,CAAC,CAAC;QAClE,MAAM,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,OAAO,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC/F,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAC7B,IAAY,EACZ,OAAO,GAAkC,EAAE;QAE3C,MAAM,IAAI,CAAC,GAAG,CACZ,mBAAmB,EACnB,oBAAoB,EACpB,KAAK,IAAI,EAAE;YACT,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc;gBACtC,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC;gBAC1E,CAAC,CAAC,MAAM,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACpD,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;QACnC,CAAC,EACD,GAAG,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAC1D,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,MAAsB;QACpD,MAAM,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;IACjF,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,QAAiB;QACvC,MAAM,IAAI,CAAC,GAAG,CACZ,WAAW,EACX,aAAa,EACb,KAAK,IAAI,EAAE;YACT,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;gBAC5B,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBAC/D,OAAO;YACT,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;YACpC,IAAI,CAAC,MAAM;gBAAE,OAAO;YACpB,MAAM,aAAa,GAAG,CAAC,GAAY,EAAQ,EAAE;gBAC3C,IAAI,IAAI,CAAC,KAAK,CAAC,mBAAmB;oBAAE,OAAO;gBAC3C,IAAI,CAAC,KAAK,CAAC,mBAAmB,GAAG,IAAI,CAAC;gBACtC,GAAG,CAAC,UAAU,CACZ,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,sEAAsE,EAC5F,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CACjD,CAAC;YACJ,CAAC,CAAC;YACF,IAAI,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;gBACnD,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;gBACnC,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,WAAW,CAAC,GAAG,EAAE;oBAC3C,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;gBACrC,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;YACxB,CAAC;iBAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACrB,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,CAAC;QACH,CAAC,EACD,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAC9B,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,OAAgB;QACvC,MAAM,IAAI,CAAC,GAAG,CACZ,YAAY,EACZ,aAAa,EACb,KAAK,IAAI,EAAE;YACT,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;YAC7B,IAAI,CAAC,OAAO;gBAAE,IAAI,CAAC,UAAU,EAAE,CAAC;YAChC,MAAM,IAAI,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACvE,IACE,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI;gBAC9B,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAC1D,CAAC;gBACD,OAAO;YACT,CAAC;YACD,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE;gBAAE,OAAO;YACjD,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,OAAO,EAAE,CAAC;gBACxC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBAC9B,OAAO;YACT,CAAC;YACD,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;gBACnC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CACtC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5C,QAAQ,EACR,SAAS,EACT,IAAI,CAAC,KAAK,CAAC,MAAM,CAClB,CAAC;YACJ,CAAC;QACH,CAAC,EACD,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CACpB,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,QAAgB,EAAE,KAAc;QACvD,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;YAC7B,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YAChD,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC,KAAK,IAAI,QAAQ,CAAC,CAAC;QACnE,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO;QAC/B,MAAM,IAAI,CAAC,GAAG,CACZ,YAAY,EACZ,oBAAoB,EACpB,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAC1B,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CACrB,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,cAAc;QAC1B,MAAM,IAAI,CAAC,GAAG,CACZ,gBAAgB,EAChB,SAAS,EACT,KAAK,IAAI,EAAE;YACT,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY;gBAAE,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YAClF,KAAK,MAAM,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;gBACzE,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;gBACxC,CAAC;gBAAC,MAAM,CAAC;oBACP,uCAAuC;gBACzC,CAAC;YACH,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,eAAe,GAAG,EAAE,CAAC;YAChC,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;gBACnC,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBACtD,CAAC;gBAAC,MAAM,CAAC;oBACP,6CAA6C;gBAC/C,CAAC;YACH,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC;YAC7B,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC;YACvB,IAAI,CAAC,KAAK,CAAC,iBAAiB,GAAG,KAAK,CAAC;YACrC,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC;YAC/B,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC;YAChC,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC;YAC9B,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QAC5B,CAAC,EACD,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CACX,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,qBAAqB,CACjC,IAAY,EACZ,OAAsC;QAEtC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,MAAM,GAAG,GAA2B,EAAE,CAAC;QACvC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,MAAM,GAAG,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;YACjE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACtE,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,OAAO,EAAE,KAAK,QAAQ;gBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;CACF;AAED,MAAM,UAAU,yBAAyB,CAAC,QAAqC;IAG7E,OAAO,EAAE,SAAS,EAAE,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAC,SAAS,EAAE,CAAC;AACpE,CAAC","sourcesContent":["import type {\n ChatToolResult,\n ConversationResponder,\n SubagentProgressSnapshot,\n} from \"../adapter.js\";\nimport * as log from \"../log.js\";\nimport {\n createChatResponseErrorReporter,\n formatToolArgs,\n splitText,\n type ChatResponseErrorOperation,\n} from \"./shared.js\";\nimport type { ProgressiveRendererPlatform } from \"./types.js\";\n\nexport function formatMarkdownToolResult(result: ChatToolResult): string {\n const argsFormatted = formatToolArgs(result.args);\n const duration = (result.durationMs / 1000).toFixed(1);\n let text = `**${result.isError ? \"Error\" : \"Done\"} ${result.toolName}**`;\n if (result.label) text += `: ${result.label}`;\n text += ` (${duration}s)\\n`;\n if (argsFormatted) text += `\\`\\`\\`\\n${argsFormatted}\\n\\`\\`\\`\\n`;\n text += `**Result:**\\n\\`\\`\\`\\n${result.result}\\n\\`\\`\\``;\n return text;\n}\n\ninterface RendererState {\n responseId: string | null;\n source: string;\n working: boolean;\n streamActive: boolean;\n streamUnavailable: boolean;\n streamedSource: string;\n pendingChars: number;\n lastFlushAt: number;\n resetDelta: boolean;\n typingInterval: ReturnType<typeof setInterval> | null;\n typingFailureWarned: boolean;\n extraIds: Array<string | number>;\n /**\n * Messages holding the overflow of a response too long for one message,\n * in order. Reused across redraws — see `postSplit`.\n */\n continuationIds: Array<string | number>;\n}\n\n/**\n * Floor on how often a streaming response redraws.\n *\n * Every platform meters edits per channel — Slack's is the tightest at roughly\n * fifty a minute — and a redraw sends the whole message, so the cost is the\n * number of calls, not their size. One second keeps a long answer inside that\n * budget while still reading as live.\n *\n * This is a floor, not a target: the interval is measured from when the last\n * redraw *finished*, so a platform that slows down under load slows the redraw\n * rate with it instead of queueing work it cannot deliver.\n */\nconst DEFAULT_FLUSH_INTERVAL_MS = 1000;\n\nclass ProgressiveRenderer {\n readonly responder: ConversationResponder;\n private readonly state: RendererState;\n private readonly sanitize: (text: string) => string;\n private readonly reportResponseError;\n private readonly now = Date.now;\n private readonly flushIntervalMs: number;\n private queueTail = Promise.resolve();\n\n constructor(private readonly platform: ProgressiveRendererPlatform) {\n this.state = {\n responseId: platform.initialResponseId ?? null,\n source: \"\",\n working: true,\n streamActive: false,\n streamUnavailable: false,\n streamedSource: \"\",\n pendingChars: 0,\n lastFlushAt: 0,\n resetDelta: false,\n typingInterval: null,\n typingFailureWarned: false,\n extraIds: [],\n continuationIds: [],\n };\n this.sanitize = platform.sanitize ?? ((text: string) => text);\n this.reportResponseError = platform.responseErrorContext\n ? createChatResponseErrorReporter(() => platform.responseErrorContext!(this.state.responseId))\n : undefined;\n this.flushIntervalMs = platform.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;\n this.responder = this.createResponder();\n }\n\n private createResponder(): ConversationResponder {\n return {\n respond: (text) => this.respond(text),\n appendResponseDelta:\n this.platform.supportsDeltas || this.platform.stream\n ? (delta) => this.appendDelta(delta)\n : undefined,\n finishResponse:\n this.platform.supportsDeltas || this.platform.stream\n ? (finalText) => this.finishResponse(finalText)\n : undefined,\n replaceResponse: (text, options) => this.replaceResponse(text, options),\n replaceSubagentProgress: this.platform.formatSubagentProgress\n ? (progress, finalText) => this.replaceSubagentProgress(progress, finalText)\n : undefined,\n respondDiagnostic: (text, options) => this.respondDiagnostic(text, options),\n respondToolResult: (result) => this.respondToolResult(result),\n setTyping: (isTyping) => this.setTyping(isTyping),\n setWorking: (working) => this.setWorking(working),\n uploadFile: (filePath, title) => this.uploadFile(filePath, title),\n ...(this.platform.react ? { react: this.platform.react } : {}),\n deleteResponse: () => this.deleteResponse(),\n };\n }\n\n private stopTyping(): void {\n if (this.state.typingInterval !== null) {\n clearInterval(this.state.typingInterval);\n this.state.typingInterval = null;\n }\n }\n\n private provisional(text: string, working: boolean): string {\n if (this.platform.formatProvisional) return this.platform.formatProvisional(text, working);\n return working && this.platform.workingIndicator ? text + this.platform.workingIndicator : text;\n }\n\n private split(text: string): string[] {\n return splitText(text, this.platform.maxLength, this.platform.formatContinuation);\n }\n\n private async postOrUpdate(text: string): Promise<void> {\n if (this.state.responseId !== null) {\n await this.platform.update(this.state.responseId, text);\n return;\n }\n if (this.platform.typing?.stopOnSend) this.stopTyping();\n this.state.responseId = await this.platform.post(text);\n }\n\n private async postSplit(text: string): Promise<void> {\n const [head = text, ...tail] = this.split(text);\n await this.postOrUpdate(head);\n for (const [index, part] of tail.entries()) {\n const existing = this.state.continuationIds[index];\n if (existing !== undefined) {\n await this.platform.update(String(existing), part);\n continue;\n }\n if (this.platform.typing?.stopOnSend) this.stopTyping();\n const id = await this.platform.postExtra(part, this.state.responseId);\n if (id !== undefined && id !== null) this.state.continuationIds[index] = id;\n }\n }\n\n private async postExtra(text: string): Promise<void> {\n if (this.platform.typing?.stopOnSend) this.stopTyping();\n await this.platform.postExtra(text, this.state.responseId);\n }\n\n private async stopNativeStream(): Promise<void> {\n if (!this.state.streamActive || this.state.responseId === null || !this.platform.stream) return;\n const streamId = this.state.responseId;\n this.state.streamActive = false;\n this.state.streamedSource = \"\";\n await this.platform.stream.stop(streamId);\n }\n\n private async abandonNativeStream(): Promise<void> {\n if (!this.platform.stream || this.state.responseId === null) return;\n const streamId = this.state.responseId;\n this.state.streamActive = false;\n this.state.streamedSource = \"\";\n await this.platform.stream.stop(streamId).catch(() => undefined);\n if (this.state.responseId === streamId) this.state.responseId = null;\n }\n\n private async renderRaw(\n text: string,\n operation: \"render\" | \"replace\",\n options?: { createOverflowLink?: () => string },\n canonicalText = text,\n ): Promise<string> {\n try {\n await this.postSplit(text);\n return canonicalText;\n } catch (err) {\n if (!this.platform.handleTooLong) throw err;\n if (this.platform.isTooLongError && !this.platform.isTooLongError(err)) throw err;\n const fallback = await this.platform.handleTooLong({\n text: canonicalText,\n operation,\n options,\n responseId: this.state.responseId,\n write: (fallbackText) => this.postSplit(fallbackText),\n getResponseId: () => this.state.responseId,\n });\n return fallback.text;\n }\n }\n\n private async renderDelta(text: string): Promise<string> {\n if (this.state.working && !text.trim()) return text;\n const prepared = this.platform.prepareSource?.(text, this.state.working) ?? text;\n const stream = this.platform.stream;\n const display = this.provisional(prepared, this.state.working);\n if (!stream || this.state.streamUnavailable) {\n await this.renderRaw(display, \"render\", undefined, prepared);\n return prepared;\n }\n if (this.state.responseId !== null && !this.state.streamActive) {\n await this.renderRaw(display, \"render\", undefined, prepared);\n return prepared;\n }\n if (\n this.state.responseId !== null &&\n this.state.streamActive &&\n !prepared.startsWith(this.state.streamedSource)\n ) {\n await this.abandonNativeStream();\n await this.renderRaw(display, \"render\", undefined, prepared);\n return prepared;\n }\n\n try {\n if (this.state.responseId !== null) {\n const delta = prepared.slice(this.state.streamedSource.length);\n if (delta && delta.length >= (stream.minDeltaChars ?? 0)) {\n await stream.append(this.state.responseId, delta);\n this.state.streamedSource = prepared;\n }\n return prepared;\n }\n this.state.responseId = await stream.start(prepared);\n this.state.streamActive = true;\n this.state.streamedSource = prepared;\n return prepared;\n } catch (err) {\n this.state.streamUnavailable = true;\n log.logWarning(\n \"Native response streaming unavailable; falling back to message updates\",\n err instanceof Error ? err.message : String(err),\n );\n await this.abandonNativeStream();\n await this.renderRaw(display, \"render\", undefined, prepared);\n return prepared;\n }\n }\n\n private async renderFinal(text: string): Promise<string> {\n const stream = this.platform.stream;\n if (stream && this.state.streamActive && this.state.responseId !== null) {\n let streamed = false;\n try {\n if (text.startsWith(this.state.streamedSource)) {\n const delta = text.slice(this.state.streamedSource.length);\n if (delta) await stream.append(this.state.responseId, delta);\n await stream.stop(this.state.responseId);\n streamed = true;\n }\n } catch (err) {\n this.state.streamUnavailable = true;\n log.logWarning(\n \"Native response streaming unavailable; falling back to message updates\",\n err instanceof Error ? err.message : String(err),\n );\n }\n this.state.streamActive = false;\n this.state.streamedSource = \"\";\n if (streamed) {\n if (this.platform.needsCanonicalRender?.(text)) await this.renderRaw(text, \"render\");\n return text;\n }\n await this.abandonNativeStream();\n }\n if (this.state.responseId !== null || text) return this.renderRaw(text, \"render\");\n return text;\n }\n\n private async run(\n label: string,\n operation: ChatResponseErrorOperation,\n work: () => Promise<void>,\n extra: () => Record<string, unknown>,\n ): Promise<void> {\n const operationPromise = this.queueTail.then(work);\n const handled = operationPromise.catch(async (err) => {\n const message = err instanceof Error ? err.message : String(err);\n log.logWarning(`${this.platform.label} ${label} error`, message);\n this.reportResponseError?.(err, operation, extra());\n if (this.platform.notifySendFailure) {\n try {\n await this.platform.notifySendFailure(message);\n } catch {\n // A secondary notification must not poison the response queue.\n }\n }\n });\n this.queueTail = handled.catch(() => undefined);\n return handled;\n }\n\n private async appendDelta(delta: string): Promise<void> {\n await this.run(\n \"appendResponseDelta\",\n \"respond\",\n async () => {\n if (!delta) return;\n if (this.state.resetDelta) {\n this.state.source = \"\";\n this.state.pendingChars = 0;\n this.state.resetDelta = false;\n }\n const sanitized = this.sanitize(delta);\n this.state.source += sanitized;\n this.state.pendingChars += sanitized.length;\n const elapsed = this.now() - this.state.lastFlushAt;\n if (\n this.state.lastFlushAt === 0 ||\n (elapsed >= this.flushIntervalMs && this.state.pendingChars > 0)\n ) {\n this.state.pendingChars = 0;\n try {\n this.state.source = await this.renderDelta(this.state.source);\n } finally {\n // A rejected edit still spent an API call. Pace subsequent deltas\n // from its completion too, retaining source for the next attempt.\n this.state.lastFlushAt = this.now();\n }\n }\n },\n () => ({ textLength: delta.length, accumulatedLength: this.state.source.length }),\n );\n }\n\n private async respond(text: string): Promise<void> {\n await this.run(\n \"respond\",\n \"respond\",\n async () => {\n const sanitized = this.sanitize(text);\n this.state.source = this.state.source ? `${this.state.source}\\n${sanitized}` : sanitized;\n this.state.pendingChars = 0;\n this.state.source = await this.renderDelta(this.state.source);\n if (this.state.responseId !== null && this.platform.logIntermediateResponses) {\n this.platform.logBotResponse?.(text, this.state.responseId);\n }\n },\n () => ({\n phase: this.state.responseId ? \"update\" : \"initial_post\",\n textLength: text.length,\n accumulatedLength: this.state.source.length,\n }),\n );\n }\n\n private async finishResponse(finalText?: string): Promise<void> {\n await this.run(\n \"finishResponse\",\n \"set_working\",\n async () => {\n if (finalText !== undefined) this.state.source = this.sanitize(finalText);\n this.state.resetDelta = false;\n this.state.pendingChars = 0;\n this.stopTyping();\n this.state.working = false;\n this.state.source = await this.renderFinal(this.state.source);\n if (this.state.responseId !== null) {\n this.platform.logBotResponse?.(this.state.source, this.state.responseId);\n }\n await this.platform.onFinish?.(this.state.source, this.state.responseId);\n },\n () => ({ finalTextLength: finalText?.length }),\n );\n }\n\n private async replaceResponse(\n text: string,\n options?: { createOverflowLink?: () => string },\n ): Promise<void> {\n await this.run(\n \"replaceResponse\",\n \"replace_response\",\n async () => {\n this.state.source = this.sanitize(text);\n this.state.pendingChars = 0;\n this.state.resetDelta = true;\n if (this.state.streamActive) await this.stopNativeStream();\n if (this.state.working && !this.state.source.trim()) return;\n const prepared =\n this.platform.prepareSource?.(this.state.source, this.state.working) ?? this.state.source;\n this.state.source = await this.renderRaw(\n this.provisional(prepared, this.state.working),\n \"replace\",\n options,\n prepared,\n );\n },\n () => ({ textLength: text.length, hadExistingResponse: Boolean(this.state.responseId) }),\n );\n }\n\n private async replaceSubagentProgress(\n progress: SubagentProgressSnapshot,\n finalText?: string,\n ): Promise<void> {\n const dashboard = this.platform.formatSubagentProgress!(progress);\n await this.responder.replaceResponse(finalText ? `${dashboard}\\n\\n${finalText}` : dashboard);\n }\n\n private async respondDiagnostic(\n text: string,\n options: { style?: \"muted\" | \"error\" } = {},\n ): Promise<void> {\n await this.run(\n \"respondDiagnostic\",\n \"respond_diagnostic\",\n async () => {\n const ids = this.platform.postDiagnostic\n ? await this.platform.postDiagnostic(text, options, this.state.responseId)\n : await this.postDefaultDiagnostic(text, options);\n this.state.extraIds.push(...ids);\n },\n () => ({ textLength: text.length, style: options.style }),\n );\n }\n\n private async respondToolResult(result: ChatToolResult): Promise<void> {\n await this.responder.respondDiagnostic(this.platform.formatToolResult(result));\n }\n\n private async setTyping(isTyping: boolean): Promise<void> {\n await this.run(\n \"setTyping\",\n \"set_working\",\n async () => {\n if (this.platform.setTyping) {\n await this.platform.setTyping(isTyping, this.state.responseId);\n return;\n }\n const typing = this.platform.typing;\n if (!typing) return;\n const onTypingError = (err: unknown): void => {\n if (this.state.typingFailureWarned) return;\n this.state.typingFailureWarned = true;\n log.logWarning(\n `${this.platform.label} sendTyping failed (further occurrences suppressed for this session)`,\n err instanceof Error ? err.message : String(err),\n );\n };\n if (isTyping && this.state.typingInterval === null) {\n typing.send().catch(onTypingError);\n this.state.typingInterval = setInterval(() => {\n typing.send().catch(onTypingError);\n }, typing.intervalMs);\n } else if (!isTyping) {\n this.stopTyping();\n }\n },\n () => ({ working: isTyping }),\n );\n }\n\n private async setWorking(working: boolean): Promise<void> {\n await this.run(\n \"setWorking\",\n \"set_working\",\n async () => {\n this.state.working = working;\n if (!working) this.stopTyping();\n await this.platform.onWorkingChanged?.(working, this.state.responseId);\n if (\n this.state.responseId === null ||\n (!this.platform.workingIndicator && !this.platform.stream)\n ) {\n return;\n }\n if (working && !this.state.source.trim()) return;\n if (this.state.streamActive && !working) {\n await this.stopNativeStream();\n return;\n }\n if (this.state.responseId !== null) {\n this.state.source = await this.renderRaw(\n this.provisional(this.state.source, working),\n \"render\",\n undefined,\n this.state.source,\n );\n }\n },\n () => ({ working }),\n );\n }\n\n private async uploadFile(filePath: string, title?: string): Promise<void> {\n if (this.platform.uploadFile) {\n await this.platform.uploadFile(filePath, title);\n return;\n }\n const note = this.platform.uploadFallbackNote?.(title ?? filePath);\n if (note === undefined) return;\n await this.run(\n \"uploadFile\",\n \"respond_diagnostic\",\n () => this.postExtra(note),\n () => ({ filePath }),\n );\n }\n\n private async deleteResponse(): Promise<void> {\n await this.run(\n \"deleteResponse\",\n \"respond\",\n async () => {\n this.stopTyping();\n if (this.state.streamActive) await this.stopNativeStream().catch(() => undefined);\n for (const id of [...this.state.extraIds, ...this.state.continuationIds]) {\n try {\n await this.platform.deleteExtra?.(id);\n } catch {\n // Deleting diagnostics is best effort.\n }\n }\n this.state.extraIds = [];\n this.state.continuationIds = [];\n if (this.state.responseId !== null) {\n try {\n await this.platform.delete?.(this.state.responseId);\n } catch {\n // Deleting the main response is best effort.\n }\n }\n this.state.responseId = null;\n this.state.source = \"\";\n this.state.streamUnavailable = false;\n this.state.streamedSource = \"\";\n this.state.streamActive = false;\n this.state.resetDelta = false;\n this.state.working = true;\n },\n () => ({}),\n );\n }\n\n private async postDefaultDiagnostic(\n text: string,\n options: { style?: \"muted\" | \"error\" },\n ): Promise<Array<string | number>> {\n const prefix = options.style === \"error\" ? this.platform.errorPrefix : \"\";\n const ids: Array<string | number> = [];\n for (const part of this.split(this.sanitize(`${prefix}${text}`))) {\n const id = await this.platform.postExtra(part, this.state.responseId);\n if (typeof id === \"string\" || typeof id === \"number\") ids.push(id);\n }\n return ids;\n }\n}\n\nexport function createProgressiveRenderer(platform: ProgressiveRendererPlatform): {\n responder: ConversationResponder;\n} {\n return { responder: new ProgressiveRenderer(platform).responder };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"progressive-renderer.js","sourceRoot":"","sources":["../../src/adapters/progressive-renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n ChatToolResult,\n ConversationResponder,\n SubagentProgressSnapshot,\n} from \"../adapter.js\";\nimport * as log from \"../log.js\";\nimport {\n createChatResponseErrorReporter,\n formatToolArgs,\n splitText,\n type ChatResponseErrorOperation,\n} from \"./shared.js\";\nimport type { ProgressiveRendererPlatform } from \"./types.js\";\n\nexport function formatMarkdownToolResult(result: ChatToolResult): string {\n const argsFormatted = formatToolArgs(result.args);\n const duration = (result.durationMs / 1000).toFixed(1);\n let text = `**${result.isError ? \"Error\" : \"Done\"} ${result.toolName}**`;\n if (result.label) text += `: ${result.label}`;\n text += ` (${duration}s)\\n`;\n if (argsFormatted) text += `\\`\\`\\`\\n${argsFormatted}\\n\\`\\`\\`\\n`;\n text += `**Result:**\\n\\`\\`\\`\\n${result.result}\\n\\`\\`\\``;\n return text;\n}\n\ninterface RendererState {\n responseId: string | null;\n source: string;\n working: boolean;\n streamActive: boolean;\n streamUnavailable: boolean;\n streamedSource: string;\n pendingChars: number;\n lastFlushAt: number;\n resetDelta: boolean;\n typingInterval: ReturnType<typeof setInterval> | null;\n typingFailureWarned: boolean;\n extraIds: Array<string | number>;\n /**\n * Messages holding the overflow of a response too long for one message,\n * in order. Reused across redraws — see `postSplit`.\n */\n continuationIds: Array<string | number>;\n}\n\n/**\n * Floor on how often a streaming response redraws.\n *\n * Every platform meters edits per channel — Slack's is the tightest at roughly\n * fifty a minute — and a redraw sends the whole message, so the cost is the\n * number of calls, not their size. One second keeps a long answer inside that\n * budget while still reading as live.\n *\n * This is a floor, not a target: the interval is measured from when the last\n * redraw *finished*, so a platform that slows down under load slows the redraw\n * rate with it instead of queueing work it cannot deliver.\n */\nconst DEFAULT_FLUSH_INTERVAL_MS = 1000;\n\nclass ProgressiveRenderer {\n readonly responder: ConversationResponder;\n private readonly state: RendererState;\n private readonly sanitize: (text: string) => string;\n private readonly reportResponseError;\n private readonly now = Date.now;\n private readonly flushIntervalMs: number;\n private queueTail = Promise.resolve();\n\n constructor(private readonly platform: ProgressiveRendererPlatform) {\n this.state = {\n responseId: platform.initialResponseId ?? null,\n source: \"\",\n working: true,\n streamActive: false,\n streamUnavailable: false,\n streamedSource: \"\",\n pendingChars: 0,\n lastFlushAt: 0,\n resetDelta: false,\n typingInterval: null,\n typingFailureWarned: false,\n extraIds: [],\n continuationIds: [],\n };\n this.sanitize = platform.sanitize ?? ((text: string) => text);\n this.reportResponseError = platform.responseErrorContext\n ? createChatResponseErrorReporter(() => platform.responseErrorContext!(this.state.responseId))\n : undefined;\n this.flushIntervalMs = platform.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;\n this.responder = this.createResponder();\n }\n\n private createResponder(): ConversationResponder {\n return {\n respond: (text) => this.respond(text),\n appendResponseDelta:\n this.platform.supportsDeltas || this.platform.stream\n ? (delta) => this.appendDelta(delta)\n : undefined,\n finishResponse:\n this.platform.supportsDeltas || this.platform.stream\n ? (finalText) => this.finishResponse(finalText)\n : undefined,\n replaceResponse: (text, options) => this.replaceResponse(text, options),\n replaceSubagentProgress: this.platform.formatSubagentProgress\n ? (progress, finalText) => this.replaceSubagentProgress(progress, finalText)\n : undefined,\n respondDiagnostic: (text, options) => this.respondDiagnostic(text, options),\n respondToolResult: (result) => this.respondToolResult(result),\n setTyping: (isTyping) => this.setTyping(isTyping),\n setWorking: (working) => this.setWorking(working),\n uploadFile: (filePath, title) => this.uploadFile(filePath, title),\n ...(this.platform.react ? { react: this.platform.react } : {}),\n deleteResponse: () => this.deleteResponse(),\n };\n }\n\n private stopTyping(): void {\n if (this.state.typingInterval !== null) {\n clearInterval(this.state.typingInterval);\n this.state.typingInterval = null;\n }\n }\n\n private provisional(text: string, working: boolean): string {\n if (this.platform.formatProvisional) return this.platform.formatProvisional(text, working);\n return working && this.platform.workingIndicator ? text + this.platform.workingIndicator : text;\n }\n\n private split(text: string): string[] {\n return splitText(text, this.platform.maxLength, this.platform.formatContinuation);\n }\n\n private async postOrUpdate(text: string): Promise<void> {\n if (this.state.responseId !== null) {\n await this.platform.update(this.state.responseId, text);\n return;\n }\n if (this.platform.typing?.stopOnSend) this.stopTyping();\n this.state.responseId = await this.platform.post(text);\n }\n\n private async postSplit(text: string): Promise<void> {\n const [head = text, ...tail] = this.split(text);\n await this.postOrUpdate(head);\n for (const [index, part] of tail.entries()) {\n const existing = this.state.continuationIds[index];\n if (existing !== undefined) {\n await this.platform.update(String(existing), part);\n continue;\n }\n if (this.platform.typing?.stopOnSend) this.stopTyping();\n const id = await this.platform.postExtra(part, this.state.responseId);\n if (id !== undefined && id !== null) this.state.continuationIds[index] = id;\n }\n }\n\n private async postExtra(text: string): Promise<void> {\n if (this.platform.typing?.stopOnSend) this.stopTyping();\n await this.platform.postExtra(text, this.state.responseId);\n }\n\n private async stopNativeStream(): Promise<void> {\n if (!this.state.streamActive || this.state.responseId === null || !this.platform.stream) return;\n const streamId = this.state.responseId;\n this.state.streamActive = false;\n this.state.streamedSource = \"\";\n await this.platform.stream.stop(streamId);\n }\n\n private async abandonNativeStream(): Promise<void> {\n if (!this.platform.stream || this.state.responseId === null) return;\n const streamId = this.state.responseId;\n this.state.streamActive = false;\n this.state.streamedSource = \"\";\n await this.platform.stream.stop(streamId).catch(() => undefined);\n if (this.state.responseId === streamId) this.state.responseId = null;\n }\n\n private async renderRaw(\n text: string,\n operation: \"render\" | \"replace\",\n options?: { createOverflowLink?: () => string },\n canonicalText = text,\n ): Promise<string> {\n try {\n await this.postSplit(text);\n return canonicalText;\n } catch (err) {\n if (!this.platform.handleTooLong) throw err;\n if (this.platform.isTooLongError && !this.platform.isTooLongError(err)) throw err;\n const fallback = await this.platform.handleTooLong({\n text: canonicalText,\n operation,\n options,\n responseId: this.state.responseId,\n write: (fallbackText) => this.postSplit(fallbackText),\n getResponseId: () => this.state.responseId,\n });\n return fallback.text;\n }\n }\n\n private async renderDelta(text: string): Promise<string> {\n if (this.state.working && !text.trim()) return text;\n const prepared = this.platform.prepareSource?.(text, this.state.working) ?? text;\n const stream = this.platform.stream;\n const display = this.provisional(prepared, this.state.working);\n if (!stream || this.state.streamUnavailable) {\n await this.renderRaw(display, \"render\", undefined, prepared);\n return prepared;\n }\n if (this.state.responseId !== null && !this.state.streamActive) {\n await this.renderRaw(display, \"render\", undefined, prepared);\n return prepared;\n }\n if (\n this.state.responseId !== null &&\n this.state.streamActive &&\n !prepared.startsWith(this.state.streamedSource)\n ) {\n await this.abandonNativeStream();\n await this.renderRaw(display, \"render\", undefined, prepared);\n return prepared;\n }\n\n try {\n if (this.state.responseId !== null) {\n const delta = prepared.slice(this.state.streamedSource.length);\n if (delta && delta.length >= (stream.minDeltaChars ?? 0)) {\n await stream.append(this.state.responseId, delta);\n this.state.streamedSource = prepared;\n }\n return prepared;\n }\n this.state.responseId = await stream.start(prepared);\n this.state.streamActive = true;\n this.state.streamedSource = prepared;\n return prepared;\n } catch (err) {\n this.state.streamUnavailable = true;\n log.logWarning(\n \"Native response streaming unavailable; falling back to message updates\",\n err instanceof Error ? err.message : String(err),\n );\n await this.abandonNativeStream();\n await this.renderRaw(display, \"render\", undefined, prepared);\n return prepared;\n }\n }\n\n private async renderFinal(text: string): Promise<string> {\n const stream = this.platform.stream;\n if (stream && this.state.streamActive && this.state.responseId !== null) {\n let streamed = false;\n try {\n if (text.startsWith(this.state.streamedSource)) {\n const delta = text.slice(this.state.streamedSource.length);\n if (delta) await stream.append(this.state.responseId, delta);\n await stream.stop(this.state.responseId);\n streamed = true;\n }\n } catch (err) {\n this.state.streamUnavailable = true;\n log.logWarning(\n \"Native response streaming unavailable; falling back to message updates\",\n err instanceof Error ? err.message : String(err),\n );\n }\n this.state.streamActive = false;\n this.state.streamedSource = \"\";\n if (streamed) {\n if (this.platform.needsCanonicalRender?.(text)) await this.renderRaw(text, \"render\");\n return text;\n }\n await this.abandonNativeStream();\n }\n if (this.state.responseId !== null || text) return this.renderRaw(text, \"render\");\n return text;\n }\n\n private async run(\n label: string,\n operation: ChatResponseErrorOperation,\n work: () => Promise<void>,\n extra: () => Record<string, unknown>,\n ): Promise<void> {\n const operationPromise = this.queueTail.then(work);\n const handled = operationPromise.catch(async (err) => {\n const message = err instanceof Error ? err.message : String(err);\n log.logWarning(`${this.platform.label} ${label} error`, message);\n this.reportResponseError?.(err, operation, extra());\n if (this.platform.notifySendFailure) {\n try {\n await this.platform.notifySendFailure(message);\n } catch {\n // A secondary notification must not poison the response queue.\n }\n }\n // Incremental/status updates are best effort. Replacements and finalization\n // are delivery boundaries: callers must not mistake a rejected send for success.\n if (label === \"replaceResponse\" || label === \"finishResponse\") throw err;\n });\n this.queueTail = handled.catch(() => undefined);\n return handled;\n }\n\n private async appendDelta(delta: string): Promise<void> {\n await this.run(\n \"appendResponseDelta\",\n \"respond\",\n async () => {\n if (!delta) return;\n if (this.state.resetDelta) {\n this.state.source = \"\";\n this.state.pendingChars = 0;\n this.state.resetDelta = false;\n }\n const sanitized = this.sanitize(delta);\n this.state.source += sanitized;\n this.state.pendingChars += sanitized.length;\n const elapsed = this.now() - this.state.lastFlushAt;\n if (\n this.state.lastFlushAt === 0 ||\n (elapsed >= this.flushIntervalMs && this.state.pendingChars > 0)\n ) {\n this.state.pendingChars = 0;\n try {\n this.state.source = await this.renderDelta(this.state.source);\n } finally {\n // A rejected edit still spent an API call. Pace subsequent deltas\n // from its completion too, retaining source for the next attempt.\n this.state.lastFlushAt = this.now();\n }\n }\n },\n () => ({ textLength: delta.length, accumulatedLength: this.state.source.length }),\n );\n }\n\n private async respond(text: string): Promise<void> {\n await this.run(\n \"respond\",\n \"respond\",\n async () => {\n const sanitized = this.sanitize(text);\n this.state.source = this.state.source ? `${this.state.source}\\n${sanitized}` : sanitized;\n this.state.pendingChars = 0;\n this.state.source = await this.renderDelta(this.state.source);\n if (this.state.responseId !== null && this.platform.logIntermediateResponses) {\n this.platform.logBotResponse?.(text, this.state.responseId);\n }\n },\n () => ({\n phase: this.state.responseId ? \"update\" : \"initial_post\",\n textLength: text.length,\n accumulatedLength: this.state.source.length,\n }),\n );\n }\n\n private async finishResponse(finalText?: string): Promise<void> {\n await this.run(\n \"finishResponse\",\n \"set_working\",\n async () => {\n if (finalText !== undefined) this.state.source = this.sanitize(finalText);\n this.state.resetDelta = false;\n this.state.pendingChars = 0;\n this.stopTyping();\n this.state.working = false;\n this.state.source = await this.renderFinal(this.state.source);\n if (this.state.responseId !== null) {\n this.platform.logBotResponse?.(this.state.source, this.state.responseId);\n }\n await this.platform.onFinish?.(this.state.source, this.state.responseId);\n },\n () => ({ finalTextLength: finalText?.length }),\n );\n }\n\n private async replaceResponse(\n text: string,\n options?: { createOverflowLink?: () => string },\n ): Promise<void> {\n await this.run(\n \"replaceResponse\",\n \"replace_response\",\n async () => {\n this.state.source = this.sanitize(text);\n this.state.pendingChars = 0;\n this.state.resetDelta = true;\n if (this.state.streamActive) await this.stopNativeStream();\n if (this.state.working && !this.state.source.trim()) return;\n const prepared =\n this.platform.prepareSource?.(this.state.source, this.state.working) ?? this.state.source;\n this.state.source = await this.renderRaw(\n this.provisional(prepared, this.state.working),\n \"replace\",\n options,\n prepared,\n );\n },\n () => ({ textLength: text.length, hadExistingResponse: Boolean(this.state.responseId) }),\n );\n }\n\n private async replaceSubagentProgress(\n progress: SubagentProgressSnapshot,\n finalText?: string,\n ): Promise<void> {\n const dashboard = this.platform.formatSubagentProgress!(progress);\n await this.responder.replaceResponse(finalText ? `${dashboard}\\n\\n${finalText}` : dashboard);\n }\n\n private async respondDiagnostic(\n text: string,\n options: { style?: \"muted\" | \"error\" } = {},\n ): Promise<void> {\n await this.run(\n \"respondDiagnostic\",\n \"respond_diagnostic\",\n async () => {\n const ids = this.platform.postDiagnostic\n ? await this.platform.postDiagnostic(text, options, this.state.responseId)\n : await this.postDefaultDiagnostic(text, options);\n this.state.extraIds.push(...ids);\n },\n () => ({ textLength: text.length, style: options.style }),\n );\n }\n\n private async respondToolResult(result: ChatToolResult): Promise<void> {\n await this.responder.respondDiagnostic(this.platform.formatToolResult(result));\n }\n\n private async setTyping(isTyping: boolean): Promise<void> {\n await this.run(\n \"setTyping\",\n \"set_working\",\n async () => {\n if (this.platform.setTyping) {\n await this.platform.setTyping(isTyping, this.state.responseId);\n return;\n }\n const typing = this.platform.typing;\n if (!typing) return;\n const onTypingError = (err: unknown): void => {\n if (this.state.typingFailureWarned) return;\n this.state.typingFailureWarned = true;\n log.logWarning(\n `${this.platform.label} sendTyping failed (further occurrences suppressed for this session)`,\n err instanceof Error ? err.message : String(err),\n );\n };\n if (isTyping && this.state.typingInterval === null) {\n typing.send().catch(onTypingError);\n this.state.typingInterval = setInterval(() => {\n typing.send().catch(onTypingError);\n }, typing.intervalMs);\n } else if (!isTyping) {\n this.stopTyping();\n }\n },\n () => ({ working: isTyping }),\n );\n }\n\n private async setWorking(working: boolean): Promise<void> {\n await this.run(\n \"setWorking\",\n \"set_working\",\n async () => {\n this.state.working = working;\n if (!working) this.stopTyping();\n await this.platform.onWorkingChanged?.(working, this.state.responseId);\n if (\n this.state.responseId === null ||\n (!this.platform.workingIndicator && !this.platform.stream)\n ) {\n return;\n }\n if (working && !this.state.source.trim()) return;\n if (this.state.streamActive && !working) {\n await this.stopNativeStream();\n return;\n }\n if (this.state.responseId !== null) {\n this.state.source = await this.renderRaw(\n this.provisional(this.state.source, working),\n \"render\",\n undefined,\n this.state.source,\n );\n }\n },\n () => ({ working }),\n );\n }\n\n private async uploadFile(filePath: string, title?: string): Promise<void> {\n if (this.platform.uploadFile) {\n await this.platform.uploadFile(filePath, title);\n return;\n }\n const note = this.platform.uploadFallbackNote?.(title ?? filePath);\n if (note === undefined) return;\n await this.run(\n \"uploadFile\",\n \"respond_diagnostic\",\n () => this.postExtra(note),\n () => ({ filePath }),\n );\n }\n\n private async deleteResponse(): Promise<void> {\n await this.run(\n \"deleteResponse\",\n \"respond\",\n async () => {\n this.stopTyping();\n if (this.state.streamActive) await this.stopNativeStream().catch(() => undefined);\n for (const id of [...this.state.extraIds, ...this.state.continuationIds]) {\n try {\n await this.platform.deleteExtra?.(id);\n } catch {\n // Deleting diagnostics is best effort.\n }\n }\n this.state.extraIds = [];\n this.state.continuationIds = [];\n if (this.state.responseId !== null) {\n try {\n await this.platform.delete?.(this.state.responseId);\n } catch {\n // Deleting the main response is best effort.\n }\n }\n this.state.responseId = null;\n this.state.source = \"\";\n this.state.streamUnavailable = false;\n this.state.streamedSource = \"\";\n this.state.streamActive = false;\n this.state.resetDelta = false;\n this.state.working = true;\n },\n () => ({}),\n );\n }\n\n private async postDefaultDiagnostic(\n text: string,\n options: { style?: \"muted\" | \"error\" },\n ): Promise<Array<string | number>> {\n const prefix = options.style === \"error\" ? this.platform.errorPrefix : \"\";\n const ids: Array<string | number> = [];\n for (const part of this.split(this.sanitize(`${prefix}${text}`))) {\n const id = await this.platform.postExtra(part, this.state.responseId);\n if (typeof id === \"string\" || typeof id === \"number\") ids.push(id);\n }\n return ids;\n }\n}\n\nexport function createProgressiveRenderer(platform: ProgressiveRendererPlatform): {\n responder: ConversationResponder;\n} {\n return { responder: new ProgressiveRenderer(platform).responder };\n}\n"]}
|
|
@@ -144,6 +144,7 @@ export declare class SlackMessagingBot implements MessagingBot {
|
|
|
144
144
|
enqueueEvent(event: ConversationEvent): boolean;
|
|
145
145
|
private getQueue;
|
|
146
146
|
private resolveQueueKey;
|
|
147
|
+
private isTaskThread;
|
|
147
148
|
private hasKnownThreadSession;
|
|
148
149
|
/**
|
|
149
150
|
* Slack's own conversation vocabulary for this channel, from the metadata
|
|
@@ -170,6 +171,7 @@ export declare class SlackMessagingBot implements MessagingBot {
|
|
|
170
171
|
private setupEventHandlers;
|
|
171
172
|
private handleAppMention;
|
|
172
173
|
private admitHumanMessage;
|
|
174
|
+
private deliverTaskUpdate;
|
|
173
175
|
private handleMessageEvent;
|
|
174
176
|
private handleSlashCommand;
|
|
175
177
|
private handleAppHomeOpened;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../../src/adapters/slack/bot.ts"],"names":[],"mappings":"AAMA,OAAO,EAGL,KAAK,YAAY,EAEjB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAI1B,KAAK,aAAa,EAElB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACtB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAG5E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D,OAAO,KAAK,EAGV,YAAY,EAEZ,SAAS,EACV,MAAM,YAAY,CAAC;AAapB,OAAO,EASL,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../../src/adapters/slack/bot.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,7 @@ import * as log from "../../log.js";
|
|
|
11
11
|
import { isRecord, readTextFileIfExists } from "../../file-guards.js";
|
|
12
12
|
import { PRODUCT_NAME, formatForceStopped } from "../../platform-messages.js";
|
|
13
13
|
import { appendBotResponseLog, appendChannelLog, MessagingEventQueue, MessagingIntakeTracker, saveIncomingAttachments, withRetry, } from "../shared.js";
|
|
14
|
-
import { processMessageIntake } from "../intake.js";
|
|
14
|
+
import { matchMagicWord, processMessageIntake } from "../intake.js";
|
|
15
15
|
import { recordPlatformChannelKind } from "../../office/projection.js";
|
|
16
16
|
import { AssistantThreadRegistry, handleAgentContextChanged, handleAgentDmOpened, handleAssistantThreadStarted, titleAssistantThread, } from "./assistant.js";
|
|
17
17
|
import { createSlackAdapters } from "./context.js";
|
|
@@ -21,6 +21,7 @@ import { isSlackThreadSessionKey, planSlackAdapterSession, planSlackEventAnchorR
|
|
|
21
21
|
import { reportUserFacingError } from "../../observability/index.js";
|
|
22
22
|
import { recordSlackUpdate } from "./update-diagnostics.js";
|
|
23
23
|
import { renderSlackBlocks, resolveSlackMentions } from "./blocks.js";
|
|
24
|
+
import { querySlackTasks, isTaskStatusQuestion, formatTaskStatus, readTaskRoots, } from "./task-status.js";
|
|
24
25
|
import { StreamStartLimiter } from "./stream-limits.js";
|
|
25
26
|
const SLACK_EVENT_ANCHOR_TEXT = "Working on it...";
|
|
26
27
|
function hasMessageContent(message, includeBlocks = true) {
|
|
@@ -130,9 +131,87 @@ export class SlackMessagingBot {
|
|
|
130
131
|
return (resolveConversationSettings(this.workspace.office(address)).slack?.replyMode ?? "top-level");
|
|
131
132
|
}
|
|
132
133
|
createContext(event) {
|
|
133
|
-
|
|
134
|
+
const context = createSlackAdapters(event, this, {
|
|
134
135
|
replyMode: this.resolveReplyMode(event.address),
|
|
135
136
|
});
|
|
137
|
+
if (event.conversationKind === "direct") {
|
|
138
|
+
context.responder.getTaskStatus = (key) => querySlackTasks(this.conversationDir(event.channel), event.channel, this.handler
|
|
139
|
+
.getRunningSessions()
|
|
140
|
+
.filter((s) => s.address.platform === "slack" && s.address.conversationId === event.channel), key);
|
|
141
|
+
}
|
|
142
|
+
if (event.conversationKind === "direct" &&
|
|
143
|
+
event.thread_ts &&
|
|
144
|
+
this.isTaskThread(event.channel, event.thread_ts)) {
|
|
145
|
+
let notified = false;
|
|
146
|
+
context.responder.notifyCompletion = async () => {
|
|
147
|
+
if (notified)
|
|
148
|
+
return;
|
|
149
|
+
const text = `<@${event.user}> 這一輪處理已結束,請查看上方結果。`;
|
|
150
|
+
const ts = await this.postInThread(event.channel, event.thread_ts, text);
|
|
151
|
+
notified = true;
|
|
152
|
+
this.logBotResponse(event.channel, text, ts, event.thread_ts);
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
if (event.conversationKind === "direct" && !event.thread_ts) {
|
|
156
|
+
context.responder.startTask = async (message, task) => {
|
|
157
|
+
if (this.stopped)
|
|
158
|
+
throw new Error("Slack is shutting down; task was not started.");
|
|
159
|
+
await context.responder.deleteResponse();
|
|
160
|
+
const root = await this.postMessage(event.channel, message);
|
|
161
|
+
this.logToFile(event.channel, {
|
|
162
|
+
date: new Date().toISOString(),
|
|
163
|
+
ts: root,
|
|
164
|
+
user: "bot",
|
|
165
|
+
text: message,
|
|
166
|
+
isMessagingBot: true,
|
|
167
|
+
taskRoot: true,
|
|
168
|
+
});
|
|
169
|
+
const sessionKey = resolveSlackSessionKey(event.channel, root);
|
|
170
|
+
try {
|
|
171
|
+
registerThreadSession({
|
|
172
|
+
conversationDir: this.conversationDir(event.channel),
|
|
173
|
+
sessionKey,
|
|
174
|
+
});
|
|
175
|
+
const child = {
|
|
176
|
+
...event,
|
|
177
|
+
ts: `task:${root}`,
|
|
178
|
+
thread_ts: root,
|
|
179
|
+
sessionKey,
|
|
180
|
+
text: task,
|
|
181
|
+
};
|
|
182
|
+
if (!this.getQueue(sessionKey).enqueue(async () => {
|
|
183
|
+
try {
|
|
184
|
+
await this.handler.handleEvent({
|
|
185
|
+
...child,
|
|
186
|
+
attachments: child.attachments?.map((a) => ({
|
|
187
|
+
name: a.original,
|
|
188
|
+
localPath: a.localPath,
|
|
189
|
+
})),
|
|
190
|
+
}, this, this.createContext(child));
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
reportUserFacingError(error, {
|
|
194
|
+
domain: "mikan",
|
|
195
|
+
surface: "task_handoff",
|
|
196
|
+
operation: "start_task_run",
|
|
197
|
+
severity: "error",
|
|
198
|
+
platform: "slack",
|
|
199
|
+
context: { conversationId: event.channel, sessionKey, threadTs: root },
|
|
200
|
+
});
|
|
201
|
+
await this.postInThread(event.channel, root, "Task could not start. Please reply here to try again.");
|
|
202
|
+
throw error;
|
|
203
|
+
}
|
|
204
|
+
}))
|
|
205
|
+
throw new Error("Task queue is closed.");
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
await this.updateMessage(event.channel, root, `${message}\n\nTask could not start.`);
|
|
209
|
+
throw error;
|
|
210
|
+
}
|
|
211
|
+
return sessionKey;
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
return context;
|
|
136
215
|
}
|
|
137
216
|
constructor(handler, config) {
|
|
138
217
|
this.statusUpdates = new Map();
|
|
@@ -710,6 +789,9 @@ export class SlackMessagingBot {
|
|
|
710
789
|
}
|
|
711
790
|
return this.hasKnownThreadSession(conversationId, sessionKey) ? sessionKey : conversationId;
|
|
712
791
|
}
|
|
792
|
+
isTaskThread(channel, root) {
|
|
793
|
+
return readTaskRoots(this.conversationDir(channel)).has(root);
|
|
794
|
+
}
|
|
713
795
|
hasKnownThreadSession(conversationId, sessionKey) {
|
|
714
796
|
return hasMaterializedChatSession({
|
|
715
797
|
conversationDir: this.conversationDir(conversationId),
|
|
@@ -1135,6 +1217,39 @@ export class SlackMessagingBot {
|
|
|
1135
1217
|
ack();
|
|
1136
1218
|
return false;
|
|
1137
1219
|
}
|
|
1220
|
+
async deliverTaskUpdate(event, attachmentsPromise) {
|
|
1221
|
+
if (matchMagicWord(event.text) === "stop" || event.text.startsWith("/"))
|
|
1222
|
+
return false;
|
|
1223
|
+
event.attachments = await attachmentsPromise;
|
|
1224
|
+
const context = this.createContext(event);
|
|
1225
|
+
const post = (text) => event.thread_ts
|
|
1226
|
+
? this.postInThread(event.channel, event.thread_ts, text)
|
|
1227
|
+
: this.postMessage(event.channel, text);
|
|
1228
|
+
try {
|
|
1229
|
+
if (!event.attachments?.length && isTaskStatusQuestion(event.text)) {
|
|
1230
|
+
const tasks = await context.responder.getTaskStatus(event.thread_ts ? event.sessionKey : undefined);
|
|
1231
|
+
if (!tasks.length)
|
|
1232
|
+
return false;
|
|
1233
|
+
const active = tasks.filter((t) => t.status === "running" || t.status === "stopping");
|
|
1234
|
+
const selection = event.thread_ts ? tasks : active.length ? active : tasks.slice(0, 1);
|
|
1235
|
+
const text = selection.length > 1
|
|
1236
|
+
? "目前有多個任務在處理,請到你想查詢的任務對話串詢問,避免弄錯。"
|
|
1237
|
+
: formatTaskStatus(selection);
|
|
1238
|
+
const ts = await post(text);
|
|
1239
|
+
this.logBotResponse(event.channel, text, ts, event.thread_ts);
|
|
1240
|
+
return true;
|
|
1241
|
+
}
|
|
1242
|
+
if (event.thread_ts && (await this.handler.steer?.(context.message))) {
|
|
1243
|
+
await post("收到補充,會在下一個處理步驟納入;目前的操作不會立即中斷。");
|
|
1244
|
+
return true;
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
catch (error) {
|
|
1248
|
+
await post(error instanceof Error ? error.message : "Could not deliver task update.");
|
|
1249
|
+
return true;
|
|
1250
|
+
}
|
|
1251
|
+
return false;
|
|
1252
|
+
}
|
|
1138
1253
|
async handleMessageEvent({ event, ack, }) {
|
|
1139
1254
|
const e = event;
|
|
1140
1255
|
if (!this.admitHumanMessage(e, ack))
|
|
@@ -1182,7 +1297,7 @@ export class SlackMessagingBot {
|
|
|
1182
1297
|
ack();
|
|
1183
1298
|
return;
|
|
1184
1299
|
}
|
|
1185
|
-
if (!isDM && isThreadReply) {
|
|
1300
|
+
if (!isDM && isThreadReply && matchMagicWord(slackEvent.text) !== "stop") {
|
|
1186
1301
|
void attachmentsPromise.catch((err) => {
|
|
1187
1302
|
log.logWarning("Failed to log Slack message", String(err));
|
|
1188
1303
|
});
|
|
@@ -1191,6 +1306,13 @@ export class SlackMessagingBot {
|
|
|
1191
1306
|
}
|
|
1192
1307
|
const activeSessionKey = slackEvent.sessionKey ?? resolveSlackSessionKey(e.channel, e.thread_ts);
|
|
1193
1308
|
slackEvent.sessionKey = activeSessionKey;
|
|
1309
|
+
const taskThread = isDM && !!e.thread_ts && this.isTaskThread(e.channel, e.thread_ts);
|
|
1310
|
+
const taskControl = taskThread || (isDM && !e.thread_ts && isTaskStatusQuestion(slackEvent.text));
|
|
1311
|
+
if (taskControl) {
|
|
1312
|
+
ack();
|
|
1313
|
+
if (await this.deliverTaskUpdate(slackEvent, attachmentsPromise))
|
|
1314
|
+
return;
|
|
1315
|
+
}
|
|
1194
1316
|
const autoReply = !isDM && slackConversationAutoReplyEnabled(this.workspace.office(slackEvent.address));
|
|
1195
1317
|
const intake = this.processSlackMessageIntake({
|
|
1196
1318
|
event: slackEvent,
|
|
@@ -1199,7 +1321,8 @@ export class SlackMessagingBot {
|
|
|
1199
1321
|
addressed: isDM || autoReply,
|
|
1200
1322
|
magicWordAddressed: isDM,
|
|
1201
1323
|
});
|
|
1202
|
-
|
|
1324
|
+
if (!taskControl)
|
|
1325
|
+
ack();
|
|
1203
1326
|
await intake;
|
|
1204
1327
|
}
|
|
1205
1328
|
async handleSlashCommand({ body, ack, }) {
|