@geminixiang/mikan 1.0.0-beta.43 → 1.0.0-beta.45
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 +32 -0
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +3 -17
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/discord/components.d.ts +2 -7
- package/dist/adapters/discord/components.d.ts.map +1 -1
- package/dist/adapters/discord/components.js.map +1 -1
- package/dist/adapters/discord/types.d.ts +7 -0
- package/dist/adapters/discord/types.d.ts.map +1 -1
- package/dist/adapters/discord/types.js.map +1 -1
- package/dist/adapters/github/bot.d.ts.map +1 -1
- package/dist/adapters/github/bot.js +10 -2
- package/dist/adapters/github/bot.js.map +1 -1
- package/dist/adapters/github/types.d.ts +5 -0
- package/dist/adapters/github/types.d.ts.map +1 -1
- package/dist/adapters/github/types.js.map +1 -1
- package/dist/adapters/github/webhook.d.ts +2 -5
- package/dist/adapters/github/webhook.d.ts.map +1 -1
- package/dist/adapters/github/webhook.js.map +1 -1
- package/dist/adapters/markdown-tables.d.ts +2 -7
- package/dist/adapters/markdown-tables.d.ts.map +1 -1
- package/dist/adapters/markdown-tables.js.map +1 -1
- package/dist/adapters/slack/assistant.d.ts +2 -30
- package/dist/adapters/slack/assistant.d.ts.map +1 -1
- package/dist/adapters/slack/assistant.js +1 -0
- package/dist/adapters/slack/assistant.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +3 -4
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +19 -64
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/types.d.ts +29 -0
- package/dist/adapters/slack/types.d.ts.map +1 -1
- package/dist/adapters/slack/types.js.map +1 -1
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +39 -65
- package/dist/adapters/telegram/bot.js.map +1 -1
- package/dist/adapters/types.d.ts +7 -0
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/agent/catalog.d.ts +34 -0
- package/dist/agent/catalog.d.ts.map +1 -0
- package/dist/agent/catalog.js +236 -0
- package/dist/agent/catalog.js.map +1 -0
- package/dist/agent/execution.d.ts +32 -0
- package/dist/agent/execution.d.ts.map +1 -0
- package/dist/agent/execution.js +169 -0
- package/dist/agent/execution.js.map +1 -0
- package/dist/agent/index.d.ts +9 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +8 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/presenter.d.ts +46 -0
- package/dist/agent/presenter.d.ts.map +1 -0
- package/dist/agent/presenter.js +673 -0
- package/dist/agent/presenter.js.map +1 -0
- package/dist/agent/prompt.d.ts +30 -0
- package/dist/agent/prompt.d.ts.map +1 -0
- package/dist/agent/prompt.js +355 -0
- package/dist/agent/prompt.js.map +1 -0
- package/dist/agent/runner.d.ts +10 -0
- package/dist/agent/runner.d.ts.map +1 -0
- package/dist/agent/runner.js +441 -0
- package/dist/agent/runner.js.map +1 -0
- package/dist/agent/types.d.ts +99 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +4 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/cli/boot.d.ts.map +1 -1
- package/dist/cli/boot.js +5 -2
- package/dist/cli/boot.js.map +1 -1
- package/dist/cli/sessions.d.ts +2 -0
- package/dist/cli/sessions.d.ts.map +1 -0
- package/dist/cli/sessions.js +78 -0
- package/dist/cli/sessions.js.map +1 -0
- package/dist/cli/types.d.ts +3 -1
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/cli/types.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +12 -4
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/manifest.d.ts.map +1 -1
- package/dist/commands/manifest.js +3 -0
- package/dist/commands/manifest.js.map +1 -1
- package/dist/commands/registry.d.ts.map +1 -1
- package/dist/commands/registry.js +25 -10
- package/dist/commands/registry.js.map +1 -1
- package/dist/commands/sandbox.js +1 -1
- package/dist/commands/sandbox.js.map +1 -1
- package/dist/commands/types.d.ts +6 -0
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/types.js.map +1 -1
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +36 -0
- package/dist/config.js.map +1 -1
- package/dist/execution-resolver.js +1 -1
- package/dist/execution-resolver.js.map +1 -1
- package/dist/harness/event-format.d.ts +7 -0
- package/dist/harness/event-format.d.ts.map +1 -1
- package/dist/harness/event-format.js +17 -0
- package/dist/harness/event-format.js.map +1 -1
- package/dist/harness/extensions/loader.d.ts.map +1 -1
- package/dist/harness/extensions/loader.js +12 -2
- package/dist/harness/extensions/loader.js.map +1 -1
- package/dist/harness/extensions/registry.d.ts +14 -1
- package/dist/harness/extensions/registry.d.ts.map +1 -1
- package/dist/harness/extensions/registry.js +49 -3
- package/dist/harness/extensions/registry.js.map +1 -1
- package/dist/harness/index.d.ts +3 -3
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +2 -2
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/runner.d.ts +1 -2
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +27 -40
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session-store.d.ts +50 -51
- package/dist/harness/session-store.d.ts.map +1 -1
- package/dist/harness/session-store.js +439 -271
- package/dist/harness/session-store.js.map +1 -1
- package/dist/harness/subagent-runner.d.ts +1 -1
- package/dist/harness/subagent-runner.d.ts.map +1 -1
- package/dist/harness/subagent-runner.js +9 -5
- package/dist/harness/subagent-runner.js.map +1 -1
- package/dist/harness/subagent-slots.d.ts.map +1 -0
- package/dist/harness/subagent-slots.js.map +1 -0
- package/dist/harness/types.d.ts +29 -16
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/usage.d.ts +9 -4
- package/dist/harness/usage.d.ts.map +1 -1
- package/dist/harness/usage.js +9 -3
- package/dist/harness/usage.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/main.js +5 -0
- package/dist/main.js.map +1 -1
- package/dist/mcp/loader.d.ts +11 -0
- package/dist/mcp/loader.d.ts.map +1 -0
- package/dist/mcp/loader.js +126 -0
- package/dist/mcp/loader.js.map +1 -0
- package/dist/mcp/types.d.ts +38 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +2 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/provisioner.d.ts +1 -0
- package/dist/provisioner.d.ts.map +1 -1
- package/dist/provisioner.js +22 -3
- package/dist/provisioner.js.map +1 -1
- package/dist/runtime/conversation-runtime.d.ts.map +1 -1
- package/dist/runtime/conversation-runtime.js +44 -25
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/session-lifecycle.d.ts +13 -0
- package/dist/runtime/session-lifecycle.d.ts.map +1 -1
- package/dist/runtime/session-lifecycle.js +62 -1
- package/dist/runtime/session-lifecycle.js.map +1 -1
- package/dist/runtime/types.d.ts +1 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/identity.d.ts +12 -5
- package/dist/sandbox/identity.d.ts.map +1 -1
- package/dist/sandbox/identity.js +14 -5
- package/dist/sandbox/identity.js.map +1 -1
- package/dist/sessions/chat-history-sync.d.ts +2 -2
- package/dist/sessions/chat-history-sync.d.ts.map +1 -1
- package/dist/sessions/chat-history-sync.js +48 -50
- package/dist/sessions/chat-history-sync.js.map +1 -1
- package/dist/sessions/migrate-v3.d.ts +18 -0
- package/dist/sessions/migrate-v3.d.ts.map +1 -0
- package/dist/sessions/migrate-v3.js +373 -0
- package/dist/sessions/migrate-v3.js.map +1 -0
- package/dist/sessions/rotation.js +4 -2
- package/dist/sessions/rotation.js.map +1 -1
- package/dist/sessions/store.d.ts +1 -1
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +19 -36
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/types.d.ts +1 -2
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js.map +1 -1
- package/dist/settings-mutation.d.ts.map +1 -1
- package/dist/settings-mutation.js +6 -1
- package/dist/settings-mutation.js.map +1 -1
- package/dist/tools/event.d.ts.map +1 -1
- package/dist/tools/event.js +2 -12
- package/dist/tools/event.js.map +1 -1
- package/dist/tools/index.d.ts +2 -3
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +0 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/sandbox.d.ts +2 -2
- package/dist/tools/sandbox.d.ts.map +1 -1
- package/dist/tools/sandbox.js +1 -1
- package/dist/tools/sandbox.js.map +1 -1
- package/dist/types.d.ts +8 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/web/admin/portal.d.ts.map +1 -1
- package/dist/web/admin/portal.js +323 -27
- package/dist/web/admin/portal.js.map +1 -1
- package/dist/web/session-view/portal.js +6 -6
- package/dist/web/session-view/portal.js.map +1 -1
- package/dist/web/session-view/service.d.ts +2 -2
- package/dist/web/session-view/service.d.ts.map +1 -1
- package/dist/web/session-view/service.js +51 -75
- package/dist/web/session-view/service.js.map +1 -1
- package/package.json +4 -3
- package/dist/agent.d.ts +0 -34
- package/dist/agent.d.ts.map +0 -1
- package/dist/agent.js +0 -1820
- package/dist/agent.js.map +0 -1
- package/dist/tools/subagent-slots.d.ts.map +0 -1
- package/dist/tools/subagent-slots.js.map +0 -1
- /package/dist/{tools → harness}/subagent-slots.d.ts +0 -0
- /package/dist/{tools → harness}/subagent-slots.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assistant.d.ts","sourceRoot":"","sources":["../../../src/adapters/slack/assistant.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"assistant.d.ts","sourceRoot":"","sources":["../../../src/adapters/slack/assistant.ts"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,sBAAsB,EAEvB,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,YAAY,EACZ,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,GAChB,MAAM,YAAY,CAAC;AA4BpB;;;;;;;;;;;GAWG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,MAAM,CAAqB;IAEnC,OAAO,CAAC,GAAG;IAIX,kCAAkC;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI,CAE1E;IAED,mDAAmD;IACnD,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI,CAE/D;IAED,qDAAqD;IACrD,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAExE;IAED,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAE1D;IAED;;;;;OAKG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE3D;IAED,4EAA4E;IAC5E,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAKvD;CACF;AAED;;;;;;;GAOG;AACH,wBAAsB,4BAA4B,CAChD,GAAG,EAAE,mBAAmB,EACxB,QAAQ,EAAE,uBAAuB,EACjC,MAAM,EAAE,sBAAsB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,mBAAmB,EACxB,QAAQ,EAAE,uBAAuB,EACjC,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,IAAI,CAAC,CAcf;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,uBAAuB,EACjC,OAAO,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,YAAY,CAAA;CAAE,GAC3E,IAAI,CAaN;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,mBAAmB,EACxB,QAAQ,EAAE,uBAAuB,EACjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAQtD"}
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
* call before they have typed anything.
|
|
34
34
|
*/
|
|
35
35
|
import * as log from "../../log.js";
|
|
36
|
+
/** The `assistant_thread` payload on the `assistant_view` lifecycle events. */
|
|
36
37
|
const GREETING = "有什麼我可以幫忙的?";
|
|
37
38
|
const GREETING_WITH_CHANNEL = (channel) => `有什麼我可以幫忙的?我看得到你正在 #${channel}。`;
|
|
38
39
|
/** Prompts offered with no channel context — general-purpose starting points. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assistant.js","sourceRoot":"","sources":["../../../src/adapters/slack/assistant.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Slack's agent / assistant surface — the app's own pane, separate from\n * channels and ordinary DMs.\n *\n * There are two of these, not one, and they differ in which events signal\n * \"someone opened a conversation\":\n *\n * | Manifest key | Opened signal | Prompts |\n * | ----------------- | ------------------------------------ | ------------- |\n * | `agent_view` | `app_home_opened` with tab=`messages` | pinned to the DM |\n * | `assistant_view` | `assistant_thread_started` | per thread |\n *\n * Slack's own words for the newer one: \"rely on the `app_home_opened` event to\n * know when a user has actively opened a DM with your app\", and\n * \"the `assistant_thread_started` event no longer indicates this\". What the\n * docs do *not* say is whether `assistant_thread_started` still fires for an\n * `agent_view` app — so both paths are handled rather than guessed at, which\n * also means an app on either manifest key works without a migration.\n *\n * The two signals need different behaviour, and conflating them would be a\n * bug: `assistant_thread_started` fires once per new conversation, so greeting\n * is right; `app_home_opened` fires **every time the pane is opened**, so\n * greeting there would nag. The agent path therefore only refreshes the\n * pinned prompts, which is idempotent.\n *\n * Session semantics are deliberately unchanged. Each conversation is a thread\n * and mikan already scopes a thread to its own session — the right shape,\n * because the pane's sidebar is a list of separate conversations rather than\n * one transcript. Continuity across them comes from the office's memory.\n *\n * Suggested prompts are deterministic, varying only with the channel Slack\n * says the person is viewing. Enough to feel aware without spending a model\n * call before they have typed anything.\n */\nimport * as log from \"../../log.js\";\n\n/** The `assistant_thread` payload on the `assistant_view` lifecycle events. */\nexport interface AssistantThreadPayload {\n user_id?: string;\n channel_id?: string;\n thread_ts?: string;\n context?: AgentContext;\n}\n\n/**\n * Which channel the person is viewing beside the pane. Slack spells this\n * `context` on `app_home_opened` and `app_context_changed`, and `app_context`\n * on `message.im` — the asymmetry is Slack's, normalized here.\n */\nexport interface AgentContext {\n channel_id?: string;\n team_id?: string;\n enterprise_id?: string | null;\n}\n\nexport interface SuggestedPrompt {\n title: string;\n message: string;\n}\n\n/** What the adapter needs from the bot to serve this surface. */\nexport interface AssistantSurfaceOps {\n postInThread(channel: string, threadTs: string, text: string): Promise<string>;\n /** `threadTs` omitted pins the prompts to the DM instead of one thread. */\n setSuggestedPrompts(\n channel: string,\n threadTs: string | undefined,\n prompts: SuggestedPrompt[],\n ): Promise<void>;\n setTitle(channel: string, threadTs: string, title: string): Promise<void>;\n /** Human-readable channel name for context, when the bot knows it. */\n channelName(channelId: string): string | undefined;\n}\n\nconst GREETING = \"有什麼我可以幫忙的?\";\nconst GREETING_WITH_CHANNEL = (channel: string) =>\n `有什麼我可以幫忙的?我看得到你正在 #${channel}。`;\n\n/** Prompts offered with no channel context — general-purpose starting points. */\nconst DEFAULT_PROMPTS: SuggestedPrompt[] = [\n { title: \"看看工作區\", message: \"這個工作區裡有什麼?先給我一個概覽。\" },\n { title: \"最近的變更\", message: \"最近的程式碼變更有哪些?挑重要的說。\" },\n { title: \"排一個提醒\", message: \"幫我排一個每天早上的提醒。\" },\n];\n\n/**\n * Prompts when Slack tells us which channel the person is looking at. Naming\n * the channel is the cheap half of \"context-aware\": it costs nothing and it is\n * what makes the suggestions feel addressed to the moment.\n */\nfunction promptsFor(channel: string | undefined): SuggestedPrompt[] {\n if (!channel) return DEFAULT_PROMPTS;\n return [\n { title: `#${channel} 在討論什麼`, message: `幫我摘要 #${channel} 最近的討論。` },\n { title: \"有什麼要我接手\", message: `#${channel} 裡有沒有需要我處理或追蹤的事?` },\n { title: \"看看工作區\", message: \"這個工作區裡有什麼?先給我一個概覽。\" },\n ];\n}\n\n/**\n * Which conversations belong to this surface, and the context Slack last\n * reported for each.\n *\n * Two levels, because the two manifest keys register at different grains: an\n * `agent_view` DM is known before any thread exists, while an\n * `assistant_view` thread is known individually.\n *\n * In memory on purpose: transient UI state that Slack re-sends on open and on\n * every change, so a restart self-heals on the next interaction. Persisting it\n * would add a store to keep consistent for nothing that survives the trip.\n */\nexport class AssistantThreadRegistry {\n private threads = new Map<string, AgentContext>();\n private channels = new Map<string, AgentContext>();\n private titled = new Set<string>();\n\n private key(channelId: string, threadTs: string): string {\n return `${channelId}\\n${threadTs}`;\n }\n\n /** An `assistant_view` thread. */\n remember(channelId: string, threadTs: string, context?: AgentContext): void {\n this.threads.set(this.key(channelId, threadTs), context ?? {});\n }\n\n /** An `agent_view` DM, which has no thread yet. */\n rememberChannel(channelId: string, context?: AgentContext): void {\n this.channels.set(channelId, context ?? {});\n }\n\n /** Thread context, falling back to the channel's. */\n contextFor(channelId: string, threadTs: string): AgentContext | undefined {\n return this.threads.get(this.key(channelId, threadTs)) ?? this.channels.get(channelId);\n }\n\n channelContext(channelId: string): AgentContext | undefined {\n return this.channels.get(channelId);\n }\n\n /**\n * Whether this thread is part of the pane — either registered individually,\n * or living in a DM known to be the agent surface. The second case is what\n * makes titles work under `agent_view`, where Slack opens threads itself and\n * never announces them.\n */\n isAgentSurface(channelId: string, threadTs: string): boolean {\n return this.threads.has(this.key(channelId, threadTs)) || this.channels.has(channelId);\n }\n\n /** True the first time a thread is seen, so a title is set exactly once. */\n claimTitle(channelId: string, threadTs: string): boolean {\n const key = this.key(channelId, threadTs);\n if (this.titled.has(key)) return false;\n this.titled.add(key);\n return true;\n }\n}\n\n/**\n * `assistant_view`: a new conversation opened. Greet, and offer prompts for\n * that thread.\n *\n * Failures are logged, never thrown. A greeting that did not post is a worse\n * pane, not a broken conversation, and taking the socket handler down over it\n * would break the surface entirely.\n */\nexport async function handleAssistantThreadStarted(\n ops: AssistantSurfaceOps,\n registry: AssistantThreadRegistry,\n thread: AssistantThreadPayload,\n): Promise<void> {\n const channelId = thread.channel_id;\n const threadTs = thread.thread_ts;\n if (!channelId || !threadTs) return;\n\n registry.remember(channelId, threadTs, thread.context);\n const channel = thread.context?.channel_id\n ? ops.channelName(thread.context.channel_id)\n : undefined;\n\n await swallow(\"greeting\", () =>\n ops.postInThread(channelId, threadTs, channel ? GREETING_WITH_CHANNEL(channel) : GREETING),\n );\n await swallow(\"setSuggestedPrompts\", () =>\n ops.setSuggestedPrompts(channelId, threadTs, promptsFor(channel)),\n );\n}\n\n/**\n * `agent_view`: the person opened the app's DM. Refresh the prompts pinned to\n * it — and deliberately do not greet, because Slack sends this on *every*\n * open, so a greeting here would arrive again and again.\n */\nexport async function handleAgentDmOpened(\n ops: AssistantSurfaceOps,\n registry: AssistantThreadRegistry,\n channelId: string,\n context?: AgentContext,\n): Promise<void> {\n if (!channelId) return;\n registry.rememberChannel(channelId, context);\n const channel = context?.channel_id ? ops.channelName(context.channel_id) : undefined;\n // The agent surface is otherwise silent, and its failure mode — no prompts,\n // untitled conversations — looks identical from the outside to Slack simply\n // not sending the event. This line is the difference between the two, and\n // is the first thing to look for when the pane seems inert.\n log.logInfo(\n `[${channelId}] Slack agent DM opened${channel ? ` (viewing #${channel})` : \"\"}; refreshing suggested prompts`,\n );\n await swallow(\"setSuggestedPrompts\", () =>\n ops.setSuggestedPrompts(channelId, undefined, promptsFor(channel)),\n );\n}\n\n/**\n * The person navigated elsewhere. Recorded at both grains so the next turn —\n * and the next prompt refresh — knows where they are, whichever manifest key\n * this app uses.\n */\nexport function handleAgentContextChanged(\n registry: AssistantThreadRegistry,\n payload: { channel_id?: string; thread_ts?: string; context?: AgentContext },\n): void {\n if (!payload.channel_id) return;\n // Logged for the same reason as the open event: these two are the whole\n // agent surface, and whether either is subscribed is otherwise invisible\n // from inside mikan.\n log.logInfo(\n `[${payload.channel_id}] Slack agent context changed${payload.context?.channel_id ? ` (viewing ${payload.context.channel_id})` : \"\"}`,\n );\n if (payload.thread_ts) {\n registry.remember(payload.channel_id, payload.thread_ts, payload.context);\n return;\n }\n registry.rememberChannel(payload.channel_id, payload.context);\n}\n\n/**\n * Title a conversation from the first thing the person said, so the pane's\n * sidebar is navigable. Without it every past conversation looks the same.\n */\nexport async function titleAssistantThread(\n ops: AssistantSurfaceOps,\n registry: AssistantThreadRegistry,\n channelId: string,\n threadTs: string,\n firstMessage: string,\n): Promise<void> {\n if (!registry.isAgentSurface(channelId, threadTs)) return;\n if (!registry.claimTitle(channelId, threadTs)) return;\n const title = summarizeTitle(firstMessage);\n if (!title) return;\n await swallow(\"setTitle\", () => ops.setTitle(channelId, threadTs, title));\n}\n\n/**\n * First line, trimmed to something a sidebar can show. Deliberately not a\n * model call: a title is worth having immediately and cheaply, and the\n * person's own words label the conversation better than a paraphrase.\n */\nexport function summarizeTitle(message: string): string {\n const firstLine = message\n .replace(/<@[^>]+>/g, \"\")\n .split(\"\\n\")\n .map((line) => line.trim())\n .find((line) => line.length > 0);\n if (!firstLine) return \"\";\n return firstLine.length <= 50 ? firstLine : `${firstLine.slice(0, 49)}…`;\n}\n\nasync function swallow(label: string, run: () => Promise<unknown>): Promise<void> {\n try {\n await run();\n } catch (err) {\n log.logWarning(\n `Slack agent surface ${label} failed`,\n err instanceof Error ? err.message : String(err),\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"assistant.js","sourceRoot":"","sources":["../../../src/adapters/slack/assistant.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Slack's agent / assistant surface — the app's own pane, separate from\n * channels and ordinary DMs.\n *\n * There are two of these, not one, and they differ in which events signal\n * \"someone opened a conversation\":\n *\n * | Manifest key | Opened signal | Prompts |\n * | ----------------- | ------------------------------------ | ------------- |\n * | `agent_view` | `app_home_opened` with tab=`messages` | pinned to the DM |\n * | `assistant_view` | `assistant_thread_started` | per thread |\n *\n * Slack's own words for the newer one: \"rely on the `app_home_opened` event to\n * know when a user has actively opened a DM with your app\", and\n * \"the `assistant_thread_started` event no longer indicates this\". What the\n * docs do *not* say is whether `assistant_thread_started` still fires for an\n * `agent_view` app — so both paths are handled rather than guessed at, which\n * also means an app on either manifest key works without a migration.\n *\n * The two signals need different behaviour, and conflating them would be a\n * bug: `assistant_thread_started` fires once per new conversation, so greeting\n * is right; `app_home_opened` fires **every time the pane is opened**, so\n * greeting there would nag. The agent path therefore only refreshes the\n * pinned prompts, which is idempotent.\n *\n * Session semantics are deliberately unchanged. Each conversation is a thread\n * and mikan already scopes a thread to its own session — the right shape,\n * because the pane's sidebar is a list of separate conversations rather than\n * one transcript. Continuity across them comes from the office's memory.\n *\n * Suggested prompts are deterministic, varying only with the channel Slack\n * says the person is viewing. Enough to feel aware without spending a model\n * call before they have typed anything.\n */\nimport * as log from \"../../log.js\";\nimport type {\n AgentContext,\n AssistantSurfaceOps,\n AssistantThreadPayload,\n SuggestedPrompt,\n} from \"./types.js\";\n\nexport type {\n AgentContext,\n AssistantSurfaceOps,\n AssistantThreadPayload,\n SuggestedPrompt,\n} from \"./types.js\";\n\n/** The `assistant_thread` payload on the `assistant_view` lifecycle events. */\nconst GREETING = \"有什麼我可以幫忙的?\";\nconst GREETING_WITH_CHANNEL = (channel: string) =>\n `有什麼我可以幫忙的?我看得到你正在 #${channel}。`;\n\n/** Prompts offered with no channel context — general-purpose starting points. */\nconst DEFAULT_PROMPTS: SuggestedPrompt[] = [\n { title: \"看看工作區\", message: \"這個工作區裡有什麼?先給我一個概覽。\" },\n { title: \"最近的變更\", message: \"最近的程式碼變更有哪些?挑重要的說。\" },\n { title: \"排一個提醒\", message: \"幫我排一個每天早上的提醒。\" },\n];\n\n/**\n * Prompts when Slack tells us which channel the person is looking at. Naming\n * the channel is the cheap half of \"context-aware\": it costs nothing and it is\n * what makes the suggestions feel addressed to the moment.\n */\nfunction promptsFor(channel: string | undefined): SuggestedPrompt[] {\n if (!channel) return DEFAULT_PROMPTS;\n return [\n { title: `#${channel} 在討論什麼`, message: `幫我摘要 #${channel} 最近的討論。` },\n { title: \"有什麼要我接手\", message: `#${channel} 裡有沒有需要我處理或追蹤的事?` },\n { title: \"看看工作區\", message: \"這個工作區裡有什麼?先給我一個概覽。\" },\n ];\n}\n\n/**\n * Which conversations belong to this surface, and the context Slack last\n * reported for each.\n *\n * Two levels, because the two manifest keys register at different grains: an\n * `agent_view` DM is known before any thread exists, while an\n * `assistant_view` thread is known individually.\n *\n * In memory on purpose: transient UI state that Slack re-sends on open and on\n * every change, so a restart self-heals on the next interaction. Persisting it\n * would add a store to keep consistent for nothing that survives the trip.\n */\nexport class AssistantThreadRegistry {\n private threads = new Map<string, AgentContext>();\n private channels = new Map<string, AgentContext>();\n private titled = new Set<string>();\n\n private key(channelId: string, threadTs: string): string {\n return `${channelId}\\n${threadTs}`;\n }\n\n /** An `assistant_view` thread. */\n remember(channelId: string, threadTs: string, context?: AgentContext): void {\n this.threads.set(this.key(channelId, threadTs), context ?? {});\n }\n\n /** An `agent_view` DM, which has no thread yet. */\n rememberChannel(channelId: string, context?: AgentContext): void {\n this.channels.set(channelId, context ?? {});\n }\n\n /** Thread context, falling back to the channel's. */\n contextFor(channelId: string, threadTs: string): AgentContext | undefined {\n return this.threads.get(this.key(channelId, threadTs)) ?? this.channels.get(channelId);\n }\n\n channelContext(channelId: string): AgentContext | undefined {\n return this.channels.get(channelId);\n }\n\n /**\n * Whether this thread is part of the pane — either registered individually,\n * or living in a DM known to be the agent surface. The second case is what\n * makes titles work under `agent_view`, where Slack opens threads itself and\n * never announces them.\n */\n isAgentSurface(channelId: string, threadTs: string): boolean {\n return this.threads.has(this.key(channelId, threadTs)) || this.channels.has(channelId);\n }\n\n /** True the first time a thread is seen, so a title is set exactly once. */\n claimTitle(channelId: string, threadTs: string): boolean {\n const key = this.key(channelId, threadTs);\n if (this.titled.has(key)) return false;\n this.titled.add(key);\n return true;\n }\n}\n\n/**\n * `assistant_view`: a new conversation opened. Greet, and offer prompts for\n * that thread.\n *\n * Failures are logged, never thrown. A greeting that did not post is a worse\n * pane, not a broken conversation, and taking the socket handler down over it\n * would break the surface entirely.\n */\nexport async function handleAssistantThreadStarted(\n ops: AssistantSurfaceOps,\n registry: AssistantThreadRegistry,\n thread: AssistantThreadPayload,\n): Promise<void> {\n const channelId = thread.channel_id;\n const threadTs = thread.thread_ts;\n if (!channelId || !threadTs) return;\n\n registry.remember(channelId, threadTs, thread.context);\n const channel = thread.context?.channel_id\n ? ops.channelName(thread.context.channel_id)\n : undefined;\n\n await swallow(\"greeting\", () =>\n ops.postInThread(channelId, threadTs, channel ? GREETING_WITH_CHANNEL(channel) : GREETING),\n );\n await swallow(\"setSuggestedPrompts\", () =>\n ops.setSuggestedPrompts(channelId, threadTs, promptsFor(channel)),\n );\n}\n\n/**\n * `agent_view`: the person opened the app's DM. Refresh the prompts pinned to\n * it — and deliberately do not greet, because Slack sends this on *every*\n * open, so a greeting here would arrive again and again.\n */\nexport async function handleAgentDmOpened(\n ops: AssistantSurfaceOps,\n registry: AssistantThreadRegistry,\n channelId: string,\n context?: AgentContext,\n): Promise<void> {\n if (!channelId) return;\n registry.rememberChannel(channelId, context);\n const channel = context?.channel_id ? ops.channelName(context.channel_id) : undefined;\n // The agent surface is otherwise silent, and its failure mode — no prompts,\n // untitled conversations — looks identical from the outside to Slack simply\n // not sending the event. This line is the difference between the two, and\n // is the first thing to look for when the pane seems inert.\n log.logInfo(\n `[${channelId}] Slack agent DM opened${channel ? ` (viewing #${channel})` : \"\"}; refreshing suggested prompts`,\n );\n await swallow(\"setSuggestedPrompts\", () =>\n ops.setSuggestedPrompts(channelId, undefined, promptsFor(channel)),\n );\n}\n\n/**\n * The person navigated elsewhere. Recorded at both grains so the next turn —\n * and the next prompt refresh — knows where they are, whichever manifest key\n * this app uses.\n */\nexport function handleAgentContextChanged(\n registry: AssistantThreadRegistry,\n payload: { channel_id?: string; thread_ts?: string; context?: AgentContext },\n): void {\n if (!payload.channel_id) return;\n // Logged for the same reason as the open event: these two are the whole\n // agent surface, and whether either is subscribed is otherwise invisible\n // from inside mikan.\n log.logInfo(\n `[${payload.channel_id}] Slack agent context changed${payload.context?.channel_id ? ` (viewing ${payload.context.channel_id})` : \"\"}`,\n );\n if (payload.thread_ts) {\n registry.remember(payload.channel_id, payload.thread_ts, payload.context);\n return;\n }\n registry.rememberChannel(payload.channel_id, payload.context);\n}\n\n/**\n * Title a conversation from the first thing the person said, so the pane's\n * sidebar is navigable. Without it every past conversation looks the same.\n */\nexport async function titleAssistantThread(\n ops: AssistantSurfaceOps,\n registry: AssistantThreadRegistry,\n channelId: string,\n threadTs: string,\n firstMessage: string,\n): Promise<void> {\n if (!registry.isAgentSurface(channelId, threadTs)) return;\n if (!registry.claimTitle(channelId, threadTs)) return;\n const title = summarizeTitle(firstMessage);\n if (!title) return;\n await swallow(\"setTitle\", () => ops.setTitle(channelId, threadTs, title));\n}\n\n/**\n * First line, trimmed to something a sidebar can show. Deliberately not a\n * model call: a title is worth having immediately and cheaply, and the\n * person's own words label the conversation better than a paraphrase.\n */\nexport function summarizeTitle(message: string): string {\n const firstLine = message\n .replace(/<@[^>]+>/g, \"\")\n .split(\"\\n\")\n .map((line) => line.trim())\n .find((line) => line.length > 0);\n if (!firstLine) return \"\";\n return firstLine.length <= 50 ? firstLine : `${firstLine.slice(0, 49)}…`;\n}\n\nasync function swallow(label: string, run: () => Promise<unknown>): Promise<void> {\n try {\n await run();\n } catch (err) {\n log.logWarning(\n `Slack agent surface ${label} failed`,\n err instanceof Error ? err.message : String(err),\n );\n }\n}\n"]}
|
|
@@ -146,12 +146,11 @@ export declare class SlackMessagingBot implements MessagingBot {
|
|
|
146
146
|
private buildSlashCommandEvent;
|
|
147
147
|
/**
|
|
148
148
|
* Generic slash-command route: synthesize the command text per the
|
|
149
|
-
* manifest's SlackSlashRoute data and dispatch to the handler.
|
|
150
|
-
*
|
|
151
|
-
*
|
|
149
|
+
* manifest's SlackSlashRoute data and dispatch to the handler. Every
|
|
150
|
+
* routed command — including `/pi-new` — reaches its CommandHandler
|
|
151
|
+
* through runtime dispatch; the adapter holds no per-command behavior.
|
|
152
152
|
*/
|
|
153
153
|
private routeSlashCommand;
|
|
154
|
-
private routeSlashNewCommand;
|
|
155
154
|
private setupEventHandlers;
|
|
156
155
|
private handleAppMention;
|
|
157
156
|
private handleMessageEvent;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../../src/adapters/slack/bot.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"bot.d.ts","sourceRoot":"","sources":["../../../src/adapters/slack/bot.ts"],"names":[],"mappings":"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"}
|
|
@@ -848,7 +848,10 @@ export class SlackMessagingBot {
|
|
|
848
848
|
platform: "slack",
|
|
849
849
|
conversationId,
|
|
850
850
|
id: ts,
|
|
851
|
-
|
|
851
|
+
// One session identity per dispatch: the caller's thread-resolved key.
|
|
852
|
+
// Defaulting to the top-level conversation here while the event carried
|
|
853
|
+
// a thread key made the same run answer to two different sessions.
|
|
854
|
+
sessionKey: options.sessionKey ?? conversationId,
|
|
852
855
|
conversationKind: options.ephemeralChannelId ? "shared" : "direct",
|
|
853
856
|
userId,
|
|
854
857
|
userName,
|
|
@@ -934,14 +937,16 @@ export class SlackMessagingBot {
|
|
|
934
937
|
...(threadTs ? { thread_ts: threadTs } : {}),
|
|
935
938
|
sessionKey,
|
|
936
939
|
});
|
|
937
|
-
const context = this.createCommandAdapters(conversationId, payload.user_id, userName, commandText, eventTs, isDirectMessage
|
|
940
|
+
const context = this.createCommandAdapters(conversationId, payload.user_id, userName, commandText, eventTs, isDirectMessage
|
|
941
|
+
? { threadTs, sessionKey }
|
|
942
|
+
: { ephemeralChannelId: conversationId, threadTs, sessionKey });
|
|
938
943
|
return { event, context };
|
|
939
944
|
}
|
|
940
945
|
/**
|
|
941
946
|
* Generic slash-command route: synthesize the command text per the
|
|
942
|
-
* manifest's SlackSlashRoute data and dispatch to the handler.
|
|
943
|
-
*
|
|
944
|
-
*
|
|
947
|
+
* manifest's SlackSlashRoute data and dispatch to the handler. Every
|
|
948
|
+
* routed command — including `/pi-new` — reaches its CommandHandler
|
|
949
|
+
* through runtime dispatch; the adapter holds no per-command behavior.
|
|
945
950
|
*/
|
|
946
951
|
async routeSlashCommand(route, payload) {
|
|
947
952
|
const { event, context } = this.buildSlashCommandEvent(payload, {
|
|
@@ -957,48 +962,6 @@ export class SlackMessagingBot {
|
|
|
957
962
|
});
|
|
958
963
|
await this.handler.handleEvent(event, this, context);
|
|
959
964
|
}
|
|
960
|
-
async routeSlashNewCommand(payload) {
|
|
961
|
-
const conversationId = payload.channel_id;
|
|
962
|
-
if (!conversationId.startsWith("D")) {
|
|
963
|
-
await this.postEphemeral(conversationId, payload.user_id, `為了避免誤清除共享上下文,${payload.command} 目前只能在與 ${PRODUCT_NAME} 的私訊中使用。`);
|
|
964
|
-
return;
|
|
965
|
-
}
|
|
966
|
-
const createdAt = new Date();
|
|
967
|
-
const eventTs = (createdAt.getTime() / 1000).toFixed(6);
|
|
968
|
-
const userName = payload.user_name ?? this.getUser(payload.user_id)?.userName;
|
|
969
|
-
this.logToFile(conversationId, {
|
|
970
|
-
date: createdAt.toISOString(),
|
|
971
|
-
ts: eventTs,
|
|
972
|
-
user: payload.user_id,
|
|
973
|
-
userName,
|
|
974
|
-
text: payload.command,
|
|
975
|
-
attachments: [],
|
|
976
|
-
isMessagingBot: false,
|
|
977
|
-
});
|
|
978
|
-
const commandMessagingBot = {
|
|
979
|
-
start: async () => { },
|
|
980
|
-
postMessage: async (_channel, text) => this.postMessage(conversationId, text),
|
|
981
|
-
updateMessage: async (channel, ts, text) => this.updateMessage(channel, ts, text),
|
|
982
|
-
enqueueEvent: (event) => this.enqueueEvent(event),
|
|
983
|
-
getMessagingInfo: () => this.getMessagingInfo(),
|
|
984
|
-
};
|
|
985
|
-
const event = {
|
|
986
|
-
...createConversationEvent({
|
|
987
|
-
platform: "slack",
|
|
988
|
-
conversationId,
|
|
989
|
-
type: "dm",
|
|
990
|
-
conversationKind: "direct",
|
|
991
|
-
ts: eventTs,
|
|
992
|
-
user: payload.user_id,
|
|
993
|
-
text: payload.command,
|
|
994
|
-
attachments: [],
|
|
995
|
-
sessionKey: conversationId,
|
|
996
|
-
}),
|
|
997
|
-
channel: conversationId,
|
|
998
|
-
};
|
|
999
|
-
const context = createSlackAdapters(event, this);
|
|
1000
|
-
await this.handler.handleNewCommand(conversationId, conversationId, commandMessagingBot, context.message, context.responder, context.platform);
|
|
1001
|
-
}
|
|
1002
965
|
setupEventHandlers() {
|
|
1003
966
|
this.socketClient.on("disconnect", (err) => {
|
|
1004
967
|
log.logWarning("Slack socket disconnect", err ? String(err) : "");
|
|
@@ -1195,24 +1158,16 @@ export class SlackMessagingBot {
|
|
|
1195
1158
|
const entry = COMMAND_MANIFEST.find((candidate) => candidate.slackCommand === command);
|
|
1196
1159
|
if (!entry)
|
|
1197
1160
|
return;
|
|
1198
|
-
|
|
1199
|
-
if (entry.name === "new") {
|
|
1200
|
-
handlerPromise = this.routeSlashNewCommand({ command, channel_id, user_id, user_name });
|
|
1201
|
-
}
|
|
1202
|
-
else if (entry.slackRoute) {
|
|
1203
|
-
handlerPromise = this.routeSlashCommand(entry.slackRoute, {
|
|
1204
|
-
command,
|
|
1205
|
-
text,
|
|
1206
|
-
channel_id,
|
|
1207
|
-
user_id,
|
|
1208
|
-
user_name,
|
|
1209
|
-
thread_ts,
|
|
1210
|
-
});
|
|
1211
|
-
}
|
|
1212
|
-
if (!handlerPromise) {
|
|
1161
|
+
if (!entry.slackRoute)
|
|
1213
1162
|
return;
|
|
1214
|
-
|
|
1215
|
-
|
|
1163
|
+
this.routeSlashCommand(entry.slackRoute, {
|
|
1164
|
+
command,
|
|
1165
|
+
text,
|
|
1166
|
+
channel_id,
|
|
1167
|
+
user_id,
|
|
1168
|
+
user_name,
|
|
1169
|
+
thread_ts,
|
|
1170
|
+
}).catch((err) => {
|
|
1216
1171
|
log.logWarning("Slack slash command error", err instanceof Error ? err.message : String(err));
|
|
1217
1172
|
});
|
|
1218
1173
|
}
|