@geminixiang/mama 0.2.0-beta.1 → 0.2.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +133 -78
- package/dist/adapter.d.ts +22 -10
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js.map +1 -1
- package/dist/adapters/discord/bot.d.ts +10 -7
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +228 -69
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/discord/context.d.ts.map +1 -1
- package/dist/adapters/discord/context.js +92 -34
- package/dist/adapters/discord/context.js.map +1 -1
- package/dist/adapters/shared.d.ts +23 -0
- package/dist/adapters/shared.d.ts.map +1 -0
- package/dist/adapters/shared.js +57 -0
- package/dist/adapters/shared.js.map +1 -0
- package/dist/adapters/slack/bot.d.ts +19 -11
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +356 -96
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/branch-manager.d.ts +21 -0
- package/dist/adapters/slack/branch-manager.d.ts.map +1 -0
- package/dist/adapters/slack/branch-manager.js +96 -0
- package/dist/adapters/slack/branch-manager.js.map +1 -0
- package/dist/adapters/slack/context.d.ts.map +1 -1
- package/dist/adapters/slack/context.js +100 -67
- package/dist/adapters/slack/context.js.map +1 -1
- package/dist/adapters/slack/session.d.ts +3 -0
- package/dist/adapters/slack/session.d.ts.map +1 -0
- package/dist/adapters/slack/session.js +16 -0
- package/dist/adapters/slack/session.js.map +1 -0
- package/dist/adapters/telegram/bot.d.ts +4 -2
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +141 -74
- 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 +49 -109
- package/dist/adapters/telegram/context.js.map +1 -1
- package/dist/adapters/telegram/html.d.ts +3 -0
- package/dist/adapters/telegram/html.d.ts.map +1 -0
- package/dist/adapters/telegram/html.js +98 -0
- package/dist/adapters/telegram/html.js.map +1 -0
- package/dist/agent.d.ts +4 -11
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +116 -196
- package/dist/agent.js.map +1 -1
- package/dist/bindings.d.ts +1 -20
- package/dist/bindings.d.ts.map +1 -1
- package/dist/bindings.js +1 -21
- package/dist/bindings.js.map +1 -1
- package/dist/config.d.ts +9 -27
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +89 -63
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +13 -3
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +102 -18
- package/dist/context.js.map +1 -1
- package/dist/events.d.ts +18 -6
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +86 -35
- package/dist/events.js.map +1 -1
- package/dist/execution-resolver.d.ts.map +1 -1
- package/dist/execution-resolver.js +1 -3
- package/dist/execution-resolver.js.map +1 -1
- package/dist/instrument.d.ts.map +1 -1
- package/dist/instrument.js +5 -11
- package/dist/instrument.js.map +1 -1
- package/dist/{login.d.ts → login/index.d.ts} +2 -2
- package/dist/login/index.d.ts.map +1 -0
- package/dist/{login.js → login/index.js} +2 -2
- package/dist/login/index.js.map +1 -0
- package/dist/{link-server.d.ts → login/portal.d.ts} +6 -4
- package/dist/login/portal.d.ts.map +1 -0
- package/dist/login/portal.js +1453 -0
- package/dist/login/portal.js.map +1 -0
- package/dist/{link-token.d.ts → login/session.d.ts} +1 -1
- package/dist/login/session.d.ts.map +1 -0
- package/dist/{link-token.js → login/session.js} +1 -1
- package/dist/login/session.js.map +1 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +175 -119
- package/dist/main.js.map +1 -1
- package/dist/provisioner.d.ts +17 -43
- package/dist/provisioner.d.ts.map +1 -1
- package/dist/provisioner.js +84 -50
- package/dist/provisioner.js.map +1 -1
- package/dist/sandbox/host.d.ts +0 -2
- package/dist/sandbox/host.d.ts.map +1 -1
- package/dist/sandbox/host.js +1 -5
- package/dist/sandbox/host.js.map +1 -1
- package/dist/sentry.d.ts.map +1 -1
- package/dist/sentry.js +2 -0
- package/dist/sentry.js.map +1 -1
- package/dist/session-policy.d.ts +13 -0
- package/dist/session-policy.d.ts.map +1 -0
- package/dist/session-policy.js +23 -0
- package/dist/session-policy.js.map +1 -0
- package/dist/session-store.d.ts +27 -1
- package/dist/session-store.d.ts.map +1 -1
- package/dist/session-store.js +162 -9
- package/dist/session-store.js.map +1 -1
- package/dist/session-view/command.d.ts +5 -0
- package/dist/session-view/command.d.ts.map +1 -0
- package/dist/session-view/command.js +11 -0
- package/dist/session-view/command.js.map +1 -0
- package/dist/session-view/portal.d.ts +9 -0
- package/dist/session-view/portal.d.ts.map +1 -0
- package/dist/session-view/portal.js +766 -0
- package/dist/session-view/portal.js.map +1 -0
- package/dist/session-view/service.d.ts +34 -0
- package/dist/session-view/service.d.ts.map +1 -0
- package/dist/session-view/service.js +380 -0
- package/dist/session-view/service.js.map +1 -0
- package/dist/session-view/store.d.ts +16 -0
- package/dist/session-view/store.d.ts.map +1 -0
- package/dist/session-view/store.js +38 -0
- package/dist/session-view/store.js.map +1 -0
- package/dist/store.d.ts +3 -6
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +15 -35
- package/dist/store.js.map +1 -1
- package/dist/tools/event.d.ts +3 -0
- package/dist/tools/event.d.ts.map +1 -1
- package/dist/tools/event.js +27 -8
- package/dist/tools/event.js.map +1 -1
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/ui-copy.d.ts +1 -0
- package/dist/ui-copy.d.ts.map +1 -1
- package/dist/ui-copy.js +3 -0
- package/dist/ui-copy.js.map +1 -1
- package/dist/vault-routing.d.ts +1 -2
- package/dist/vault-routing.d.ts.map +1 -1
- package/dist/vault-routing.js +1 -7
- package/dist/vault-routing.js.map +1 -1
- package/package.json +1 -1
- package/dist/link-server.d.ts.map +0 -1
- package/dist/link-server.js +0 -839
- package/dist/link-server.js.map +0 -1
- package/dist/link-token.d.ts.map +0 -1
- package/dist/link-token.js.map +0 -1
- package/dist/login.d.ts.map +0 -1
- package/dist/login.js.map +0 -1
- package/dist/vault.test.d.ts +0 -2
- package/dist/vault.test.d.ts.map +0 -1
- package/dist/vault.test.js +0 -67
- package/dist/vault.test.js.map +0 -1
package/README.md
CHANGED
|
@@ -47,7 +47,9 @@ We actively track the upstream `pi-mom` and plan to:
|
|
|
47
47
|
- **Multi-platform** — Slack, Telegram, and Discord adapters out of the box
|
|
48
48
|
- **Persistent sessions** — session behavior is adapted per platform instead of forcing one thread model everywhere
|
|
49
49
|
- **Concurrent conversations** — Slack threads, Discord replies/threads, and Telegram reply chains can run independently
|
|
50
|
-
- **Sandbox execution** — run agent commands on host, in shared
|
|
50
|
+
- **Sandbox execution** — run agent commands on host, in a shared container, in a managed per-user container, or experimentally in a Firecracker VM
|
|
51
|
+
- **Credential vaults** — `/login` stores credentials under `--state-dir` and injects env only into container/image/Firecracker runs
|
|
52
|
+
- **Web session viewer** — users can open a read-only web view of the current session via `session` / `/session`
|
|
51
53
|
- **Persistent memory** — workspace-level and channel-level `MEMORY.md` files
|
|
52
54
|
- **Skills** — drop custom CLI tools into `skills/` directories
|
|
53
55
|
- **Event system** — schedule one-shot or recurring tasks via JSON files
|
|
@@ -55,11 +57,11 @@ We actively track the upstream `pi-mom` and plan to:
|
|
|
55
57
|
|
|
56
58
|
## Platform Session Model
|
|
57
59
|
|
|
58
|
-
| Platform | User Interaction Structure
|
|
59
|
-
| -------- |
|
|
60
|
-
| Slack | channel top-level + thread replies
|
|
61
|
-
| Discord |
|
|
62
|
-
| Telegram | private chats, group
|
|
60
|
+
| Platform | User Interaction Structure | `sessionKey` Rule | Default Session Model | Special Handling Needed | Notes |
|
|
61
|
+
| -------- | ------------------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------ |
|
|
62
|
+
| Slack | channel top-level + thread replies | top-level / DM: `conversationId`; thread: `conversationId:threadTs` | top-level channel and DM sessions persist; each Slack thread forks into its own session | High | thread inherits parent context at fork time only; branch changes do not merge back automatically |
|
|
63
|
+
| Discord | server mentions, replies, thread channels, DMs | DM: `channelId`; shared top-level: `channelId:messageId`; reply/thread: rooted id | DMs are one persistent session; shared spaces are scoped per top-level mention or thread | Medium | replies in shared channels continue the root message session; DM replies do not fork |
|
|
64
|
+
| Telegram | private chats, group mentions, group reply chains | private: `chatId`; shared top-level: `chatId:messageId`; reply chain: root reply | private chats are one persistent session; shared groups are scoped per mentioned reply root | Medium | Telegram has no native thread model; shared sessions are inferred from reply chains |
|
|
63
65
|
|
|
64
66
|
## Requirements
|
|
65
67
|
|
|
@@ -99,7 +101,8 @@ npm run build
|
|
|
99
101
|
- `assistant_thread_context_changed`, `assistant_thread_started`
|
|
100
102
|
- `message.channels`, `message.groups`, `message.im`
|
|
101
103
|
5. Enable **Interactivity** (Settings → Interactivity & Shortcuts → toggle on).
|
|
102
|
-
6.
|
|
104
|
+
6. (Optional) Add **Slash Commands** such as `/pi-login` and `/pi-new` in the Slack app settings if you want dedicated commands with less naming conflict. `/pi-new` is intended for DM use only.
|
|
105
|
+
7. Copy the **App-Level Token** (`xapp-…`) and **Bot Token** (`xoxb-…`).
|
|
103
106
|
|
|
104
107
|
Or import this **App Manifest** directly (Settings → App Manifest → paste JSON):
|
|
105
108
|
|
|
@@ -169,14 +172,16 @@ Or import this **App Manifest** directly (Settings → App Manifest → paste JS
|
|
|
169
172
|
export MOM_SLACK_APP_TOKEN=xapp-...
|
|
170
173
|
export MOM_SLACK_BOT_TOKEN=xoxb-...
|
|
171
174
|
|
|
172
|
-
mama [--sandbox=host|container:<container>] <working-directory>
|
|
175
|
+
mama [--state-dir=~/.mama] [--sandbox=host|container:<container>|image:<image>|firecracker:<vm-id>:<path>] <working-directory>
|
|
173
176
|
```
|
|
174
177
|
|
|
175
178
|
The bot responds when `@mentioned` in any channel or via DM.
|
|
176
179
|
|
|
177
180
|
- **Top-level channel messages** — share one persistent channel session.
|
|
178
181
|
- **Thread replies** — fork from the channel session into an isolated thread session.
|
|
179
|
-
- **
|
|
182
|
+
- **DM top-level messages** — share one persistent DM session.
|
|
183
|
+
- **DM thread replies** — fork from the DM session into an isolated thread session.
|
|
184
|
+
- **Thread memory** — inherited at fork time only; thread changes do not merge back into the parent session automatically.
|
|
180
185
|
|
|
181
186
|
---
|
|
182
187
|
|
|
@@ -184,17 +189,18 @@ The bot responds when `@mentioned` in any channel or via DM.
|
|
|
184
189
|
|
|
185
190
|
1. Message [@BotFather](https://t.me/BotFather) → `/newbot` to create a bot and get the **Bot Token**.
|
|
186
191
|
2. Optionally disable privacy mode (`/setprivacy → Disable`) so the bot can read group messages without being `@mentioned`.
|
|
187
|
-
3. For OAuth login setup, see [docs/oauth/github.md](docs/oauth/github.md) and [docs/oauth/google-workspace.md](docs/oauth/google-workspace.md).
|
|
188
192
|
|
|
189
193
|
```bash
|
|
190
194
|
export MOM_TELEGRAM_BOT_TOKEN=123456:ABC-...
|
|
191
195
|
|
|
192
|
-
mama [--sandbox=host|container:<container>] <working-directory>
|
|
196
|
+
mama [--state-dir=~/.mama] [--sandbox=host|container:<container>|image:<image>|firecracker:<vm-id>:<path>] <working-directory>
|
|
193
197
|
```
|
|
194
198
|
|
|
195
199
|
- **Private chats** — every message is forwarded to the bot automatically.
|
|
196
200
|
- **Group chats** — the bot only responds when `@mentioned` by username.
|
|
197
|
-
- **
|
|
201
|
+
- **Private chat session** — one persistent session per DM.
|
|
202
|
+
- **Group top-level mentions** — each mentioned message starts its own scoped session.
|
|
203
|
+
- **Reply chains** — replying to a previous message continues that reply-root session.
|
|
198
204
|
- Say `stop` or `/stop` to cancel a running task.
|
|
199
205
|
|
|
200
206
|
---
|
|
@@ -209,33 +215,38 @@ mama [--sandbox=host|container:<container>] <working-directory>
|
|
|
209
215
|
```bash
|
|
210
216
|
export MOM_DISCORD_BOT_TOKEN=MTI...
|
|
211
217
|
|
|
212
|
-
mama [--sandbox=host|container:<container>] <working-directory>
|
|
218
|
+
mama [--state-dir=~/.mama] [--sandbox=host|container:<container>|image:<image>|firecracker:<vm-id>:<path>] <working-directory>
|
|
213
219
|
```
|
|
214
220
|
|
|
215
221
|
- **Server channels** — the bot responds when `@mentioned`.
|
|
216
222
|
- **DMs** — every message is forwarded automatically.
|
|
217
|
-
- **
|
|
218
|
-
- **
|
|
223
|
+
- **DM session** — one persistent session per DM channel.
|
|
224
|
+
- **Top-level mentions in shared channels** — each mentioned message starts its own scoped session.
|
|
225
|
+
- **Threads and reply chains** — messages inside the same thread or reply root share a session.
|
|
219
226
|
- Say `stop` or `/stop` to cancel a running task.
|
|
220
227
|
|
|
221
228
|
---
|
|
222
229
|
|
|
223
230
|
## Options
|
|
224
231
|
|
|
225
|
-
| Option | Default | Description
|
|
226
|
-
| -------------------------------------- | --------- |
|
|
227
|
-
| `--
|
|
228
|
-
| `--sandbox=
|
|
229
|
-
| `--sandbox=
|
|
230
|
-
| `--sandbox=
|
|
231
|
-
| `--
|
|
232
|
-
| `--download <channel-id>` | | Download channel history to stdout and exit (Slack only)
|
|
232
|
+
| Option | Default | Description |
|
|
233
|
+
| -------------------------------------- | --------- | ------------------------------------------------------------------ |
|
|
234
|
+
| `--state-dir=<dir>` | `~/.mama` | Store settings, credential vaults, and bindings outside workspace |
|
|
235
|
+
| `--sandbox=host` | ✓ | Run commands directly on host; vault env is not injected |
|
|
236
|
+
| `--sandbox=container:<name>` | | Run commands in an existing shared container |
|
|
237
|
+
| `--sandbox=image:<image>` | | Auto-provision one Docker container per platform user |
|
|
238
|
+
| `--sandbox=firecracker:<vm-id>:<path>` | | Experimental Firecracker microVM mode (alpha; not recommended yet) |
|
|
239
|
+
| `--download <channel-id>` | | Download channel history to stdout and exit (Slack only) |
|
|
233
240
|
|
|
234
|
-
###
|
|
241
|
+
### Sandbox and Vault Semantics
|
|
235
242
|
|
|
236
|
-
- `
|
|
237
|
-
- `
|
|
238
|
-
- `
|
|
243
|
+
- `host`: no vault env injection.
|
|
244
|
+
- `container:<name>`: one container maps to one shared vault key: `container-<name>`.
|
|
245
|
+
- `image:<image>`: mama creates one container per resolved vault/user and injects that vault's env and file mounts.
|
|
246
|
+
- `firecracker:*`: per-user vault routing via `bindings.json` first, then direct userId vault. This mode is still alpha and not recommended for normal deployments yet.
|
|
247
|
+
- `docker:*` is not supported; use `container:*` or `image:*`.
|
|
248
|
+
|
|
249
|
+
See [docs/sandbox.md](docs/sandbox.md) for the full sandbox/vault behavior matrix.
|
|
239
250
|
|
|
240
251
|
### Download channel history (Slack)
|
|
241
252
|
|
|
@@ -243,14 +254,51 @@ mama [--sandbox=host|container:<container>] <working-directory>
|
|
|
243
254
|
mama --download C0123456789
|
|
244
255
|
```
|
|
245
256
|
|
|
257
|
+
## `/login` Credential Onboarding
|
|
258
|
+
|
|
259
|
+
For normal deployments, set `MOM_LINK_URL` to the externally reachable base URL of the web credential onboarding flow:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
export MOM_LINK_URL="https://mama.example.com"
|
|
263
|
+
# optional; defaults to 8181 when MOM_LINK_URL is set
|
|
264
|
+
export MOM_LINK_PORT=8181
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
For local-only testing, you can set `MOM_LINK_PORT` without `MOM_LINK_URL`; mama will use `http://localhost:<port>` for the onboarding link.
|
|
268
|
+
|
|
269
|
+
Users can then run `/login` in a private conversation with the bot. mama returns a 15-minute link for storing API keys or using built-in OAuth providers. `/login` is rejected in shared channels to avoid leaking onboarding links.
|
|
270
|
+
|
|
271
|
+
On Slack, you can also register native slash commands such as `/pi-login` and `/pi-new`.
|
|
272
|
+
|
|
273
|
+
- `/pi-login` in a shared channel opens a DM and continues the credential flow there.
|
|
274
|
+
- `/pi-new` only works in a Slack DM and resets that DM session context.
|
|
275
|
+
|
|
276
|
+
## Web Session Viewer
|
|
277
|
+
|
|
278
|
+
The same web portal used for `/login` can also render a read-only view of the current session.
|
|
279
|
+
|
|
280
|
+
- Users can send `session`, `/session`, or `/pi-session` in a private conversation / DM.
|
|
281
|
+
- mama returns an expiring read-only link to `/session?token=...`.
|
|
282
|
+
- The page shows the current branch timeline, including user messages, assistant replies, tool results, and compaction / branch summary events.
|
|
283
|
+
- For now, session links are only issued from private conversations to avoid leaking shared-channel history.
|
|
284
|
+
|
|
285
|
+
This feature uses the same `MOM_LINK_URL` / `MOM_LINK_PORT` configuration as `/login`.
|
|
286
|
+
|
|
287
|
+
Built-in OAuth guides:
|
|
288
|
+
|
|
289
|
+
- [GitHub OAuth](docs/oauth/github.md)
|
|
290
|
+
- [Google Workspace CLI OAuth](docs/oauth/google-workspace.md)
|
|
291
|
+
|
|
292
|
+
Credentials are stored under `<state-dir>/vaults` (default `~/.mama/vaults`). Runtime env injection only happens in `container`, `image`, and `firecracker` modes.
|
|
293
|
+
|
|
246
294
|
## Configuration
|
|
247
295
|
|
|
248
|
-
mama
|
|
296
|
+
mama loads settings from `<state-dir>/settings.json` first, then falls back to `<working-directory>/settings.json` if the state-dir file is absent. For shared bot deployments, prefer the state-dir copy:
|
|
249
297
|
|
|
250
298
|
```json
|
|
251
299
|
{
|
|
252
300
|
"provider": "anthropic",
|
|
253
|
-
"model": "claude-sonnet-4-
|
|
301
|
+
"model": "claude-sonnet-4-5",
|
|
254
302
|
"thinkingLevel": "off",
|
|
255
303
|
"sessionScope": "thread",
|
|
256
304
|
"logFormat": "console",
|
|
@@ -259,15 +307,15 @@ mama stores operator-managed configuration in `~/.mama` by default. Use `--state
|
|
|
259
307
|
}
|
|
260
308
|
```
|
|
261
309
|
|
|
262
|
-
| Field | Default | Description
|
|
263
|
-
| --------------- | ------------------- |
|
|
264
|
-
| `provider` | `anthropic` | AI provider (env: `MOM_AI_PROVIDER`)
|
|
265
|
-
| `model` | `claude-sonnet-4-
|
|
266
|
-
| `thinkingLevel` | `off` | `off` / `low` / `medium` / `high`
|
|
267
|
-
| `sessionScope` | `thread` |
|
|
268
|
-
| `logFormat` | `console` | `console` (colored stdout) or `json` (GCP Cloud Logging)
|
|
269
|
-
| `logLevel` | `info` | `trace` / `debug` / `info` / `warn` / `error`
|
|
270
|
-
| `sentryDsn` | unset | Sentry DSN (preferred over env `SENTRY_DSN`)
|
|
310
|
+
| Field | Default | Description |
|
|
311
|
+
| --------------- | ------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
312
|
+
| `provider` | `anthropic` | AI provider (env: `MOM_AI_PROVIDER`) |
|
|
313
|
+
| `model` | `claude-sonnet-4-5` | Model name (env: `MOM_AI_MODEL`) |
|
|
314
|
+
| `thinkingLevel` | `off` | `off` / `low` / `medium` / `high` |
|
|
315
|
+
| `sessionScope` | `thread` | Legacy compatibility setting. Current session boundaries are platform-defined by adapter/session policy. |
|
|
316
|
+
| `logFormat` | `console` | `console` (colored stdout) or `json` (GCP Cloud Logging) |
|
|
317
|
+
| `logLevel` | `info` | `trace` / `debug` / `info` / `warn` / `error` |
|
|
318
|
+
| `sentryDsn` | unset | Sentry DSN (preferred over env `SENTRY_DSN`) |
|
|
271
319
|
|
|
272
320
|
When `sentryDsn` is set, mama sends Sentry events with sensitive prompt/tool content redacted before upload.
|
|
273
321
|
|
|
@@ -284,7 +332,7 @@ Set `logFormat: "json"` to send structured logs directly to Cloud Logging via AP
|
|
|
284
332
|
GOOGLE_CLOUD_PROJECT=<your-project-id> mama <working-directory>
|
|
285
333
|
```
|
|
286
334
|
|
|
287
|
-
`settings.json
|
|
335
|
+
In `<state-dir>/settings.json` (or `<working-directory>/settings.json` as a fallback):
|
|
288
336
|
|
|
289
337
|
```json
|
|
290
338
|
{
|
|
@@ -295,72 +343,79 @@ GOOGLE_CLOUD_PROJECT=<your-project-id> mama <working-directory>
|
|
|
295
343
|
|
|
296
344
|
Logs appear in Cloud Logging under **Log name: `mama`**. Console output (stdout) is unaffected and continues to work alongside Cloud Logging.
|
|
297
345
|
|
|
346
|
+
## State Directory Layout
|
|
347
|
+
|
|
348
|
+
```
|
|
349
|
+
<state-dir>/
|
|
350
|
+
├── settings.json # Preferred provider/model/logging/Sentry config
|
|
351
|
+
└── vaults/
|
|
352
|
+
├── bindings.json # Platform user -> vault mapping
|
|
353
|
+
├── vault.json # Vault metadata
|
|
354
|
+
└── <vault-id>/
|
|
355
|
+
├── env # Injected env vars
|
|
356
|
+
└── ... # Credential files (e.g. gws.json, .ssh/)
|
|
357
|
+
```
|
|
358
|
+
|
|
298
359
|
## Working Directory Layout
|
|
299
360
|
|
|
300
361
|
```
|
|
301
362
|
<working-directory>/
|
|
363
|
+
├── settings.json # Optional fallback config if <state-dir>/settings.json is absent
|
|
302
364
|
├── MEMORY.md # Global memory (all channels)
|
|
303
365
|
├── SYSTEM.md # Installed packages / env changes log
|
|
304
366
|
├── skills/ # Global skills (CLI tools)
|
|
305
367
|
├── events/ # Scheduled event files
|
|
306
|
-
└── <
|
|
307
|
-
├── MEMORY.md #
|
|
368
|
+
└── <conversation-id>/
|
|
369
|
+
├── MEMORY.md # Conversation-specific memory
|
|
308
370
|
├── log.jsonl # Full message history
|
|
309
371
|
├── attachments/ # Downloaded user files
|
|
310
372
|
├── scratch/ # Agent working directory
|
|
311
|
-
├── skills/ #
|
|
373
|
+
├── skills/ # Conversation-specific skills
|
|
312
374
|
└── sessions/
|
|
313
|
-
├── current # Pointer for the
|
|
375
|
+
├── current # Pointer for the persistent top-level / direct session
|
|
314
376
|
├── 2026-04-05T18-04-31-010Z_1d92b3ad.jsonl
|
|
315
|
-
└── <
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
Operator-managed state lives outside the workspace:
|
|
319
|
-
|
|
320
|
-
```
|
|
321
|
-
<state-dir>/
|
|
322
|
-
├── settings.json # AI provider/model/Sentry config
|
|
323
|
-
└── vaults/
|
|
324
|
-
├── vault.json # Per-user vault routing
|
|
325
|
-
└── bindings.json # Optional platform-user to vault mapping
|
|
377
|
+
└── <session-suffix>.jsonl # Fixed-path scoped session (thread / reply root)
|
|
326
378
|
```
|
|
327
379
|
|
|
328
380
|
## Container Sandbox
|
|
329
381
|
|
|
330
382
|
```bash
|
|
331
383
|
# Create a container (mount your working directory to /workspace)
|
|
332
|
-
docker run -d --name mama-
|
|
384
|
+
docker run -d --name mama-tools \
|
|
333
385
|
-v /path/to/workspace:/workspace \
|
|
334
386
|
alpine:latest sleep infinity
|
|
335
387
|
|
|
336
388
|
# Start mama with container sandbox
|
|
337
|
-
mama --sandbox=container:mama-
|
|
389
|
+
mama --sandbox=container:mama-tools /path/to/workspace
|
|
338
390
|
```
|
|
339
391
|
|
|
392
|
+
`container:mama-tools` uses vault key `container-mama-tools`. If multiple users share the same container, they share that container vault.
|
|
393
|
+
|
|
340
394
|
## Managed Per-User Container Sandbox
|
|
341
395
|
|
|
342
396
|
```bash
|
|
343
|
-
#
|
|
344
|
-
|
|
397
|
+
# Pull the prebuilt image from GHCR
|
|
398
|
+
# Release builds publish :tools, :<version>, and :latest / :beta
|
|
399
|
+
# Pushes to main also publish :edge
|
|
400
|
+
docker pull ghcr.io/geminixiang/mama-sandbox:tools
|
|
345
401
|
|
|
346
|
-
#
|
|
347
|
-
mama --sandbox=image:mama-sandbox:tools /path/to/workspace
|
|
402
|
+
# Start mama with managed image sandboxes
|
|
403
|
+
mama --sandbox=image:ghcr.io/geminixiang/mama-sandbox:tools /path/to/workspace
|
|
348
404
|
```
|
|
349
405
|
|
|
350
|
-
|
|
406
|
+
Or build the bundled image locally:
|
|
351
407
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
-
|
|
355
|
-
|
|
356
|
-
- `uv`
|
|
357
|
-
- `gcloud`, `gsutil`, `bq`
|
|
358
|
-
- `gws` via `npm install -g @googleworkspace/cli`
|
|
408
|
+
```bash
|
|
409
|
+
docker build -f docker/mama-sandbox.Dockerfile -t mama-sandbox:tools .
|
|
410
|
+
mama --sandbox=image:mama-sandbox:tools /path/to/workspace
|
|
411
|
+
```
|
|
359
412
|
|
|
360
|
-
|
|
413
|
+
In this mode mama creates one Docker container per resolved vault/user, attaches each container to its own Docker bridge network for per-user network isolation, mounts the workspace at `/workspace`, injects vault env on execution, mounts any credential files declared in the vault, and stops idle containers automatically.
|
|
361
414
|
|
|
362
415
|
## Firecracker Sandbox
|
|
363
416
|
|
|
417
|
+
Warning: Firecracker support is still in very early alpha. It is useful for experimentation, but it is not yet the recommended sandbox mode for normal development or production use. Prefer `image:<image>` unless you are actively validating Firecracker behavior.
|
|
418
|
+
|
|
364
419
|
Firecracker provides lightweight VM isolation with the security benefits of a hypervisor. Unlike Docker containers, Firecracker runs a full Linux kernel, providing stronger isolation.
|
|
365
420
|
|
|
366
421
|
### Requirements
|
|
@@ -432,13 +487,13 @@ Drop JSON files into `<working-directory>/events/` to trigger the agent:
|
|
|
432
487
|
|
|
433
488
|
```json
|
|
434
489
|
// Immediate — triggers as soon as mama sees the file
|
|
435
|
-
{"type": "immediate", "
|
|
490
|
+
{"type": "immediate", "platform": "slack", "conversationId": "C0123456789", "conversationKind": "shared", "text": "New deployment finished"}
|
|
436
491
|
|
|
437
492
|
// One-shot — triggers once at a specific time
|
|
438
|
-
{"type": "one-shot", "
|
|
493
|
+
{"type": "one-shot", "platform": "telegram", "conversationId": "574247312", "conversationKind": "direct", "text": "Daily standup reminder", "at": "2025-12-15T09:00:00+08:00"}
|
|
439
494
|
|
|
440
495
|
// Periodic — triggers on a cron schedule
|
|
441
|
-
{"type": "periodic", "
|
|
496
|
+
{"type": "periodic", "platform": "discord", "conversationId": "1498975469343739948", "conversationKind": "shared", "text": "Check inbox", "schedule": "0 9 * * 1-5", "timezone": "Asia/Taipei"}
|
|
442
497
|
```
|
|
443
498
|
|
|
444
499
|
## Skills
|
|
@@ -473,12 +528,12 @@ npm run build # production build
|
|
|
473
528
|
|
|
474
529
|
## 📦 Dependencies & Versions
|
|
475
530
|
|
|
476
|
-
| Package | mama Version | pi-mom Synced Version
|
|
477
|
-
| ------------------------------- | ------------ |
|
|
478
|
-
| `@mariozechner/pi-agent-core` | `^0.
|
|
479
|
-
| `@mariozechner/pi-ai` | `^0.
|
|
480
|
-
| `@mariozechner/pi-coding-agent` | `^0.
|
|
481
|
-
| `@anthropic-ai/sandbox-runtime` | `^0.0.
|
|
531
|
+
| Package | mama Version | pi-mom Synced Version |
|
|
532
|
+
| ------------------------------- | ------------ | -------------------------------- |
|
|
533
|
+
| `@mariozechner/pi-agent-core` | `^0.69.0` | ✅ Synchronized |
|
|
534
|
+
| `@mariozechner/pi-ai` | `^0.69.0` | ✅ Synchronized |
|
|
535
|
+
| `@mariozechner/pi-coding-agent` | `^0.69.0` | ✅ Synchronized |
|
|
536
|
+
| `@anthropic-ai/sandbox-runtime` | `^0.0.49` | ⚠️ Newer than original fork base |
|
|
482
537
|
|
|
483
538
|
## License
|
|
484
539
|
|
package/dist/adapter.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
export type ConversationKind = "direct" | "shared";
|
|
1
2
|
export interface ChatMessage {
|
|
2
3
|
id: string;
|
|
3
4
|
sessionKey: string;
|
|
5
|
+
conversationKind: ConversationKind;
|
|
4
6
|
userId: string;
|
|
5
7
|
userName?: string;
|
|
6
8
|
text: string;
|
|
@@ -10,12 +12,21 @@ export interface ChatMessage {
|
|
|
10
12
|
}[];
|
|
11
13
|
threadTs?: string;
|
|
12
14
|
}
|
|
15
|
+
export interface ChatToolResult {
|
|
16
|
+
toolName: string;
|
|
17
|
+
label?: string;
|
|
18
|
+
args?: Record<string, unknown>;
|
|
19
|
+
result: string;
|
|
20
|
+
isError: boolean;
|
|
21
|
+
durationMs: number;
|
|
22
|
+
}
|
|
13
23
|
export interface ChatResponseContext {
|
|
14
24
|
respond(text: string): Promise<void>;
|
|
15
25
|
replaceResponse(text: string): Promise<void>;
|
|
16
|
-
|
|
17
|
-
style?: "muted";
|
|
26
|
+
respondDiagnostic(text: string, options?: {
|
|
27
|
+
style?: "muted" | "error";
|
|
18
28
|
}): Promise<void>;
|
|
29
|
+
respondToolResult(result: ChatToolResult): Promise<void>;
|
|
19
30
|
setTyping(isTyping: boolean): Promise<void>;
|
|
20
31
|
setWorking(working: boolean): Promise<void>;
|
|
21
32
|
uploadFile(filePath: string, title?: string): Promise<void>;
|
|
@@ -33,6 +44,9 @@ export interface PlatformInfo {
|
|
|
33
44
|
userName: string;
|
|
34
45
|
displayName: string;
|
|
35
46
|
}[];
|
|
47
|
+
diagnostics?: {
|
|
48
|
+
showUsageSummary?: boolean;
|
|
49
|
+
};
|
|
36
50
|
}
|
|
37
51
|
export interface ChatAdapter {
|
|
38
52
|
start(): Promise<void>;
|
|
@@ -44,8 +58,10 @@ export interface ChatAdapter {
|
|
|
44
58
|
*/
|
|
45
59
|
export interface BotEvent {
|
|
46
60
|
type: string;
|
|
47
|
-
/**
|
|
61
|
+
/** Platform-specific raw conversation/channel/chat identifier */
|
|
48
62
|
conversationId: string;
|
|
63
|
+
/** Cross-platform conversation shape: direct message vs shared space */
|
|
64
|
+
conversationKind: ConversationKind;
|
|
49
65
|
/** Message timestamp or ID as string */
|
|
50
66
|
ts: string;
|
|
51
67
|
/** Parent message ID for threaded replies (optional) */
|
|
@@ -59,7 +75,7 @@ export interface BotEvent {
|
|
|
59
75
|
name: string;
|
|
60
76
|
localPath: string;
|
|
61
77
|
}[];
|
|
62
|
-
/** Platform-computed session key; overrides default
|
|
78
|
+
/** Platform-computed session key; overrides default conversationId:thread_ts computation */
|
|
63
79
|
sessionKey?: string;
|
|
64
80
|
}
|
|
65
81
|
/**
|
|
@@ -68,8 +84,8 @@ export interface BotEvent {
|
|
|
68
84
|
*/
|
|
69
85
|
export interface Bot {
|
|
70
86
|
start(): Promise<void>;
|
|
71
|
-
postMessage(
|
|
72
|
-
updateMessage(
|
|
87
|
+
postMessage(channel: string, text: string): Promise<string>;
|
|
88
|
+
updateMessage(channel: string, ts: string, text: string): Promise<void>;
|
|
73
89
|
enqueueEvent(event: BotEvent): boolean;
|
|
74
90
|
getPlatformInfo(): PlatformInfo;
|
|
75
91
|
}
|
|
@@ -100,9 +116,5 @@ export interface BotHandler {
|
|
|
100
116
|
forceStop(sessionKey: string): void;
|
|
101
117
|
/** Reset a session: abort if running, delete history, remove from cache */
|
|
102
118
|
handleNew(sessionKey: string, conversationId: string, bot: Bot): Promise<void>;
|
|
103
|
-
/** Handle credential onboarding for a user login command. */
|
|
104
|
-
handleLogin(platform: string, platformUserId: string, conversationId: string, bot: Bot, commandText: string, isPrivateConversation: boolean): Promise<void>;
|
|
105
119
|
}
|
|
106
|
-
/** @deprecated Use BotHandler */
|
|
107
|
-
export type MomHandler = BotHandler;
|
|
108
120
|
//# sourceMappingURL=adapter.d.ts.map
|
package/dist/adapter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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","sourcesContent":["export type ConversationKind = \"direct\" | \"shared\";\n\nexport interface ChatMessage {\n id: string;\n sessionKey: string;\n conversationKind: ConversationKind;\n userId: string;\n userName?: string;\n text: string;\n attachments?: { name: string; localPath: string }[];\n threadTs?: string;\n}\n\nexport interface ChatToolResult {\n toolName: string;\n label?: string;\n args?: Record<string, unknown>;\n result: string;\n isError: boolean;\n durationMs: number;\n}\n\nexport interface ChatResponseContext {\n respond(text: string): Promise<void>;\n replaceResponse(text: string): Promise<void>;\n respondDiagnostic(text: string, options?: { style?: \"muted\" | \"error\" }): Promise<void>;\n respondToolResult(result: ChatToolResult): Promise<void>;\n setTyping(isTyping: boolean): Promise<void>;\n setWorking(working: boolean): Promise<void>;\n uploadFile(filePath: string, title?: string): Promise<void>;\n deleteResponse(): Promise<void>;\n}\n\nexport interface PlatformInfo {\n name: string;\n formattingGuide: string;\n channels: { id: string; name: string }[];\n users: { id: string; userName: string; displayName: string }[];\n diagnostics?: {\n showUsageSummary?: boolean;\n };\n}\n\nexport interface ChatAdapter {\n start(): Promise<void>;\n stop(): Promise<void>;\n getPlatformInfo(): PlatformInfo;\n}\n\n// ============================================================================\n// Generic cross-platform event and bot interfaces\n// ============================================================================\n\n/**\n * A platform-agnostic event (message/mention) that triggers the agent.\n */\nexport interface BotEvent {\n type: string;\n /** Platform-specific raw conversation/channel/chat identifier */\n conversationId: string;\n /** Cross-platform conversation shape: direct message vs shared space */\n conversationKind: ConversationKind;\n /** Message timestamp or ID as string */\n ts: string;\n /** Parent message ID for threaded replies (optional) */\n thread_ts?: string;\n /** User ID */\n user: string;\n /** Message text (already stripped of bot mentions) */\n text: string;\n /** Downloaded attachments */\n attachments?: { name: string; localPath: string }[];\n /** Platform-computed session key; overrides default conversationId:thread_ts computation */\n sessionKey?: string;\n}\n\n/**\n * Minimum interface that every platform bot must implement,\n * used by the central handler in main.ts and by EventsWatcher.\n */\nexport interface Bot {\n start(): Promise<void>;\n postMessage(channel: string, text: string): Promise<string>;\n updateMessage(channel: string, ts: string, text: string): Promise<void>;\n enqueueEvent(event: BotEvent): boolean;\n getPlatformInfo(): PlatformInfo;\n}\n\n/** Pre-created platform adapters passed to the handler */\nexport interface BotAdapters {\n message: ChatMessage;\n responseCtx: ChatResponseContext;\n platform: PlatformInfo;\n}\n\n/**\n * Handler callbacks invoked by each platform bot.\n * Each bot creates platform-specific adapters before calling handleEvent.\n */\nexport interface RunningSession {\n sessionKey: string;\n startedAt: number; // Date.now() when run started\n /** Last activity timestamp (for detecting hung tasks) */\n lastActivityAt?: number;\n /** Current tool/step being executed (if any) */\n currentTool?: string;\n}\n\nexport interface BotHandler {\n isRunning(sessionKey: string): boolean;\n getRunningSessions(): RunningSession[];\n handleEvent(event: BotEvent, bot: Bot, adapters: BotAdapters, isEvent?: boolean): Promise<void>;\n handleStop(sessionKey: string, conversationId: string, bot: Bot): Promise<void>;\n /** Force stop a running session (bypass normal stop mechanism) */\n forceStop(sessionKey: string): void;\n /** Reset a session: abort if running, delete history, remove from cache */\n handleNew(sessionKey: string, conversationId: string, bot: Bot): Promise<void>;\n}\n"]}
|
package/dist/adapter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"","sourcesContent":["export interface ChatMessage {\n id: string;\n sessionKey: string;\n userId: string;\n userName?: string;\n text: string;\n attachments?: { name: string; localPath: string }[];\n threadTs?: string;\n}\n\nexport interface ChatResponseContext {\n respond(text: string): Promise<void>;\n replaceResponse(text: string): Promise<void>;\n
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"","sourcesContent":["export type ConversationKind = \"direct\" | \"shared\";\n\nexport interface ChatMessage {\n id: string;\n sessionKey: string;\n conversationKind: ConversationKind;\n userId: string;\n userName?: string;\n text: string;\n attachments?: { name: string; localPath: string }[];\n threadTs?: string;\n}\n\nexport interface ChatToolResult {\n toolName: string;\n label?: string;\n args?: Record<string, unknown>;\n result: string;\n isError: boolean;\n durationMs: number;\n}\n\nexport interface ChatResponseContext {\n respond(text: string): Promise<void>;\n replaceResponse(text: string): Promise<void>;\n respondDiagnostic(text: string, options?: { style?: \"muted\" | \"error\" }): Promise<void>;\n respondToolResult(result: ChatToolResult): Promise<void>;\n setTyping(isTyping: boolean): Promise<void>;\n setWorking(working: boolean): Promise<void>;\n uploadFile(filePath: string, title?: string): Promise<void>;\n deleteResponse(): Promise<void>;\n}\n\nexport interface PlatformInfo {\n name: string;\n formattingGuide: string;\n channels: { id: string; name: string }[];\n users: { id: string; userName: string; displayName: string }[];\n diagnostics?: {\n showUsageSummary?: boolean;\n };\n}\n\nexport interface ChatAdapter {\n start(): Promise<void>;\n stop(): Promise<void>;\n getPlatformInfo(): PlatformInfo;\n}\n\n// ============================================================================\n// Generic cross-platform event and bot interfaces\n// ============================================================================\n\n/**\n * A platform-agnostic event (message/mention) that triggers the agent.\n */\nexport interface BotEvent {\n type: string;\n /** Platform-specific raw conversation/channel/chat identifier */\n conversationId: string;\n /** Cross-platform conversation shape: direct message vs shared space */\n conversationKind: ConversationKind;\n /** Message timestamp or ID as string */\n ts: string;\n /** Parent message ID for threaded replies (optional) */\n thread_ts?: string;\n /** User ID */\n user: string;\n /** Message text (already stripped of bot mentions) */\n text: string;\n /** Downloaded attachments */\n attachments?: { name: string; localPath: string }[];\n /** Platform-computed session key; overrides default conversationId:thread_ts computation */\n sessionKey?: string;\n}\n\n/**\n * Minimum interface that every platform bot must implement,\n * used by the central handler in main.ts and by EventsWatcher.\n */\nexport interface Bot {\n start(): Promise<void>;\n postMessage(channel: string, text: string): Promise<string>;\n updateMessage(channel: string, ts: string, text: string): Promise<void>;\n enqueueEvent(event: BotEvent): boolean;\n getPlatformInfo(): PlatformInfo;\n}\n\n/** Pre-created platform adapters passed to the handler */\nexport interface BotAdapters {\n message: ChatMessage;\n responseCtx: ChatResponseContext;\n platform: PlatformInfo;\n}\n\n/**\n * Handler callbacks invoked by each platform bot.\n * Each bot creates platform-specific adapters before calling handleEvent.\n */\nexport interface RunningSession {\n sessionKey: string;\n startedAt: number; // Date.now() when run started\n /** Last activity timestamp (for detecting hung tasks) */\n lastActivityAt?: number;\n /** Current tool/step being executed (if any) */\n currentTool?: string;\n}\n\nexport interface BotHandler {\n isRunning(sessionKey: string): boolean;\n getRunningSessions(): RunningSession[];\n handleEvent(event: BotEvent, bot: Bot, adapters: BotAdapters, isEvent?: boolean): Promise<void>;\n handleStop(sessionKey: string, conversationId: string, bot: Bot): Promise<void>;\n /** Force stop a running session (bypass normal stop mechanism) */\n forceStop(sessionKey: string): void;\n /** Reset a session: abort if running, delete history, remove from cache */\n handleNew(sessionKey: string, conversationId: string, bot: Bot): Promise<void>;\n}\n"]}
|
|
@@ -18,8 +18,8 @@ export declare class DiscordBot implements Bot {
|
|
|
18
18
|
workingDir: string;
|
|
19
19
|
});
|
|
20
20
|
start(): Promise<void>;
|
|
21
|
-
postMessage(
|
|
22
|
-
updateMessage(
|
|
21
|
+
postMessage(channel: string, text: string): Promise<string>;
|
|
22
|
+
updateMessage(channel: string, ts: string, text: string): Promise<void>;
|
|
23
23
|
enqueueEvent(event: BotEvent): boolean;
|
|
24
24
|
getPlatformInfo(): PlatformInfo;
|
|
25
25
|
updateMessageRaw(channelId: string, messageId: string, text: string): Promise<void>;
|
|
@@ -28,6 +28,7 @@ export declare class DiscordBot implements Bot {
|
|
|
28
28
|
deleteMessageRaw(channelId: string, messageId: string): Promise<void>;
|
|
29
29
|
sendTyping(channelId: string): Promise<void>;
|
|
30
30
|
uploadFile(channelId: string, filePath: string, title?: string): Promise<void>;
|
|
31
|
+
sendDirectMessage(userId: string, text: string): Promise<string>;
|
|
31
32
|
getAllChannels(): {
|
|
32
33
|
id: string;
|
|
33
34
|
name: string;
|
|
@@ -40,18 +41,20 @@ export declare class DiscordBot implements Bot {
|
|
|
40
41
|
logToFile(channelId: string, entry: object): void;
|
|
41
42
|
logBotResponse(channelId: string, text: string, ts: string): void;
|
|
42
43
|
/**
|
|
43
|
-
* Process attachments from a Discord message
|
|
44
|
-
* Downloads files
|
|
45
|
-
* Returns format compatible with ChatMessage: { name: string, localPath: string }[]
|
|
44
|
+
* Process attachments from a Discord message.
|
|
45
|
+
* Downloads files before returning so the agent can read them immediately.
|
|
46
46
|
*/
|
|
47
|
-
processAttachments(channelId: string, attachments: Collection<string, Attachment>, _messageId: string): {
|
|
47
|
+
processAttachments(channelId: string, attachments: Collection<string, Attachment>, _messageId: string): Promise<{
|
|
48
48
|
name: string;
|
|
49
49
|
localPath: string;
|
|
50
|
-
}[]
|
|
50
|
+
}[]>;
|
|
51
51
|
private downloadAttachment;
|
|
52
52
|
private getQueue;
|
|
53
|
+
private resolveStopTarget;
|
|
53
54
|
private loadCachedGuildData;
|
|
54
55
|
private stripBotMention;
|
|
56
|
+
private resolveConversationContext;
|
|
57
|
+
private createSessionSlashAdapters;
|
|
55
58
|
private setupEventHandlers;
|
|
56
59
|
private fetchTextChannel;
|
|
57
60
|
}
|