From a7e0fa08e70bd261c944fc1b84f103a24ef40bfc Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 23 May 2026 11:58:20 +0100 Subject: [PATCH] docs: expand meeting notes docs --- docs/.i18n/glossary.zh-CN.json | 16 +++ docs/cli/meeting-notes.md | 62 +++++++- docs/plugins/meeting-notes.md | 250 ++++++++++++++++++++++++++++++--- 3 files changed, 307 insertions(+), 21 deletions(-) diff --git a/docs/.i18n/glossary.zh-CN.json b/docs/.i18n/glossary.zh-CN.json index ed1af0a0bcd..2427d48a664 100644 --- a/docs/.i18n/glossary.zh-CN.json +++ b/docs/.i18n/glossary.zh-CN.json @@ -1035,6 +1035,22 @@ "source": "Gateway exposure runbook", "target": "Gateway 暴露运行手册" }, + { + "source": "Meeting Notes CLI", + "target": "Meeting Notes CLI" + }, + { + "source": "Discord voice", + "target": "Discord 语音" + }, + { + "source": "Plugin management", + "target": "插件管理" + }, + { + "source": "Plugin architecture", + "target": "插件架构" + }, { "source": "Z.AI (GLM)", "target": "Z.AI (GLM)" diff --git a/docs/cli/meeting-notes.md b/docs/cli/meeting-notes.md index 4102a669e68..6f383a29a2c 100644 --- a/docs/cli/meeting-notes.md +++ b/docs/cli/meeting-notes.md @@ -14,6 +14,10 @@ is read-only and is available when that plugin is installed or loaded from source. Capture, import, and summarization are owned by the `meeting_notes` agent tool and by configured auto-start sources. +Use the CLI when you want to find yesterday's notes, open the Markdown file in +an editor, feed a transcript to another tool, or debug where a session landed on +disk. It does not start or stop capture. + Artifacts live under the OpenClaw state directory: ```text @@ -25,7 +29,8 @@ $OPENCLAW_STATE_DIR/meeting-notes/YYYY-MM-DD// ``` The default state directory is `~/.openclaw`; set `OPENCLAW_STATE_DIR` to use a -different one. The date directory comes from the session start time. +different one. The date directory comes from the session start time, and the +session directory is a safe filesystem segment derived from the session id. ## Commands @@ -36,9 +41,11 @@ openclaw meeting-notes show YYYY-MM-DD/ openclaw meeting-notes path openclaw meeting-notes path YYYY-MM-DD/ openclaw meeting-notes path --dir +openclaw meeting-notes path --metadata openclaw meeting-notes path --transcript openclaw meeting-notes list --json openclaw meeting-notes show --json +openclaw meeting-notes path --json ``` - `list`: list stored sessions, date-qualified selector, start time, title, and `summary.md` path. @@ -54,5 +61,58 @@ from `list`, for example `openclaw meeting-notes show 2026-05-22/standup`. Default session ids include a timestamp and random suffix; configure fixed session ids only when they are unique within the day. +## Output + +`list` prints one session per line: + +```text +2026-05-22/standup 2026-05-22T09:00:00.000Z Weekly standup /Users/alex/.openclaw/meeting-notes/2026-05-22/standup/summary.md +``` + +The output is tab-separated. The columns are selector, start time, title, and +summary path. The selector is the safest value to pass back to `show` or `path`. + +`list --json` prints objects with: + +- `sessionId` +- `selector` +- `date` +- `title` +- `startedAt` +- `stoppedAt` +- `source` +- `path` +- `summaryPath` +- `hasSummary` + +`show --json` returns the stored session metadata, selector, session directory, +summary path, and summary Markdown text. `path --json` returns the selected path +and whether that file exists. + +## Many meetings per day + +Meeting Notes groups sessions by date, then by session id. Ten meetings on one +day become ten sibling folders: + +```text +~/.openclaw/meeting-notes/2026-05-22/ + meeting-2026-05-22T09-00-00-000Z-a1b2c3d4/ + meeting-2026-05-22T10-30-00-000Z-b2c3d4e5/ + standup/ +``` + +Use default generated ids for most automation. Use a fixed id such as `standup` +only when the same id will not be used twice on the same date. + +## Missing summaries + +Live sessions write `summary.md` when the session stops. Imported transcripts +write `summary.md` immediately after import. A session can still appear in +`list` without a summary when capture is active, a provider failed during stop, +or metadata was written before any utterances arrived. + +Use `path --transcript` to inspect the append-only transcript, and use +the `meeting_notes` tool action `summarize` to regenerate the Markdown summary. + See [Meeting Notes](/plugins/meeting-notes) for configuration, auto-start, and source-provider details. diff --git a/docs/plugins/meeting-notes.md b/docs/plugins/meeting-notes.md index 4adc38883c6..6962e81c014 100644 --- a/docs/plugins/meeting-notes.md +++ b/docs/plugins/meeting-notes.md @@ -9,7 +9,12 @@ title: "Meeting Notes plugin" The Meeting Notes plugin is the generic notes layer for live calls and imported meeting transcripts. It owns transcript storage, summary rendering, and the -`meeting_notes` tool. Channel plugins own capture. +`meeting_notes` tool. Channel plugins own capture, authentication, and +platform-specific meeting joins. + +Use this page when you want OpenClaw to capture Discord voice notes today, when +you want to import a transcript from another meeting system, or when you are +building a Google Meet, Slack huddle, Zoom, or calendar-owned source provider. ## Source model @@ -26,13 +31,82 @@ This keeps Discord, Google Meet, Slack huddles, and future meeting surfaces out of the notes engine. Each source supplies speaker-labeled utterances; Meeting Notes writes the artifacts and summary. -## Enable +## Install and enable Meeting Notes is an external source plugin in this repository. It is not part of the core OpenClaw npm package and becomes available only when the plugin is -installed or loaded from source. Once loaded, it is enabled by default unless -`plugins.enabled` is false, `plugins.deny` includes `meeting-notes`, or -`plugins.entries.meeting-notes.enabled` is false. +installed as a plugin or loaded from a source checkout that contains +`extensions/meeting-notes`. + +Once the plugin is loaded, it is enabled by default unless one of these settings +blocks it: + +- `plugins.enabled: false` disables all plugins. +- `plugins.deny` contains `meeting-notes`. +- `plugins.allow` is set and does not contain `meeting-notes`. +- `plugins.entries.meeting-notes.enabled: false` disables this plugin entry. +- `plugins.entries.meeting-notes.config.enabled: false` keeps the plugin loaded + but disables the `meeting_notes` tool and auto-start service. + +The normal user config file is `~/.openclaw/openclaw.json`. The `plugins` +section controls plugin loading, and the nested `entries..config` +object is passed to that plugin as plugin-specific config. A separate +`config: { ... }` block under `meeting-notes` is expected; it is how plugins +receive their own options without adding core config keys. + +Use this shape when your config has a plugin allowlist: + +```json5 +{ + plugins: { + allow: ["discord", "meeting-notes"], + entries: { + "meeting-notes": { + enabled: true, + config: { + enabled: true, + maxUtterances: 2000, + autoStart: [], + }, + }, + }, + }, +} +``` + +Run a config check after editing: + +```bash +openclaw config validate +``` + +Gateway config hot reload applies plugin allowlist and plugin-entry changes. +Restart the Gateway if you are also changing the source plugin itself, installing +new plugin files, or changing Discord voice credentials. + +## Configuration + +Meeting Notes has three plugin config fields: + +- `enabled`: `true` by default. Set `false` to leave the plugin installed but + disable the tool and auto-start service. +- `maxUtterances`: `2000` by default. Summary generation reads only the newest + N utterances from `transcript.jsonl`; valid values are clamped to `1` through + `10000`. +- `autoStart`: empty by default. Each entry starts a live notes source when the + Gateway starts or reloads the plugin. + +An `autoStart` entry accepts: + +- `providerId`: required. Use `discord-voice` for Discord voice. +- `enabled`: optional, default `true`. Set `false` to keep an entry without + starting it. +- `sessionId`: optional. If omitted, OpenClaw generates a timestamped id. +- `title`: optional human-readable title for summaries and CLI output. +- `accountId`: optional source account id when more than one account exists. +- `guildId`: provider-specific Discord guild id. +- `channelId`: provider-specific Discord voice channel id. +- `meetingUrl`: provider-specific meeting URL for browser or calendar sources. Use `autoStart` when OpenClaw should begin notes capture automatically on gateway startup: @@ -58,13 +132,53 @@ gateway startup: } ``` +Auto-start retries startup failures up to 12 times with a five-second delay. +This lets the notes service wait for channel plugins such as Discord to finish +initializing. Sessions that were started by auto-start are stopped and summarized +when the plugin service stops cleanly. + Discord voice capture still needs normal Discord voice setup and permissions. See [Discord voice](/channels/discord#voice-mode). -Transcription uses the normal audio understanding stack configured under -`tools.media.audio`. If no explicit audio model is configured, OpenClaw tries -configured provider keys first, then local audio engines such as `sherpa-onnx`, -`whisper-cli`, or `whisper` when available. +## Discord voice + +Discord is the first live source. The Discord plugin owns the voice connection, +speaker detection, audio decoding, and transcription. Meeting Notes receives +final speaker-labeled utterances and persists them. + +For Discord live capture: + +- Enable and configure the Discord plugin first. +- Configure Discord voice mode so OpenClaw can join the target voice channel. +- Use `providerId: "discord-voice"`. +- Provide `guildId` and `channelId`. +- Add `accountId` only when you run more than one Discord account. + +The transcription model is not chosen by Meeting Notes. In Discord `stt-tts` +voice mode, STT uses `tools.media.audio`; `voice.model` controls the agent reply +model, not transcription. In realtime voice modes, transcription follows the +configured realtime provider and model. See [Discord voice](/channels/discord#voice-mode) +for the current Discord voice model and provider knobs. + +## Google Meet, Slack huddles, and other sources + +Meeting Notes is intentionally source-neutral. Google Meet, Slack huddles, Zoom, +calendar recordings, or browser caption capture should be separate source +providers that register with the plugin SDK. + +Recommended source choices: + +- Google Meet live browser/caption support: implement a `live-caption` provider + that accepts `meetingUrl` and emits final caption utterances. +- Google Meet recordings or downloaded transcripts: implement + `posthoc-transcript` or use `manual-transcript` until a provider exists. +- Slack huddles today: import post-meeting huddle notes or transcript artifacts. + Slack does not expose a general bot-join live huddle audio API. +- Slack huddles later: keep the Slack-owned source provider responsible for + Slack auth, artifact lookup, and transcript normalization. + +The notes engine should not contain platform joins, browser automation, Slack +API polling, or Discord voice logic. Those belong to the owning source plugin. ## Tool @@ -109,21 +223,61 @@ Import a transcript: } ``` +`manual-transcript` splits plain transcript text into utterances. Use it for +copied Google Meet notes, Slack huddle summaries, calendar transcripts, or any +source that already produced text. + +## Storage layout + Artifacts are stored under the OpenClaw state directory: -- `meeting-notes/YYYY-MM-DD//metadata.json` -- `meeting-notes/YYYY-MM-DD//transcript.jsonl` -- `meeting-notes/YYYY-MM-DD//summary.json` -- `meeting-notes/YYYY-MM-DD//summary.md` +```text +$OPENCLAW_STATE_DIR/meeting-notes/YYYY-MM-DD// + metadata.json + transcript.jsonl + summary.json + summary.md +``` + +If `OPENCLAW_STATE_DIR` is unset, the default state directory is +`~/.openclaw`. A normal local install therefore writes notes under +`~/.openclaw/meeting-notes/...`. + +Each file has one job: + +- `metadata.json`: session id, source provider, title, start time, stop time, + and provider metadata. +- `transcript.jsonl`: append-only speaker utterances. Each line is one JSON + object with the utterance text and the session id. +- `summary.json`: structured summary data used by tooling. +- `summary.md`: human-readable notes for terminals, editors, and document + workflows. The date directory comes from the session start time, so multiple meetings per day stay grouped. If a human session id repeats across days, use the date-qualified selector from `openclaw meeting-notes list`, such as `2026-05-22/standup`. -By default, OpenClaw generates timestamped session ids, so many meetings on the -same day get separate directories. Configure `sessionId` only when that id is -unique for the day. +By default, OpenClaw generates timestamped session ids: + +```text +meeting-2026-05-22T10-00-00-000Z-a1b2c3d4 +``` + +That means ten meetings on the same day become ten sibling directories: + +```text +~/.openclaw/meeting-notes/2026-05-22/ + meeting-2026-05-22T09-00-00-000Z-a1b2c3d4/ + meeting-2026-05-22T10-30-00-000Z-b2c3d4e5/ + meeting-2026-05-22T13-00-00-000Z-c3d4e5f6/ +``` + +Configure `sessionId` only when that id is unique for the day. Human ids such as +`standup` are fine for one recurring meeting per day. If the same id appears on +multiple days, use the date-qualified selector in the CLI. + +## CLI access Use the read-only CLI to find or print stored summaries: @@ -131,17 +285,73 @@ Use the read-only CLI to find or print stored summaries: openclaw meeting-notes list openclaw meeting-notes show openclaw meeting-notes path +openclaw meeting-notes path --transcript ``` See [Meeting Notes CLI](/cli/meeting-notes) for the full command reference. +## Long meetings + For long meetings, utterances are appended to `transcript.jsonl` as they arrive. Summary generation reads a bounded window controlled by `plugins.entries.meeting-notes.config.maxUtterances` (default: `2000`) so a multi-hour call does not require unbounded summary memory. -## Slack Huddles +This means the transcript can keep growing on disk, while summarization stays +bounded. Increase `maxUtterances` when you need more of a multi-hour meeting in +the generated summary. Decrease it when summaries are too slow or too large. -Slack huddles should use a post-meeting source first. Slack does not expose a -general bot-join live huddle audio API, but Slack huddle notes and transcript -artifacts can be imported later by a Slack-owned provider. +Current summaries are generated when a session stops, after an import, or when +the `summarize` action runs. They are not continuously rewritten for every +utterance. + +## Troubleshooting + +### `meeting_notes` is missing + +Check that the plugin is installed or loaded from source, and that plugin +loading does not exclude it: + +```bash +openclaw config validate +openclaw meeting-notes list +``` + +If `plugins.allow` is set, it must include `meeting-notes`. If `plugins.deny` +contains `meeting-notes`, remove it. + +### Auto-start does not join Discord + +Confirm the `autoStart` entry uses `providerId: "discord-voice"` and includes +both `guildId` and `channelId`. If you run multiple Discord accounts, include +`accountId`. Also verify Discord voice works outside Meeting Notes by joining +the same voice channel through the Discord voice commands. + +### Summary is missing + +Live sessions write `summary.md` when stopped. Stop the session with +`meeting_notes` action `stop`, then inspect it: + +```bash +openclaw meeting-notes list +openclaw meeting-notes path +``` + +Use `meeting_notes` action `summarize` to regenerate `summary.md` for an +existing stored session. + +### Selector is ambiguous + +If you reused a human session id such as `standup`, use the date-qualified +selector shown by `openclaw meeting-notes list`: + +```bash +openclaw meeting-notes show 2026-05-22/standup +``` + +## Related + +- [Meeting Notes CLI](/cli/meeting-notes) +- [Discord voice](/channels/discord#voice-mode) +- [Plugin management](/tools/plugin) +- [Plugin architecture](/plugins/architecture)