@geminixiang/mikan 1.0.0-beta.76 → 1.0.0-beta.78
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 +39 -0
- package/dist/adapters/commands/login.d.ts.map +1 -1
- package/dist/adapters/commands/login.js +0 -9
- package/dist/adapters/commands/login.js.map +1 -1
- package/dist/adapters/commands/manifest.d.ts +0 -19
- package/dist/adapters/commands/manifest.d.ts.map +1 -1
- package/dist/adapters/commands/manifest.js +0 -34
- package/dist/adapters/commands/manifest.js.map +1 -1
- package/dist/adapters/commands/model.d.ts +0 -5
- package/dist/adapters/commands/model.d.ts.map +1 -1
- package/dist/adapters/commands/model.js +0 -5
- package/dist/adapters/commands/model.js.map +1 -1
- package/dist/adapters/commands/new.d.ts.map +1 -1
- package/dist/adapters/commands/new.js +0 -2
- package/dist/adapters/commands/new.js.map +1 -1
- package/dist/adapters/commands/registry.d.ts +0 -1
- package/dist/adapters/commands/registry.d.ts.map +1 -1
- package/dist/adapters/commands/registry.js +0 -8
- package/dist/adapters/commands/registry.js.map +1 -1
- package/dist/adapters/commands/session-view.d.ts.map +1 -1
- package/dist/adapters/commands/session-view.js +0 -2
- package/dist/adapters/commands/session-view.js.map +1 -1
- package/dist/adapters/commands/types.d.ts +0 -29
- package/dist/adapters/commands/types.d.ts.map +1 -1
- package/dist/adapters/commands/types.js.map +1 -1
- package/dist/adapters/commands/utils.d.ts +0 -3
- package/dist/adapters/commands/utils.d.ts.map +1 -1
- package/dist/adapters/commands/utils.js +0 -3
- package/dist/adapters/commands/utils.js.map +1 -1
- package/dist/adapters/discord/bot.d.ts +0 -4
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +5 -41
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/discord/components.d.ts +0 -23
- package/dist/adapters/discord/components.d.ts.map +1 -1
- package/dist/adapters/discord/components.js +0 -23
- package/dist/adapters/discord/components.js.map +1 -1
- package/dist/adapters/discord/context.d.ts.map +1 -1
- package/dist/adapters/discord/context.js +1 -11
- package/dist/adapters/discord/context.js.map +1 -1
- package/dist/adapters/discord/format.d.ts +0 -1
- package/dist/adapters/discord/format.d.ts.map +1 -1
- package/dist/adapters/discord/format.js +0 -37
- package/dist/adapters/discord/format.js.map +1 -1
- package/dist/adapters/github/bot.d.ts +0 -44
- package/dist/adapters/github/bot.d.ts.map +1 -1
- package/dist/adapters/github/bot.js +1 -120
- package/dist/adapters/github/bot.js.map +1 -1
- package/dist/adapters/github/client.d.ts +0 -57
- package/dist/adapters/github/client.d.ts.map +1 -1
- package/dist/adapters/github/client.js +0 -59
- package/dist/adapters/github/client.js.map +1 -1
- package/dist/adapters/github/context.d.ts.map +1 -1
- package/dist/adapters/github/context.js +1 -8
- package/dist/adapters/github/context.js.map +1 -1
- package/dist/adapters/github/github-ops.d.ts +0 -55
- package/dist/adapters/github/github-ops.d.ts.map +1 -1
- package/dist/adapters/github/github-ops.js +0 -59
- package/dist/adapters/github/github-ops.js.map +1 -1
- package/dist/adapters/github/ids.d.ts +0 -27
- package/dist/adapters/github/ids.d.ts.map +1 -1
- package/dist/adapters/github/ids.js +0 -29
- package/dist/adapters/github/ids.js.map +1 -1
- package/dist/adapters/github/repo.d.ts +0 -25
- package/dist/adapters/github/repo.d.ts.map +1 -1
- package/dist/adapters/github/repo.js +0 -49
- package/dist/adapters/github/repo.js.map +1 -1
- package/dist/adapters/github/tool-pack.d.ts +0 -10
- package/dist/adapters/github/tool-pack.d.ts.map +1 -1
- package/dist/adapters/github/tool-pack.js +0 -10
- package/dist/adapters/github/tool-pack.js.map +1 -1
- package/dist/adapters/github/tools/checks.d.ts +0 -6
- package/dist/adapters/github/tools/checks.d.ts.map +1 -1
- package/dist/adapters/github/tools/checks.js +0 -7
- package/dist/adapters/github/tools/checks.js.map +1 -1
- package/dist/adapters/github/tools/issue.d.ts +0 -5
- package/dist/adapters/github/tools/issue.d.ts.map +1 -1
- package/dist/adapters/github/tools/issue.js +0 -5
- package/dist/adapters/github/tools/issue.js.map +1 -1
- package/dist/adapters/github/tools/pr.d.ts +0 -7
- package/dist/adapters/github/tools/pr.d.ts.map +1 -1
- package/dist/adapters/github/tools/pr.js +0 -7
- package/dist/adapters/github/tools/pr.js.map +1 -1
- package/dist/adapters/github/tools/read.d.ts +0 -6
- package/dist/adapters/github/tools/read.d.ts.map +1 -1
- package/dist/adapters/github/tools/read.js +0 -8
- package/dist/adapters/github/tools/read.js.map +1 -1
- package/dist/adapters/github/tools/review-reply.d.ts +0 -5
- package/dist/adapters/github/tools/review-reply.d.ts.map +1 -1
- package/dist/adapters/github/tools/review-reply.js +0 -5
- package/dist/adapters/github/tools/review-reply.js.map +1 -1
- package/dist/adapters/github/tools/sync.d.ts +0 -6
- package/dist/adapters/github/tools/sync.d.ts.map +1 -1
- package/dist/adapters/github/tools/sync.js +0 -6
- package/dist/adapters/github/tools/sync.js.map +1 -1
- package/dist/adapters/github/types.d.ts +0 -88
- 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 +0 -13
- package/dist/adapters/github/webhook.d.ts.map +1 -1
- package/dist/adapters/github/webhook.js +0 -16
- package/dist/adapters/github/webhook.js.map +1 -1
- package/dist/adapters/index.d.ts +3 -4
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/intake.d.ts +0 -17
- package/dist/adapters/intake.d.ts.map +1 -1
- package/dist/adapters/intake.js +6 -32
- package/dist/adapters/intake.js.map +1 -1
- package/dist/adapters/markdown-tables.d.ts +0 -10
- package/dist/adapters/markdown-tables.d.ts.map +1 -1
- package/dist/adapters/markdown-tables.js +1 -42
- package/dist/adapters/markdown-tables.js.map +1 -1
- package/dist/adapters/progressive-renderer.d.ts.map +1 -1
- package/dist/adapters/progressive-renderer.js +3 -25
- package/dist/adapters/progressive-renderer.js.map +1 -1
- package/dist/adapters/shared.d.ts +0 -57
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/shared.js +0 -71
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/slack/assistant.d.ts +0 -49
- package/dist/adapters/slack/assistant.d.ts.map +1 -1
- package/dist/adapters/slack/assistant.js +0 -97
- package/dist/adapters/slack/assistant.js.map +1 -1
- package/dist/adapters/slack/auto-reply-context.d.ts +0 -7
- package/dist/adapters/slack/auto-reply-context.d.ts.map +1 -1
- package/dist/adapters/slack/auto-reply-context.js +0 -7
- package/dist/adapters/slack/auto-reply-context.js.map +1 -1
- package/dist/adapters/slack/blocks.d.ts +0 -9
- package/dist/adapters/slack/blocks.d.ts.map +1 -1
- package/dist/adapters/slack/blocks.js +0 -20
- package/dist/adapters/slack/blocks.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +0 -116
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +7 -231
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/context.d.ts.map +1 -1
- package/dist/adapters/slack/context.js +1 -3
- package/dist/adapters/slack/context.js.map +1 -1
- package/dist/adapters/slack/jev-context.d.ts +0 -13
- package/dist/adapters/slack/jev-context.d.ts.map +1 -1
- package/dist/adapters/slack/jev-context.js +0 -12
- package/dist/adapters/slack/jev-context.js.map +1 -1
- package/dist/adapters/slack/markdown.d.ts +0 -1
- package/dist/adapters/slack/markdown.d.ts.map +1 -1
- package/dist/adapters/slack/markdown.js +0 -5
- package/dist/adapters/slack/markdown.js.map +1 -1
- package/dist/adapters/slack/persona.d.ts +0 -9
- package/dist/adapters/slack/persona.d.ts.map +1 -1
- package/dist/adapters/slack/persona.js +0 -9
- package/dist/adapters/slack/persona.js.map +1 -1
- package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
- package/dist/adapters/slack/response-lifecycle.js +1 -45
- package/dist/adapters/slack/response-lifecycle.js.map +1 -1
- package/dist/adapters/slack/session.d.ts +2 -1
- package/dist/adapters/slack/session.d.ts.map +1 -1
- package/dist/adapters/slack/session.js +2 -2
- package/dist/adapters/slack/session.js.map +1 -1
- package/dist/adapters/slack/stream-limits.d.ts +0 -25
- package/dist/adapters/slack/stream-limits.d.ts.map +1 -1
- package/dist/adapters/slack/stream-limits.js +0 -34
- package/dist/adapters/slack/stream-limits.js.map +1 -1
- package/dist/adapters/slack/task-intent.d.ts +0 -13
- package/dist/adapters/slack/task-intent.d.ts.map +1 -1
- package/dist/adapters/slack/task-intent.js +0 -7
- package/dist/adapters/slack/task-intent.js.map +1 -1
- package/dist/adapters/slack/task-status.d.ts +0 -1
- package/dist/adapters/slack/task-status.d.ts.map +1 -1
- package/dist/adapters/slack/task-status.js +1 -9
- package/dist/adapters/slack/task-status.js.map +1 -1
- package/dist/adapters/slack/tool-pack.d.ts +0 -6
- package/dist/adapters/slack/tool-pack.d.ts.map +1 -1
- package/dist/adapters/slack/tool-pack.js +0 -6
- package/dist/adapters/slack/tool-pack.js.map +1 -1
- package/dist/adapters/slack/tools/blockkit.d.ts.map +1 -1
- package/dist/adapters/slack/tools/blockkit.js +0 -11
- package/dist/adapters/slack/tools/blockkit.js.map +1 -1
- package/dist/adapters/slack/types.d.ts +0 -19
- package/dist/adapters/slack/types.d.ts.map +1 -1
- package/dist/adapters/slack/types.js.map +1 -1
- package/dist/adapters/slack/update-diagnostics.d.ts +0 -1
- package/dist/adapters/slack/update-diagnostics.d.ts.map +1 -1
- package/dist/adapters/slack/update-diagnostics.js +1 -7
- package/dist/adapters/slack/update-diagnostics.js.map +1 -1
- package/dist/adapters/telegram/bot.d.ts +0 -6
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +1 -50
- package/dist/adapters/telegram/bot.js.map +1 -1
- package/dist/adapters/telegram/context.d.ts.map +1 -1
- package/dist/adapters/telegram/context.js +1 -8
- package/dist/adapters/telegram/context.js.map +1 -1
- package/dist/adapters/types.d.ts +0 -57
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/adapters/web/admin/client-assets.d.ts +4 -0
- package/dist/adapters/web/admin/client-assets.d.ts.map +1 -0
- package/dist/adapters/web/admin/client-assets.js +1765 -0
- package/dist/adapters/web/admin/client-assets.js.map +1 -0
- package/dist/adapters/web/admin/portal.d.ts +0 -10
- package/dist/adapters/web/admin/portal.d.ts.map +1 -1
- package/dist/adapters/web/admin/portal.js +6 -1909
- package/dist/adapters/web/admin/portal.js.map +1 -1
- package/dist/adapters/web/admin/types.d.ts +0 -3
- package/dist/adapters/web/admin/types.d.ts.map +1 -1
- package/dist/adapters/web/admin/types.js.map +1 -1
- package/dist/adapters/web/login/oauth.d.ts.map +1 -1
- package/dist/adapters/web/login/oauth.js +3 -7
- package/dist/adapters/web/login/oauth.js.map +1 -1
- package/dist/adapters/web/login/portal.d.ts +0 -10
- package/dist/adapters/web/login/portal.d.ts.map +1 -1
- package/dist/adapters/web/login/portal.js +4 -37
- package/dist/adapters/web/login/portal.js.map +1 -1
- package/dist/adapters/web/login/types.d.ts +0 -5
- package/dist/adapters/web/login/types.d.ts.map +1 -1
- package/dist/adapters/web/login/types.js.map +1 -1
- package/dist/adapters/web/portal-shell.d.ts +0 -12
- package/dist/adapters/web/portal-shell.d.ts.map +1 -1
- package/dist/adapters/web/portal-shell.js +8 -25
- package/dist/adapters/web/portal-shell.js.map +1 -1
- package/dist/adapters/web/server.d.ts +0 -1
- package/dist/adapters/web/server.d.ts.map +1 -1
- package/dist/adapters/web/server.js +0 -2
- package/dist/adapters/web/server.js.map +1 -1
- package/dist/adapters/web/session-view/portal.d.ts.map +1 -1
- package/dist/adapters/web/session-view/portal.js +13 -24
- package/dist/adapters/web/session-view/portal.js.map +1 -1
- package/dist/adapters/web/session-view/types.d.ts.map +1 -1
- package/dist/adapters/web/session-view/types.js.map +1 -1
- package/dist/adapters/web/token-store.d.ts +0 -2
- package/dist/adapters/web/token-store.d.ts.map +1 -1
- package/dist/adapters/web/token-store.js +0 -2
- package/dist/adapters/web/token-store.js.map +1 -1
- package/dist/cli/arg-grammar.d.ts +0 -3
- package/dist/cli/arg-grammar.d.ts.map +1 -1
- package/dist/cli/arg-grammar.js +0 -3
- package/dist/cli/arg-grammar.js.map +1 -1
- package/dist/cli/boot.d.ts.map +1 -1
- package/dist/cli/boot.js +3 -12
- package/dist/cli/boot.js.map +1 -1
- package/dist/cli/download.d.ts.map +1 -1
- package/dist/cli/download.js +2 -6
- package/dist/cli/download.js.map +1 -1
- package/dist/cli/office.d.ts.map +1 -1
- package/dist/cli/office.js +0 -31
- package/dist/cli/office.js.map +1 -1
- package/dist/cli/onboard.d.ts +0 -2
- package/dist/cli/onboard.d.ts.map +1 -1
- package/dist/cli/onboard.js +0 -30
- package/dist/cli/onboard.js.map +1 -1
- package/dist/cli/process-lifecycle.d.ts +0 -5
- package/dist/cli/process-lifecycle.d.ts.map +1 -1
- package/dist/cli/process-lifecycle.js +0 -6
- package/dist/cli/process-lifecycle.js.map +1 -1
- package/dist/cli/sandbox.d.ts +3 -0
- package/dist/cli/sandbox.d.ts.map +1 -0
- package/dist/cli/sandbox.js +79 -0
- package/dist/cli/sandbox.js.map +1 -0
- package/dist/cli/sessions.d.ts.map +1 -1
- package/dist/cli/sessions.js +0 -11
- package/dist/cli/sessions.js.map +1 -1
- package/dist/cli/types.d.ts +2 -6
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/cli/types.js.map +1 -1
- package/dist/env-manifest.d.ts +0 -21
- package/dist/env-manifest.d.ts.map +1 -1
- package/dist/env-manifest.js +0 -11
- package/dist/env-manifest.js.map +1 -1
- package/dist/events/index.d.ts +0 -51
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +0 -42
- package/dist/events/index.js.map +1 -1
- package/dist/events/scheduler.d.ts +0 -8
- package/dist/events/scheduler.d.ts.map +1 -1
- package/dist/events/scheduler.js +0 -8
- package/dist/events/scheduler.js.map +1 -1
- package/dist/file-guards.d.ts +0 -15
- package/dist/file-guards.d.ts.map +1 -1
- package/dist/file-guards.js +2 -26
- package/dist/file-guards.js.map +1 -1
- package/dist/harness/execution-env.d.ts +0 -15
- package/dist/harness/execution-env.d.ts.map +1 -1
- package/dist/harness/execution-env.js +4 -55
- package/dist/harness/execution-env.js.map +1 -1
- package/dist/harness/http.d.ts +0 -12
- package/dist/harness/http.d.ts.map +1 -1
- package/dist/harness/http.js +0 -34
- package/dist/harness/http.js.map +1 -1
- package/dist/harness/index.d.ts +4 -7
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +4 -7
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/jev.d.ts +0 -28
- package/dist/harness/jev.d.ts.map +1 -1
- package/dist/harness/jev.js +0 -45
- package/dist/harness/jev.js.map +1 -1
- package/dist/harness/mcp-result.d.ts +20 -0
- package/dist/harness/mcp-result.d.ts.map +1 -0
- package/dist/harness/mcp-result.js +171 -0
- package/dist/harness/mcp-result.js.map +1 -0
- package/dist/harness/mcp.d.ts +0 -19
- package/dist/harness/mcp.d.ts.map +1 -1
- package/dist/harness/mcp.js +7 -66
- package/dist/harness/mcp.js.map +1 -1
- package/dist/harness/models.d.ts +0 -19
- package/dist/harness/models.d.ts.map +1 -1
- package/dist/harness/models.js +0 -52
- package/dist/harness/models.js.map +1 -1
- package/dist/harness/open-connector.d.ts +0 -12
- package/dist/harness/open-connector.d.ts.map +1 -1
- package/dist/harness/open-connector.js +0 -22
- package/dist/harness/open-connector.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 +16 -66
- package/dist/harness/presenter.js.map +1 -1
- package/dist/harness/prompt.d.ts +0 -11
- package/dist/harness/prompt.d.ts.map +1 -1
- package/dist/harness/prompt.js +1 -18
- package/dist/harness/prompt.js.map +1 -1
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +8 -28
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session.d.ts +11 -28
- package/dist/harness/session.d.ts.map +1 -1
- package/dist/harness/session.js +100 -38
- package/dist/harness/session.js.map +1 -1
- package/dist/harness/skills.d.ts +0 -22
- package/dist/harness/skills.d.ts.map +1 -1
- package/dist/harness/skills.js +0 -20
- package/dist/harness/skills.js.map +1 -1
- package/dist/harness/subagent-profiles.d.ts +0 -4
- package/dist/harness/subagent-profiles.d.ts.map +1 -1
- package/dist/harness/subagent-profiles.js +0 -29
- package/dist/harness/subagent-profiles.js.map +1 -1
- package/dist/harness/subagent.d.ts +0 -25
- package/dist/harness/subagent.d.ts.map +1 -1
- package/dist/harness/subagent.js +1 -70
- package/dist/harness/subagent.js.map +1 -1
- package/dist/harness/tools/event.d.ts.map +1 -1
- package/dist/harness/tools/event.js +0 -9
- package/dist/harness/tools/event.js.map +1 -1
- package/dist/harness/tools/generate-image.d.ts +0 -6
- package/dist/harness/tools/generate-image.d.ts.map +1 -1
- package/dist/harness/tools/generate-image.js.map +1 -1
- package/dist/harness/tools/host-fn-tool.d.ts +0 -17
- package/dist/harness/tools/host-fn-tool.d.ts.map +1 -1
- package/dist/harness/tools/host-fn-tool.js +0 -16
- package/dist/harness/tools/host-fn-tool.js.map +1 -1
- package/dist/harness/tools/index.d.ts +1 -7
- package/dist/harness/tools/index.d.ts.map +1 -1
- package/dist/harness/tools/index.js +3 -14
- package/dist/harness/tools/index.js.map +1 -1
- package/dist/harness/tools/jev-browser.d.ts +4 -94
- package/dist/harness/tools/jev-browser.d.ts.map +1 -1
- package/dist/harness/tools/jev-browser.js +203 -92
- package/dist/harness/tools/jev-browser.js.map +1 -1
- package/dist/harness/tools/jev.d.ts +0 -8
- package/dist/harness/tools/jev.d.ts.map +1 -1
- package/dist/harness/tools/jev.js +0 -11
- package/dist/harness/tools/jev.js.map +1 -1
- package/dist/harness/tools/pi-tools.d.ts +1 -11
- package/dist/harness/tools/pi-tools.d.ts.map +1 -1
- package/dist/harness/tools/pi-tools.js +1 -30
- package/dist/harness/tools/pi-tools.js.map +1 -1
- package/dist/harness/tools/react.d.ts +0 -5
- package/dist/harness/tools/react.d.ts.map +1 -1
- package/dist/harness/tools/react.js +0 -5
- package/dist/harness/tools/react.js.map +1 -1
- package/dist/harness/tools/secret-redaction.d.ts +0 -25
- package/dist/harness/tools/secret-redaction.d.ts.map +1 -1
- package/dist/harness/tools/secret-redaction.js +3 -36
- package/dist/harness/tools/secret-redaction.js.map +1 -1
- package/dist/harness/tools/subagent.d.ts +0 -34
- package/dist/harness/tools/subagent.d.ts.map +1 -1
- package/dist/harness/tools/subagent.js +0 -92
- package/dist/harness/tools/subagent.js.map +1 -1
- package/dist/harness/tools/task.d.ts +0 -1
- package/dist/harness/tools/task.d.ts.map +1 -1
- package/dist/harness/tools/task.js +0 -1
- package/dist/harness/tools/task.js.map +1 -1
- package/dist/harness/tools/types.d.ts +0 -16
- package/dist/harness/tools/types.d.ts.map +1 -1
- package/dist/harness/tools/types.js.map +1 -1
- package/dist/harness/types.d.ts +1 -77
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +1 -1
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js +0 -13
- package/dist/log.js.map +1 -1
- package/dist/main.js +7 -52
- package/dist/main.js.map +1 -1
- package/dist/memory-capture/index.d.ts +16 -0
- package/dist/memory-capture/index.d.ts.map +1 -0
- package/dist/memory-capture/index.js +194 -0
- package/dist/memory-capture/index.js.map +1 -0
- package/dist/memory-capture/types.d.ts +27 -0
- package/dist/memory-capture/types.d.ts.map +1 -0
- package/dist/memory-capture/types.js.map +1 -0
- package/dist/observability/index.d.ts +0 -9
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/index.js +0 -9
- package/dist/observability/index.js.map +1 -1
- package/dist/observability/instrument.js +0 -5
- package/dist/observability/instrument.js.map +1 -1
- package/dist/observability/otel.js +0 -1
- package/dist/observability/otel.js.map +1 -1
- package/dist/observability/sentry.d.ts +0 -18
- package/dist/observability/sentry.d.ts.map +1 -1
- package/dist/observability/sentry.js +0 -36
- package/dist/observability/sentry.js.map +1 -1
- package/dist/observability/types.d.ts +1 -10
- package/dist/observability/types.d.ts.map +1 -1
- package/dist/observability/types.js.map +1 -1
- package/dist/office/index.d.ts +0 -76
- package/dist/office/index.d.ts.map +1 -1
- package/dist/office/index.js +4 -154
- package/dist/office/index.js.map +1 -1
- package/dist/office/projection.d.ts +0 -29
- package/dist/office/projection.d.ts.map +1 -1
- package/dist/office/projection.js +5 -41
- package/dist/office/projection.js.map +1 -1
- package/dist/office/types.d.ts +0 -66
- package/dist/office/types.d.ts.map +1 -1
- package/dist/office/types.js.map +1 -1
- package/dist/runtime/conversation-runtime.d.ts.map +1 -1
- package/dist/runtime/conversation-runtime.js +22 -83
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/session-lifecycle.d.ts +0 -10
- package/dist/runtime/session-lifecycle.d.ts.map +1 -1
- package/dist/runtime/session-lifecycle.js +0 -12
- package/dist/runtime/session-lifecycle.js.map +1 -1
- package/dist/runtime/types.d.ts +2 -29
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/cloudflare.d.ts.map +1 -1
- package/dist/sandbox/cloudflare.js +2 -1
- package/dist/sandbox/cloudflare.js.map +1 -1
- package/dist/sandbox/container.d.ts.map +1 -1
- package/dist/sandbox/container.js +21 -15
- package/dist/sandbox/container.js.map +1 -1
- package/dist/sandbox/host.d.ts.map +1 -1
- package/dist/sandbox/host.js +0 -2
- package/dist/sandbox/host.js.map +1 -1
- package/dist/sandbox/identity.d.ts +0 -28
- package/dist/sandbox/identity.d.ts.map +1 -1
- package/dist/sandbox/identity.js +0 -28
- package/dist/sandbox/identity.js.map +1 -1
- package/dist/sandbox/index.d.ts +0 -18
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +2 -19
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/layout.d.ts +7 -0
- package/dist/sandbox/layout.d.ts.map +1 -0
- package/dist/sandbox/layout.js +13 -0
- package/dist/sandbox/layout.js.map +1 -0
- package/dist/sandbox/provisioner.d.ts +24 -65
- package/dist/sandbox/provisioner.d.ts.map +1 -1
- package/dist/sandbox/provisioner.js +213 -125
- package/dist/sandbox/provisioner.js.map +1 -1
- package/dist/sandbox/types.d.ts +0 -39
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/sandbox/types.js.map +1 -1
- package/dist/sandbox/utils.d.ts +2 -5
- package/dist/sandbox/utils.d.ts.map +1 -1
- package/dist/sandbox/utils.js +31 -31
- package/dist/sandbox/utils.js.map +1 -1
- package/dist/sessions/chat-history-sync.d.ts +0 -6
- package/dist/sessions/chat-history-sync.d.ts.map +1 -1
- package/dist/sessions/chat-history-sync.js +1 -33
- package/dist/sessions/chat-history-sync.js.map +1 -1
- package/dist/sessions/history-line.d.ts +0 -20
- package/dist/sessions/history-line.d.ts.map +1 -1
- package/dist/sessions/history-line.js +0 -20
- package/dist/sessions/history-line.js.map +1 -1
- package/dist/sessions/migrate-common.d.ts +0 -15
- package/dist/sessions/migrate-common.d.ts.map +1 -1
- package/dist/sessions/migrate-common.js +0 -19
- package/dist/sessions/migrate-common.js.map +1 -1
- package/dist/sessions/migrate-pi-084.d.ts.map +1 -1
- package/dist/sessions/migrate-pi-084.js +0 -7
- package/dist/sessions/migrate-pi-084.js.map +1 -1
- package/dist/sessions/migrate-v3.d.ts +0 -7
- package/dist/sessions/migrate-v3.d.ts.map +1 -1
- package/dist/sessions/migrate-v3.js +1 -67
- package/dist/sessions/migrate-v3.js.map +1 -1
- package/dist/sessions/session-key.d.ts +3 -17
- package/dist/sessions/session-key.d.ts.map +1 -1
- package/dist/sessions/session-key.js +8 -35
- package/dist/sessions/session-key.js.map +1 -1
- package/dist/sessions/session-store.d.ts +1 -7
- package/dist/sessions/session-store.d.ts.map +1 -1
- package/dist/sessions/session-store.js +8 -50
- package/dist/sessions/session-store.js.map +1 -1
- package/dist/sessions/store.d.ts +0 -60
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +0 -113
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/types.d.ts +0 -17
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js.map +1 -1
- package/dist/settings/apply.d.ts +0 -6
- package/dist/settings/apply.d.ts.map +1 -1
- package/dist/settings/apply.js +0 -29
- package/dist/settings/apply.js.map +1 -1
- package/dist/settings/index.d.ts +0 -53
- package/dist/settings/index.d.ts.map +1 -1
- package/dist/settings/index.js +0 -77
- package/dist/settings/index.js.map +1 -1
- package/dist/settings/migrate.d.ts +0 -5
- package/dist/settings/migrate.d.ts.map +1 -1
- package/dist/settings/migrate.js +0 -17
- package/dist/settings/migrate.js.map +1 -1
- package/dist/types.d.ts +9 -159
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/vault/index.d.ts +2 -36
- package/dist/vault/index.d.ts.map +1 -1
- package/dist/vault/index.js +135 -65
- package/dist/vault/index.js.map +1 -1
- package/dist/vault/types.d.ts +0 -15
- package/dist/vault/types.d.ts.map +1 -1
- package/dist/vault/types.js.map +1 -1
- package/package.json +1 -1
- package/dist/dream/index.d.ts +0 -20
- package/dist/dream/index.d.ts.map +0 -1
- package/dist/dream/index.js +0 -264
- package/dist/dream/index.js.map +0 -1
- package/dist/dream/types.d.ts +0 -30
- package/dist/dream/types.d.ts.map +0 -1
- package/dist/dream/types.js.map +0 -1
- /package/dist/{dream → memory-capture}/types.js +0 -0
|
@@ -38,13 +38,7 @@ function hasBotIdentity(message) {
|
|
|
38
38
|
}
|
|
39
39
|
const USER_MESSAGE_SUBTYPES = new Set([undefined, "file_share"]);
|
|
40
40
|
const BOT_MESSAGE_SUBTYPES = new Set([...USER_MESSAGE_SUBTYPES, "bot_message"]);
|
|
41
|
-
/**
|
|
42
|
-
* Slack's per-call limit on `markdown_text`: "Limit this field to 12,000
|
|
43
|
-
* characters." mikan allows far more in a message, so streamed text is split
|
|
44
|
-
* to fit rather than truncated.
|
|
45
|
-
*/
|
|
46
41
|
const MAX_STREAM_TEXT_CHARS = 12_000;
|
|
47
|
-
/** Slices `text` into pieces that each fit one streaming call. */
|
|
48
42
|
export function chunkStreamText(text, limit = MAX_STREAM_TEXT_CHARS) {
|
|
49
43
|
if (text.length <= limit)
|
|
50
44
|
return [text];
|
|
@@ -54,8 +48,6 @@ export function chunkStreamText(text, limit = MAX_STREAM_TEXT_CHARS) {
|
|
|
54
48
|
}
|
|
55
49
|
return chunks;
|
|
56
50
|
}
|
|
57
|
-
// web-api v8 throws WebAPIRateLimitedError; the duck-typed shapes cover
|
|
58
|
-
// platform `data.error === "rate_limited"` / 429 responses and older callers.
|
|
59
51
|
function slackIsRateLimited(err) {
|
|
60
52
|
if (err instanceof WebAPIRateLimitedError)
|
|
61
53
|
return true;
|
|
@@ -97,23 +89,13 @@ function buildSlackAppMessageText(event) {
|
|
|
97
89
|
const deduped = parts.filter((part, index) => parts.indexOf(part) === index);
|
|
98
90
|
return deduped.join("\n");
|
|
99
91
|
}
|
|
100
|
-
// ---------------------------------------------------------------------------
|
|
101
|
-
// Shared mrkdwn truncation helper
|
|
102
|
-
// ---------------------------------------------------------------------------
|
|
103
92
|
const MRKDWN_CONTEXT_TEXT_LIMIT = 3000;
|
|
104
|
-
/**
|
|
105
|
-
* Build a Slack context block whose text is capped at the mrkdwn limit.
|
|
106
|
-
* Used for muted diagnostics and ephemeral command responses.
|
|
107
|
-
*/
|
|
108
93
|
export function buildMrkdwnContextBlock(text) {
|
|
109
94
|
const blockText = text.length > MRKDWN_CONTEXT_TEXT_LIMIT
|
|
110
95
|
? text.substring(0, MRKDWN_CONTEXT_TEXT_LIMIT - 20) + "\n_(truncated)_"
|
|
111
96
|
: text;
|
|
112
97
|
return { type: "context", elements: [{ type: "mrkdwn", text: blockText }] };
|
|
113
98
|
}
|
|
114
|
-
// ============================================================================
|
|
115
|
-
// SlackMessagingBot
|
|
116
|
-
// ============================================================================
|
|
117
99
|
class AttachmentDownloadHttpError extends Error {
|
|
118
100
|
constructor(message, status) {
|
|
119
101
|
super(message);
|
|
@@ -126,7 +108,6 @@ function isRetryableAttachmentDownloadError(error) {
|
|
|
126
108
|
return error.status === 408 || error.status === 429 || error.status >= 500;
|
|
127
109
|
}
|
|
128
110
|
export class SlackMessagingBot {
|
|
129
|
-
/** Host office dir for a Slack conversation. */
|
|
130
111
|
conversationDir(channelId) {
|
|
131
112
|
return this.workspace.office(createOfficeAddress("slack", channelId)).dir;
|
|
132
113
|
}
|
|
@@ -222,17 +203,10 @@ export class SlackMessagingBot {
|
|
|
222
203
|
this.botId = null;
|
|
223
204
|
this.teamId = null;
|
|
224
205
|
this.ownMentionRegex = null;
|
|
225
|
-
this.startupTs = null;
|
|
206
|
+
this.startupTs = null;
|
|
226
207
|
this.users = new Map();
|
|
227
208
|
this.channels = new Map();
|
|
228
|
-
/** Which threads belong to the assistant pane, and their last known context. */
|
|
229
209
|
this.assistantThreads = new AssistantThreadRegistry();
|
|
230
|
-
/**
|
|
231
|
-
* Native response streams opened recently. Per bot rather than per module:
|
|
232
|
-
* the rate tier applies per workspace, and this bot is the connection to
|
|
233
|
-
* one — which also means a test constructing a bot gets a fresh budget
|
|
234
|
-
* instead of inheriting whatever ran before it.
|
|
235
|
-
*/
|
|
236
210
|
this.streamStarts = new StreamStartLimiter();
|
|
237
211
|
this.stopped = false;
|
|
238
212
|
this.queues = new Map();
|
|
@@ -243,8 +217,6 @@ export class SlackMessagingBot {
|
|
|
243
217
|
this.botToken = config.botToken;
|
|
244
218
|
this.socketClient = new SocketModeClient({
|
|
245
219
|
appToken: config.appToken,
|
|
246
|
-
// Default 5s is too tight: brief event-loop stalls (e.g. backfill, sync fs)
|
|
247
|
-
// cause false pong timeouts; 4 in a row makes Slack drop the socket.
|
|
248
220
|
clientPingTimeout: 12_000,
|
|
249
221
|
});
|
|
250
222
|
this.webClient = new WebClient(config.botToken);
|
|
@@ -257,9 +229,6 @@ export class SlackMessagingBot {
|
|
|
257
229
|
setEventScheduler(scheduler) {
|
|
258
230
|
this.eventScheduler = scheduler;
|
|
259
231
|
}
|
|
260
|
-
// ==========================================================================
|
|
261
|
-
// Public API
|
|
262
|
-
// ==========================================================================
|
|
263
232
|
async start() {
|
|
264
233
|
this.stopped = false;
|
|
265
234
|
const auth = await this.webClient.auth.test();
|
|
@@ -271,9 +240,6 @@ export class SlackMessagingBot {
|
|
|
271
240
|
return;
|
|
272
241
|
log.logInfo(`Loaded ${this.channels.size} channels, ${this.users.size} users`);
|
|
273
242
|
this.backfillChannelKinds();
|
|
274
|
-
// Record startup time before opening the socket. Slack may replay older events;
|
|
275
|
-
// those should be logged but not processed. Backfill runs in the background up
|
|
276
|
-
// to this timestamp so startup is not blocked by one history call per channel.
|
|
277
243
|
this.startupTs = (Date.now() / 1000).toFixed(6);
|
|
278
244
|
this.setupEventHandlers();
|
|
279
245
|
await this.socketClient.start();
|
|
@@ -313,11 +279,6 @@ export class SlackMessagingBot {
|
|
|
313
279
|
}
|
|
314
280
|
return source.replace(this.ownMentionRegex, "").trim();
|
|
315
281
|
}
|
|
316
|
-
/**
|
|
317
|
-
* Response-source `<@userName>` mentions become native `<@U…>` here — the
|
|
318
|
-
* one conversion every outgoing response path funnels through. Slack only
|
|
319
|
-
* links and notifies on raw user ids.
|
|
320
|
-
*/
|
|
321
282
|
resolveMentions(text) {
|
|
322
283
|
return resolveSlackMentions(text, this.users.values());
|
|
323
284
|
}
|
|
@@ -334,14 +295,12 @@ export class SlackMessagingBot {
|
|
|
334
295
|
});
|
|
335
296
|
}
|
|
336
297
|
async addReaction(channel, messageTs, emoji) {
|
|
337
|
-
// Slack reaction names are colon-free short names; strip any wrapping colons.
|
|
338
298
|
const name = emoji.replace(/^:|:$/g, "");
|
|
339
299
|
await slackRetry(async () => {
|
|
340
300
|
try {
|
|
341
301
|
await this.webClient.reactions.add({ channel, timestamp: messageTs, name });
|
|
342
302
|
}
|
|
343
303
|
catch (err) {
|
|
344
|
-
// Re-reacting with the same emoji is not an error worth surfacing.
|
|
345
304
|
if (err?.data?.error === "already_reacted")
|
|
346
305
|
return;
|
|
347
306
|
throw err;
|
|
@@ -399,13 +358,6 @@ export class SlackMessagingBot {
|
|
|
399
358
|
return channelId;
|
|
400
359
|
});
|
|
401
360
|
}
|
|
402
|
-
/**
|
|
403
|
-
* Fetch recent messages from a channel, oldest first. Without `threadTs`
|
|
404
|
-
* this is one `conversations.history` page of top-level messages (thread
|
|
405
|
-
* replies are not expanded); with it, one `conversations.replies` page of
|
|
406
|
-
* that thread's replies, excluding the parent. Callers page forward by
|
|
407
|
-
* passing the last returned `ts` as `oldest`.
|
|
408
|
-
*/
|
|
409
361
|
async fetchHistory(channel, options) {
|
|
410
362
|
const limit = Math.min(Math.max(options?.limit ?? 200, 1), 999);
|
|
411
363
|
const threadTs = options?.threadTs;
|
|
@@ -425,9 +377,6 @@ export class SlackMessagingBot {
|
|
|
425
377
|
const messages = (result.messages ?? []);
|
|
426
378
|
const mapped = messages
|
|
427
379
|
.filter((msg) => !!msg.ts)
|
|
428
|
-
// conversations.replies leads with the thread parent; the caller asked
|
|
429
|
-
// for the replies to it, and including it would re-ingest the bot's
|
|
430
|
-
// own message on every poll.
|
|
431
380
|
.filter((msg) => msg.ts !== threadTs)
|
|
432
381
|
.map((msg) => {
|
|
433
382
|
const user = msg.user ? this.users.get(msg.user) : undefined;
|
|
@@ -444,12 +393,9 @@ export class SlackMessagingBot {
|
|
|
444
393
|
message.userName = user.userName;
|
|
445
394
|
return message;
|
|
446
395
|
});
|
|
447
|
-
// history returns newest-first, replies oldest-first; the contract is
|
|
448
|
-
// oldest-first either way.
|
|
449
396
|
return threadTs ? mapped : mapped.toReversed();
|
|
450
397
|
});
|
|
451
398
|
}
|
|
452
|
-
/** Refresh and list the workspace's active users (`users.list`). */
|
|
453
399
|
async listUsers() {
|
|
454
400
|
await slackRetry(() => this.fetchUsers());
|
|
455
401
|
return this.getAllUsers().map((user) => ({
|
|
@@ -472,28 +418,9 @@ export class SlackMessagingBot {
|
|
|
472
418
|
recordSlackUpdate(this, { channel, ts }, text, payload, { success: true });
|
|
473
419
|
});
|
|
474
420
|
}
|
|
475
|
-
/**
|
|
476
|
-
* Claim one native stream, or decline. Declining is not an error: the caller
|
|
477
|
-
* falls back to edit-based updates, which is a working answer rather than a
|
|
478
|
-
* degraded one, and costs no request against the tighter start tier.
|
|
479
|
-
*/
|
|
480
421
|
tryReserveStreamStart() {
|
|
481
422
|
return this.streamStarts.tryReserve();
|
|
482
423
|
}
|
|
483
|
-
/**
|
|
484
|
-
* Open a stream, carrying text of any length.
|
|
485
|
-
*
|
|
486
|
-
* Slack caps `markdown_text` at 12,000 characters per call, and a long first
|
|
487
|
-
* render exceeds that easily — mikan allows 35,000 in a message. Rather than
|
|
488
|
-
* truncating (losing the answer) or failing (falling back to edit mode for
|
|
489
|
-
* the whole response), the opening call takes the first slice and the rest
|
|
490
|
-
* follows as appends before this resolves. The caller sees one operation
|
|
491
|
-
* that sent everything, so the renderer's idea of what has been streamed
|
|
492
|
-
* stays true.
|
|
493
|
-
*
|
|
494
|
-
* Splitting mid-word or mid-fence is harmless here: a stream concatenates,
|
|
495
|
-
* so Slack renders the reassembled text, not the pieces.
|
|
496
|
-
*/
|
|
497
424
|
async startMessageStream(channel, text, threadTs, recipientUserId) {
|
|
498
425
|
const [head, ...tail] = chunkStreamText(text);
|
|
499
426
|
const ts = await slackRetry(async () => {
|
|
@@ -513,7 +440,6 @@ export class SlackMessagingBot {
|
|
|
513
440
|
await this.appendStreamChunk(channel, ts, part);
|
|
514
441
|
return ts;
|
|
515
442
|
}
|
|
516
|
-
/** Append a delta of any length, split to the per-call cap. */
|
|
517
443
|
async appendMessageStream(channel, ts, text) {
|
|
518
444
|
for (const part of chunkStreamText(text)) {
|
|
519
445
|
await this.appendStreamChunk(channel, ts, part);
|
|
@@ -524,8 +450,6 @@ export class SlackMessagingBot {
|
|
|
524
450
|
await this.webClient.apiCall("chat.appendStream", {
|
|
525
451
|
channel,
|
|
526
452
|
ts,
|
|
527
|
-
// A mention split across stream deltas stays unresolved here; the
|
|
528
|
-
// canonical final render (updateMessage) resolves the full text.
|
|
529
453
|
markdown_text: this.resolveMentions(text),
|
|
530
454
|
});
|
|
531
455
|
});
|
|
@@ -540,10 +464,6 @@ export class SlackMessagingBot {
|
|
|
540
464
|
await this.webClient.chat.delete({ channel, ts });
|
|
541
465
|
});
|
|
542
466
|
}
|
|
543
|
-
// ==========================================================================
|
|
544
|
-
// Slack Assistant API (AI assistant experience)
|
|
545
|
-
// ==========================================================================
|
|
546
|
-
/** Set the status for an assistant thread (shows "thinking" state) */
|
|
547
467
|
async setAssistantStatus(channel, threadTs, status) {
|
|
548
468
|
const key = `${channel}:${threadTs}`;
|
|
549
469
|
const previous = this.statusUpdates.get(key) ?? Promise.resolve();
|
|
@@ -565,11 +485,8 @@ export class SlackMessagingBot {
|
|
|
565
485
|
this.statusUpdates.delete(key);
|
|
566
486
|
}
|
|
567
487
|
}
|
|
568
|
-
/** Offer starting points in a new assistant thread. */
|
|
569
488
|
async setAssistantSuggestedPrompts(channel, threadTs, prompts) {
|
|
570
489
|
return slackRetry(async () => {
|
|
571
|
-
// Omitting thread_ts pins the prompts to the DM itself, which is what
|
|
572
|
-
// the agent surface wants: there is no thread yet when it opens.
|
|
573
490
|
await this.webClient.assistant.threads.setSuggestedPrompts({
|
|
574
491
|
channel_id: channel,
|
|
575
492
|
...(threadTs ? { thread_ts: threadTs } : {}),
|
|
@@ -577,7 +494,6 @@ export class SlackMessagingBot {
|
|
|
577
494
|
});
|
|
578
495
|
});
|
|
579
496
|
}
|
|
580
|
-
/** Name an assistant thread, which is what the sidebar conversation list shows. */
|
|
581
497
|
async setAssistantTitle(channel, threadTs, title) {
|
|
582
498
|
return slackRetry(async () => {
|
|
583
499
|
await this.webClient.assistant.threads.setTitle({
|
|
@@ -587,7 +503,6 @@ export class SlackMessagingBot {
|
|
|
587
503
|
});
|
|
588
504
|
});
|
|
589
505
|
}
|
|
590
|
-
/** The assistant surface's view of this bot, handed to the lifecycle handlers. */
|
|
591
506
|
assistantOps() {
|
|
592
507
|
return {
|
|
593
508
|
postInThread: (channel, threadTs, text) => this.postInThread(channel, threadTs, text),
|
|
@@ -596,10 +511,6 @@ export class SlackMessagingBot {
|
|
|
596
511
|
channelName: (channelId) => this.channels.get(channelId)?.name,
|
|
597
512
|
};
|
|
598
513
|
}
|
|
599
|
-
/**
|
|
600
|
-
* A new conversation opened in the assistant pane. Slack waits for the app
|
|
601
|
-
* to speak first here; staying silent is what makes the pane look broken.
|
|
602
|
-
*/
|
|
603
514
|
handleAssistantThreadStarted({ event, ack }) {
|
|
604
515
|
ack();
|
|
605
516
|
const payload = event;
|
|
@@ -607,12 +518,6 @@ export class SlackMessagingBot {
|
|
|
607
518
|
return;
|
|
608
519
|
void handleAssistantThreadStarted(this.assistantOps(), this.assistantThreads, payload.assistant_thread);
|
|
609
520
|
}
|
|
610
|
-
/**
|
|
611
|
-
* The person navigated to another channel while the pane is open. Slack
|
|
612
|
-
* sends this as `assistant_thread_context_changed` under `assistant_view`
|
|
613
|
-
* and `app_context_changed` under `agent_view`; the payload differs enough
|
|
614
|
-
* to normalize here rather than in the handler.
|
|
615
|
-
*/
|
|
616
521
|
handleAgentContextChangedEvent({ event, ack, }) {
|
|
617
522
|
ack();
|
|
618
523
|
const payload = event;
|
|
@@ -695,17 +600,10 @@ export class SlackMessagingBot {
|
|
|
695
600
|
},
|
|
696
601
|
};
|
|
697
602
|
}
|
|
698
|
-
// ==========================================================================
|
|
699
|
-
// Events Integration
|
|
700
|
-
// ==========================================================================
|
|
701
|
-
/**
|
|
702
|
-
* Enqueue an event for processing. Always queues (no "already working" rejection).
|
|
703
|
-
* Returns true if enqueued, false if queue is full (max 5).
|
|
704
|
-
*/
|
|
705
603
|
enqueueEvent(event) {
|
|
706
604
|
if (this.stopped)
|
|
707
605
|
return false;
|
|
708
|
-
const conversationId = event.conversationId;
|
|
606
|
+
const conversationId = event.address.conversationId;
|
|
709
607
|
const queue = this.getQueue(conversationId);
|
|
710
608
|
if (queue.size() >= 5) {
|
|
711
609
|
log.logWarning(`Event queue full for ${conversationId}, discarding: ${event.text.substring(0, 50)}`);
|
|
@@ -775,9 +673,6 @@ export class SlackMessagingBot {
|
|
|
775
673
|
}
|
|
776
674
|
});
|
|
777
675
|
}
|
|
778
|
-
// ==========================================================================
|
|
779
|
-
// Private - Event Handlers
|
|
780
|
-
// ==========================================================================
|
|
781
676
|
getQueue(channelId) {
|
|
782
677
|
let queue = this.queues.get(channelId);
|
|
783
678
|
if (!queue) {
|
|
@@ -815,14 +710,6 @@ export class SlackMessagingBot {
|
|
|
815
710
|
sessionKey,
|
|
816
711
|
});
|
|
817
712
|
}
|
|
818
|
-
/**
|
|
819
|
-
* Slack's own conversation vocabulary for this channel, from the metadata
|
|
820
|
-
* fetchChannels() already loads. Externally shared channels report
|
|
821
|
-
* "external" regardless of privacy — platform-public within one workspace
|
|
822
|
-
* is the sharing condition, and a channel visible to another organization
|
|
823
|
-
* does not satisfy it. Unknown channels return undefined (never recorded,
|
|
824
|
-
* so the projection keeps its isolated default).
|
|
825
|
-
*/
|
|
826
713
|
channelKindFor(channelId) {
|
|
827
714
|
if (channelId.startsWith("D"))
|
|
828
715
|
return "im";
|
|
@@ -839,13 +726,6 @@ export class SlackMessagingBot {
|
|
|
839
726
|
return "public_channel";
|
|
840
727
|
return undefined;
|
|
841
728
|
}
|
|
842
|
-
/**
|
|
843
|
-
* Office visibility follows the recorded channel kind, and an unrecorded
|
|
844
|
-
* kind fails closed to private (ADR 0008). Offices created before kinds
|
|
845
|
-
* were recorded would therefore lose public status until their next
|
|
846
|
-
* message; the channel list loaded at startup already knows every kind, so
|
|
847
|
-
* record it for all registered Slack offices now. Metadata only.
|
|
848
|
-
*/
|
|
849
729
|
backfillChannelKinds() {
|
|
850
730
|
let recorded = 0;
|
|
851
731
|
for (const record of listRegisteredOffices(this.workspace.stateDir)) {
|
|
@@ -869,14 +749,12 @@ export class SlackMessagingBot {
|
|
|
869
749
|
log.logInfo(`Recorded channel kind for ${recorded} Slack offices`);
|
|
870
750
|
}
|
|
871
751
|
processSlackMessageIntake(options) {
|
|
872
|
-
const kind = this.channelKindFor(options.event.conversationId);
|
|
752
|
+
const kind = this.channelKindFor(options.event.address.conversationId);
|
|
873
753
|
if (kind) {
|
|
874
754
|
try {
|
|
875
755
|
recordPlatformChannelKind(this.workspace.office(options.event.address), kind);
|
|
876
756
|
}
|
|
877
757
|
catch (err) {
|
|
878
|
-
// A failed snapshot must not block the message; the projection just
|
|
879
|
-
// keeps its previous (or isolated default) posture.
|
|
880
758
|
log.logWarning("Failed to record Slack channel kind", String(err));
|
|
881
759
|
}
|
|
882
760
|
}
|
|
@@ -902,8 +780,6 @@ export class SlackMessagingBot {
|
|
|
902
780
|
createContext: (event) => this.createContext(event),
|
|
903
781
|
deferAttachmentsUntilRun: true,
|
|
904
782
|
}).then((outcome) => {
|
|
905
|
-
// Slack logs eagerly via logUserMessage; when intake does not enqueue,
|
|
906
|
-
// nothing awaits the attachment download, so absorb its failure here.
|
|
907
783
|
if (outcome !== "enqueued")
|
|
908
784
|
absorbAttachmentFailure();
|
|
909
785
|
}, (err) => {
|
|
@@ -958,7 +834,6 @@ export class SlackMessagingBot {
|
|
|
958
834
|
{
|
|
959
835
|
type: "button",
|
|
960
836
|
text: { type: "plain_text", text: "Force Stop", emoji: true },
|
|
961
|
-
// `value` preserves the raw key; action_id is only a unique route.
|
|
962
837
|
action_id: `force_stop_${session.sessionKey.replace(/:/g, "_")}`,
|
|
963
838
|
value: session.sessionKey,
|
|
964
839
|
style: "danger",
|
|
@@ -968,10 +843,6 @@ export class SlackMessagingBot {
|
|
|
968
843
|
}
|
|
969
844
|
}
|
|
970
845
|
}
|
|
971
|
-
/**
|
|
972
|
-
* Scheduled jobs of the opener's own DM office only: the App Home is a
|
|
973
|
-
* personal surface, so other offices' schedules are not listed here.
|
|
974
|
-
*/
|
|
975
846
|
appendScheduledJobs(blocks, dmChannelId) {
|
|
976
847
|
const periodicEvents = dmChannelId && this.eventScheduler
|
|
977
848
|
? this.eventScheduler.periodicEvents(createOfficeAddress("slack", dmChannelId))
|
|
@@ -1043,9 +914,6 @@ export class SlackMessagingBot {
|
|
|
1043
914
|
platform: "slack",
|
|
1044
915
|
conversationId,
|
|
1045
916
|
id: ts,
|
|
1046
|
-
// One session identity per dispatch: the caller's thread-resolved key.
|
|
1047
|
-
// Defaulting to the top-level conversation here while the event carried
|
|
1048
|
-
// a thread key made the same run answer to two different sessions.
|
|
1049
917
|
sessionKey: options.sessionKey ?? conversationId,
|
|
1050
918
|
conversationKind: options.ephemeralChannelId ? "shared" : "direct",
|
|
1051
919
|
userId,
|
|
@@ -1137,12 +1005,6 @@ export class SlackMessagingBot {
|
|
|
1137
1005
|
});
|
|
1138
1006
|
return { event, context };
|
|
1139
1007
|
}
|
|
1140
|
-
/**
|
|
1141
|
-
* Generic slash-command route: synthesize the command text per the
|
|
1142
|
-
* manifest's SlackSlashRoute data and dispatch to the handler. Every
|
|
1143
|
-
* routed command — including `/pi-new` — reaches its CommandHandler
|
|
1144
|
-
* through runtime dispatch; the adapter holds no per-command behavior.
|
|
1145
|
-
*/
|
|
1146
1008
|
async routeSlashCommand(route, payload) {
|
|
1147
1009
|
const { event, context } = this.buildSlashCommandEvent(payload, {
|
|
1148
1010
|
includeText: route.includeText,
|
|
@@ -1179,16 +1041,12 @@ export class SlackMessagingBot {
|
|
|
1179
1041
|
this.socketClient.on("app_home_opened", (payload) => {
|
|
1180
1042
|
void this.intake.run(() => this.handleAppHomeOpened(payload));
|
|
1181
1043
|
});
|
|
1182
|
-
// The assistant surface's lifecycle. Both events were already subscribed
|
|
1183
|
-
// in the app manifest and then dropped on the floor, which is why the pane
|
|
1184
|
-
// opened empty and the sidebar filled with untitled conversations.
|
|
1185
1044
|
this.socketClient.on("assistant_thread_started", (payload) => {
|
|
1186
1045
|
void this.intake.run(() => this.handleAssistantThreadStarted(payload));
|
|
1187
1046
|
});
|
|
1188
1047
|
this.socketClient.on("assistant_thread_context_changed", (payload) => {
|
|
1189
1048
|
void this.intake.run(() => this.handleAgentContextChangedEvent(payload));
|
|
1190
1049
|
});
|
|
1191
|
-
// agent_view's spelling of the same signal.
|
|
1192
1050
|
this.socketClient.on("app_context_changed", (payload) => {
|
|
1193
1051
|
void this.intake.run(() => this.handleAgentContextChangedEvent(payload));
|
|
1194
1052
|
});
|
|
@@ -1201,13 +1059,10 @@ export class SlackMessagingBot {
|
|
|
1201
1059
|
}
|
|
1202
1060
|
async handleAppMention({ event, ack, }) {
|
|
1203
1061
|
const e = event;
|
|
1204
|
-
// Skip DMs (handled by message event)
|
|
1205
1062
|
if (e.channel.startsWith("D")) {
|
|
1206
1063
|
ack();
|
|
1207
1064
|
return;
|
|
1208
1065
|
}
|
|
1209
|
-
// Top-level mentions use a persistent channel session.
|
|
1210
|
-
// Thread replies get their own isolated session (channelId:thread_ts).
|
|
1211
1066
|
const sessionKey = resolveSlackSessionKey(e.channel, e.thread_ts);
|
|
1212
1067
|
const mentionText = this.stripOwnMention(e.text);
|
|
1213
1068
|
const slackEvent = createConversationEvent({
|
|
@@ -1224,7 +1079,6 @@ export class SlackMessagingBot {
|
|
|
1224
1079
|
files: e.files,
|
|
1225
1080
|
});
|
|
1226
1081
|
const attachmentsPromise = this.logUserMessage(slackEvent);
|
|
1227
|
-
// Only trigger processing for messages AFTER startup (not replayed old messages)
|
|
1228
1082
|
if (this.startupTs && e.ts < this.startupTs) {
|
|
1229
1083
|
log.logInfo(`[${e.channel}] Logged old message (pre-startup), not triggering: ${slackEvent.text.substring(0, 30)}`);
|
|
1230
1084
|
void attachmentsPromise.catch((err) => {
|
|
@@ -1249,8 +1103,6 @@ export class SlackMessagingBot {
|
|
|
1249
1103
|
ack();
|
|
1250
1104
|
return false;
|
|
1251
1105
|
}
|
|
1252
|
-
// User-token posts carry bot_id/app_id beside the human user. Only unknown
|
|
1253
|
-
// authors and known bot users take the external-bot loop-protection path.
|
|
1254
1106
|
const authorIsKnownHuman = !!event.user && this.users.get(event.user)?.isBot === false;
|
|
1255
1107
|
const isExternalMessage = event.subtype === "bot_message" || (!!event.bot_id && !authorIsKnownHuman);
|
|
1256
1108
|
if (isExternalMessage) {
|
|
@@ -1269,13 +1121,6 @@ export class SlackMessagingBot {
|
|
|
1269
1121
|
ack();
|
|
1270
1122
|
return false;
|
|
1271
1123
|
}
|
|
1272
|
-
/**
|
|
1273
|
-
* Handle a DM message that may be about a background task without spending
|
|
1274
|
-
* a model turn: a pure status question is answered from observation, and a
|
|
1275
|
-
* supplement is steered into the running task. Jev decides which (falling
|
|
1276
|
-
* back to the regex status shortcut); anything else returns false so the
|
|
1277
|
-
* message becomes an ordinary conversation turn.
|
|
1278
|
-
*/
|
|
1279
1124
|
async deliverTaskUpdate(event, attachmentsPromise) {
|
|
1280
1125
|
if (matchMagicWord(event.text) === "stop" || event.text.startsWith("/"))
|
|
1281
1126
|
return false;
|
|
@@ -1290,8 +1135,6 @@ export class SlackMessagingBot {
|
|
|
1290
1135
|
return false;
|
|
1291
1136
|
const active = tasks.filter((t) => t.status === "running" || t.status === "stopping");
|
|
1292
1137
|
const user = this.users.get(event.user);
|
|
1293
|
-
// A message carrying files is never a pure status question; in a task
|
|
1294
|
-
// thread it is a supplement, at top level an ordinary turn.
|
|
1295
1138
|
const intent = event.attachments?.length
|
|
1296
1139
|
? event.thread_ts
|
|
1297
1140
|
? "steer"
|
|
@@ -1312,8 +1155,6 @@ export class SlackMessagingBot {
|
|
|
1312
1155
|
return true;
|
|
1313
1156
|
}
|
|
1314
1157
|
if (intent === "steer") {
|
|
1315
|
-
// In a thread the message already targets that task; at top level it
|
|
1316
|
-
// can only be steered when exactly one task is running.
|
|
1317
1158
|
const target = event.thread_ts
|
|
1318
1159
|
? context.message
|
|
1319
1160
|
: active.length === 1
|
|
@@ -1337,17 +1178,6 @@ export class SlackMessagingBot {
|
|
|
1337
1178
|
}
|
|
1338
1179
|
return false;
|
|
1339
1180
|
}
|
|
1340
|
-
/**
|
|
1341
|
-
* Ask Jev a single typed yes/no question about whether this unaddressed
|
|
1342
|
-
* shared-channel message (top-level or thread reply) addresses mikan. The
|
|
1343
|
-
* scored state carries the surrounding scope from log.jsonl, since a bare
|
|
1344
|
-
* thread reply cannot be judged from its own text. Only called in `jev`
|
|
1345
|
-
* auto-reply mode, and only awaited by the caller in that mode, so
|
|
1346
|
-
* `on`/`off` stay synchronous (magic-word `stop` handling depends on that).
|
|
1347
|
-
* Any failure (including a missing `OPENROUTER_API_KEY`) fails closed to
|
|
1348
|
-
* "not addressed" so a misconfiguration cannot make the bot noisy in a
|
|
1349
|
-
* shared channel.
|
|
1350
|
-
*/
|
|
1351
1181
|
async evaluateJevAddressed(event) {
|
|
1352
1182
|
if (!event.text.trim() || matchMagicWord(event.text) === "stop")
|
|
1353
1183
|
return false;
|
|
@@ -1373,7 +1203,7 @@ export class SlackMessagingBot {
|
|
|
1373
1203
|
surface: "slack_auto_reply_jev",
|
|
1374
1204
|
operation: "evaluate",
|
|
1375
1205
|
severity: "warning",
|
|
1376
|
-
context: { conversationId: event.conversationId },
|
|
1206
|
+
context: { conversationId: event.address.conversationId },
|
|
1377
1207
|
});
|
|
1378
1208
|
return false;
|
|
1379
1209
|
}
|
|
@@ -1382,22 +1212,14 @@ export class SlackMessagingBot {
|
|
|
1382
1212
|
const e = event;
|
|
1383
1213
|
if (!this.admitHumanMessage(e, ack))
|
|
1384
1214
|
return;
|
|
1385
|
-
// message.im normally carries channel_type "im", but fall back to the
|
|
1386
|
-
// D-prefix convention (used by handleAppMention and session keys) so a
|
|
1387
|
-
// missing channel_type cannot silently classify a DM as an unaddressed
|
|
1388
|
-
// channel message that never triggers.
|
|
1389
1215
|
const isDM = e.channel_type === "im" || e.channel.startsWith("D");
|
|
1390
1216
|
const conversationKind = isDM ? "direct" : "shared";
|
|
1391
1217
|
const isMessagingBotMention = e.text?.includes(`<@${this.botUserId}>`);
|
|
1392
|
-
// Skip channel @mentions - already handled by app_mention event
|
|
1393
1218
|
if (!isDM && isMessagingBotMention) {
|
|
1394
1219
|
ack();
|
|
1395
1220
|
return;
|
|
1396
1221
|
}
|
|
1397
1222
|
const sessionKey = isDM ? resolveSlackSessionKey(e.channel, e.thread_ts) : undefined;
|
|
1398
|
-
// Name the conversation from the first thing the person said. Guarded on
|
|
1399
|
-
// the assistant registry, so classic DM threads are untouched, and it
|
|
1400
|
-
// claims the title once per thread.
|
|
1401
1223
|
if (isDM && e.thread_ts && e.text) {
|
|
1402
1224
|
void titleAssistantThread(this.assistantOps(), this.assistantThreads, e.channel, e.thread_ts, this.stripOwnMention(e.text));
|
|
1403
1225
|
}
|
|
@@ -1415,7 +1237,6 @@ export class SlackMessagingBot {
|
|
|
1415
1237
|
files: e.files,
|
|
1416
1238
|
});
|
|
1417
1239
|
const attachmentsPromise = this.logUserMessage(slackEvent);
|
|
1418
|
-
// Only trigger processing for messages AFTER startup (not replayed old messages)
|
|
1419
1240
|
if (this.startupTs && e.ts < this.startupTs) {
|
|
1420
1241
|
log.logInfo(`[${e.channel}] Skipping old message (pre-startup): ${slackEvent.text.substring(0, 30)}`);
|
|
1421
1242
|
void attachmentsPromise.catch((err) => {
|
|
@@ -1426,10 +1247,6 @@ export class SlackMessagingBot {
|
|
|
1426
1247
|
}
|
|
1427
1248
|
const activeSessionKey = slackEvent.sessionKey ?? resolveSlackSessionKey(e.channel, e.thread_ts);
|
|
1428
1249
|
slackEvent.sessionKey = activeSessionKey;
|
|
1429
|
-
// Task threads always go through the task gate. Top-level DMs do only
|
|
1430
|
-
// while a task is running (so supplements can be steered) or when the
|
|
1431
|
-
// regex already recognises a status question about a finished one, so
|
|
1432
|
-
// idle DMs never pay a Jev round-trip.
|
|
1433
1250
|
const taskControl = isDM &&
|
|
1434
1251
|
(e.thread_ts
|
|
1435
1252
|
? this.isTaskThread(e.channel, e.thread_ts)
|
|
@@ -1439,9 +1256,6 @@ export class SlackMessagingBot {
|
|
|
1439
1256
|
if (await this.deliverTaskUpdate(slackEvent, attachmentsPromise))
|
|
1440
1257
|
return;
|
|
1441
1258
|
}
|
|
1442
|
-
// Shared-channel messages without a mention, top-level or in a thread,
|
|
1443
|
-
// all go through the same auto-reply gate; jev mode sees the surrounding
|
|
1444
|
-
// scope so thread follow-ups are judged in context rather than dropped.
|
|
1445
1259
|
const autoReplyMode = isDM
|
|
1446
1260
|
? "off"
|
|
1447
1261
|
: slackConversationAutoReplyMode(this.workspace.office(slackEvent.address));
|
|
@@ -1490,10 +1304,6 @@ export class SlackMessagingBot {
|
|
|
1490
1304
|
handleAppHomeOpened({ event, ack }) {
|
|
1491
1305
|
const e = event;
|
|
1492
1306
|
ack();
|
|
1493
|
-
// Under agent_view this is how Slack says "the person opened the app's
|
|
1494
|
-
// DM" — the signal assistant_thread_started used to carry. It fires on
|
|
1495
|
-
// every open, not once per conversation, so this path refreshes the
|
|
1496
|
-
// pinned prompts and deliberately does not greet.
|
|
1497
1307
|
if (e.tab === "messages") {
|
|
1498
1308
|
if (e.channel) {
|
|
1499
1309
|
void handleAgentDmOpened(this.assistantOps(), this.assistantThreads, e.channel, e.context);
|
|
@@ -1523,18 +1333,12 @@ export class SlackMessagingBot {
|
|
|
1523
1333
|
return;
|
|
1524
1334
|
}
|
|
1525
1335
|
ack();
|
|
1526
|
-
// Prefer the verbatim key from `value`; the action_id fallback only
|
|
1527
|
-
// serves buttons rendered before `value` existed and misdecodes session
|
|
1528
|
-
// keys whose conversation id contains "_".
|
|
1529
1336
|
const sessionKey = action.value ?? action.action_id.replace("force_stop_", "").replace(/_/g, ":");
|
|
1530
1337
|
const userId = body.user?.id;
|
|
1531
1338
|
const channelId = body.container?.channel_id || conversationIdOf(sessionKey);
|
|
1532
1339
|
log.logInfo(`[Force Stop] User ${userId} requested force stop for ${sessionKey}`);
|
|
1533
|
-
// Use handler's forceStop method
|
|
1534
1340
|
this.handler.forceStop(createOfficeAddress("slack", channelId), sessionKey);
|
|
1535
|
-
// Notify in channel
|
|
1536
1341
|
await this.postMessage(channelId, formatForceStopped("slack", userId ?? "unknown"));
|
|
1537
|
-
// Refresh home tab
|
|
1538
1342
|
if (userId) {
|
|
1539
1343
|
this.openDirectConversation(userId)
|
|
1540
1344
|
.then((dmChannelId) => this.webClient.views.publish({
|
|
@@ -1623,11 +1427,6 @@ export class SlackMessagingBot {
|
|
|
1623
1427
|
return this.handler.handleEvent(event, this, this.createContext(slackEvent));
|
|
1624
1428
|
});
|
|
1625
1429
|
}
|
|
1626
|
-
/**
|
|
1627
|
-
* Download Slack message files into the office's attachments directory.
|
|
1628
|
-
* The Slack contract is all-or-error: any failed download throws after the
|
|
1629
|
-
* successful ones are on disk, so callers still log the message text.
|
|
1630
|
-
*/
|
|
1631
1430
|
async processAttachments(channelId, files, timestamp) {
|
|
1632
1431
|
const items = [];
|
|
1633
1432
|
for (const file of files) {
|
|
@@ -1639,7 +1438,6 @@ export class SlackMessagingBot {
|
|
|
1639
1438
|
}
|
|
1640
1439
|
items.push({
|
|
1641
1440
|
name: file.name,
|
|
1642
|
-
// Slack timestamps are float seconds; the stored filename uses ms.
|
|
1643
1441
|
timestampMs: Math.floor(parseFloat(timestamp) * 1000),
|
|
1644
1442
|
download: (destPath) => this.downloadSlackFile(url, destPath),
|
|
1645
1443
|
});
|
|
@@ -1654,7 +1452,6 @@ export class SlackMessagingBot {
|
|
|
1654
1452
|
}
|
|
1655
1453
|
return saved;
|
|
1656
1454
|
}
|
|
1657
|
-
/** Authorized download with retry; Slack file URLs require the bot token. */
|
|
1658
1455
|
async downloadSlackFile(url, destPath) {
|
|
1659
1456
|
await withRetry(async () => {
|
|
1660
1457
|
const response = await fetch(url, {
|
|
@@ -1667,9 +1464,6 @@ export class SlackMessagingBot {
|
|
|
1667
1464
|
await writeFile(destPath, Buffer.from(buffer));
|
|
1668
1465
|
}, { maxAttempts: 3, baseDelayMs: 250, isRateLimited: isRetryableAttachmentDownloadError });
|
|
1669
1466
|
}
|
|
1670
|
-
/**
|
|
1671
|
-
* Log a user message to log.jsonl after attachments are ready.
|
|
1672
|
-
*/
|
|
1673
1467
|
async logUserMessage(event) {
|
|
1674
1468
|
const user = this.users.get(event.user);
|
|
1675
1469
|
let attachments = [];
|
|
@@ -1682,8 +1476,6 @@ export class SlackMessagingBot {
|
|
|
1682
1476
|
attachmentError = err;
|
|
1683
1477
|
}
|
|
1684
1478
|
}
|
|
1685
|
-
// Always write the text log, even if attachment processing failed — we want
|
|
1686
|
-
// a record of the user message regardless of file-handling errors.
|
|
1687
1479
|
this.logToFile(event.channel, {
|
|
1688
1480
|
date: new Date(parseFloat(event.ts) * 1000).toISOString(),
|
|
1689
1481
|
ts: event.ts,
|
|
@@ -1720,9 +1512,6 @@ export class SlackMessagingBot {
|
|
|
1720
1512
|
});
|
|
1721
1513
|
return attachments;
|
|
1722
1514
|
}
|
|
1723
|
-
// ==========================================================================
|
|
1724
|
-
// Private - Backfill
|
|
1725
|
-
// ==========================================================================
|
|
1726
1515
|
async getExistingTimestamps(channelId) {
|
|
1727
1516
|
const logPath = join(this.conversationDir(channelId), "log.jsonl");
|
|
1728
1517
|
const timestamps = new Set();
|
|
@@ -1750,14 +1539,12 @@ export class SlackMessagingBot {
|
|
|
1750
1539
|
return false;
|
|
1751
1540
|
return BOT_MESSAGE_SUBTYPES.has(message.subtype) && hasMessageContent(message);
|
|
1752
1541
|
}
|
|
1753
|
-
// Unlike live intake, historical human posts need text or files, not just blocks.
|
|
1754
1542
|
return (!!message.user &&
|
|
1755
1543
|
USER_MESSAGE_SUBTYPES.has(message.subtype) &&
|
|
1756
1544
|
hasMessageContent(message, false));
|
|
1757
1545
|
}
|
|
1758
1546
|
async backfillChannel(channelId, upperBoundTs) {
|
|
1759
1547
|
const existingTs = await this.getExistingTimestamps(channelId);
|
|
1760
|
-
// Find the biggest ts in log.jsonl
|
|
1761
1548
|
let lastLoggedTs;
|
|
1762
1549
|
for (const ts of existingTs) {
|
|
1763
1550
|
if (!lastLoggedTs || parseFloat(ts) > parseFloat(lastLoggedTs))
|
|
@@ -1770,8 +1557,8 @@ export class SlackMessagingBot {
|
|
|
1770
1557
|
do {
|
|
1771
1558
|
const result = await this.webClient.conversations.history({
|
|
1772
1559
|
channel: channelId,
|
|
1773
|
-
oldest: lastLoggedTs,
|
|
1774
|
-
latest: upperBoundTs,
|
|
1560
|
+
oldest: lastLoggedTs,
|
|
1561
|
+
latest: upperBoundTs,
|
|
1775
1562
|
inclusive: false,
|
|
1776
1563
|
limit: 1000,
|
|
1777
1564
|
cursor,
|
|
@@ -1782,15 +1569,12 @@ export class SlackMessagingBot {
|
|
|
1782
1569
|
cursor = result.response_metadata?.next_cursor;
|
|
1783
1570
|
pageCount++;
|
|
1784
1571
|
} while (cursor && pageCount < maxPages);
|
|
1785
|
-
// Filter: include mikan's messages, external app/bot messages, and user messages.
|
|
1786
1572
|
const relevantMessages = allMessages.filter((msg) => {
|
|
1787
1573
|
if (!msg.ts || existingTs.has(msg.ts))
|
|
1788
|
-
return false;
|
|
1574
|
+
return false;
|
|
1789
1575
|
return this.isBackfillableMessage(msg);
|
|
1790
1576
|
});
|
|
1791
|
-
// Reverse to chronological order
|
|
1792
1577
|
relevantMessages.reverse();
|
|
1793
|
-
// Log each message to log.jsonl
|
|
1794
1578
|
for (const msg of relevantMessages) {
|
|
1795
1579
|
const isMikanMessage = msg.user === this.botUserId;
|
|
1796
1580
|
const isExternalMessagingBotMessage = !isMikanMessage && hasBotIdentity(msg);
|
|
@@ -1819,7 +1603,6 @@ export class SlackMessagingBot {
|
|
|
1819
1603
|
}
|
|
1820
1604
|
async backfillAllChannels(upperBoundTs) {
|
|
1821
1605
|
const startTime = Date.now();
|
|
1822
|
-
// Only backfill channels that already have a log.jsonl (mikan has interacted with them before)
|
|
1823
1606
|
const channelsToBackfill = [];
|
|
1824
1607
|
for (const [channelId, channel] of this.channels) {
|
|
1825
1608
|
const logPath = join(this.conversationDir(channelId), "log.jsonl");
|
|
@@ -1839,7 +1622,6 @@ export class SlackMessagingBot {
|
|
|
1839
1622
|
catch (error) {
|
|
1840
1623
|
log.logWarning(`Failed to backfill #${channel.name}`, String(error));
|
|
1841
1624
|
}
|
|
1842
|
-
// Add delay between channels to avoid hitting Slack rate limits
|
|
1843
1625
|
if (channelId !== channelsToBackfill[channelsToBackfill.length - 1]?.[0]) {
|
|
1844
1626
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
1845
1627
|
}
|
|
@@ -1847,9 +1629,6 @@ export class SlackMessagingBot {
|
|
|
1847
1629
|
const durationMs = Date.now() - startTime;
|
|
1848
1630
|
log.logBackfillComplete(totalMessages, durationMs);
|
|
1849
1631
|
}
|
|
1850
|
-
// ==========================================================================
|
|
1851
|
-
// Private - Fetch Users/Channels
|
|
1852
|
-
// ==========================================================================
|
|
1853
1632
|
async fetchUsers() {
|
|
1854
1633
|
let cursor;
|
|
1855
1634
|
do {
|
|
@@ -1869,7 +1648,6 @@ export class SlackMessagingBot {
|
|
|
1869
1648
|
} while (cursor);
|
|
1870
1649
|
}
|
|
1871
1650
|
async fetchChannels() {
|
|
1872
|
-
// Fetch public/private channels
|
|
1873
1651
|
let cursor;
|
|
1874
1652
|
do {
|
|
1875
1653
|
const result = await this.webClient.conversations.list({
|
|
@@ -1891,7 +1669,6 @@ export class SlackMessagingBot {
|
|
|
1891
1669
|
}
|
|
1892
1670
|
cursor = result.response_metadata?.next_cursor;
|
|
1893
1671
|
} while (cursor);
|
|
1894
|
-
// Also fetch DM channels (IMs)
|
|
1895
1672
|
cursor = undefined;
|
|
1896
1673
|
do {
|
|
1897
1674
|
const result = await this.webClient.conversations.list({
|
|
@@ -1903,7 +1680,6 @@ export class SlackMessagingBot {
|
|
|
1903
1680
|
for (const im of ims ?? []) {
|
|
1904
1681
|
if (!im.id)
|
|
1905
1682
|
continue;
|
|
1906
|
-
// Use user's name as channel name for DMs
|
|
1907
1683
|
const user = im.user ? this.users.get(im.user) : undefined;
|
|
1908
1684
|
const name = user ? `DM:${user.userName}` : `DM:${im.id}`;
|
|
1909
1685
|
this.channels.set(im.id, { id: im.id, name });
|