|
| 1 | +--- |
| 2 | +title: Office-assistant MVP (meeting notes + Q&A) |
| 3 | +--- |
| 4 | + |
| 5 | +A minimal "office assistant" built from two manually-run workflows and a Postgres |
| 6 | +knowledge base: |
| 7 | + |
| 8 | +- **`office-assistant-ingest-meeting`** — paste a meeting transcript; an LLM |
| 9 | + summarizes it and extracts action items, the notes are stored in the KB, a Jira |
| 10 | + issue is opened for the action items, and the summary is posted to Teams. |
| 11 | +- **`office-assistant-ask`** — ask a question; the KB is full-text searched for |
| 12 | + the most relevant notes and an LLM synthesizes a grounded, cited answer. |
| 13 | + |
| 14 | +Cross-run state lives in Postgres, so ingesting builds up a corpus that asking |
| 15 | +reads back. Both workflows are in |
| 16 | +[`packages/site/src/content/examples/`](https://github.com/dvflw/mantle/tree/main/packages/site/src/content/examples). |
| 17 | + |
| 18 | +## Prerequisites |
| 19 | + |
| 20 | +Create these credentials (`mantle secrets create`) and the KB schema: |
| 21 | + |
| 22 | +| Credential name | Type | Used for | |
| 23 | +| --------------- | ---- | -------- | |
| 24 | +| `openai` | `openai` | `ai/completion` (summarize + answer) | |
| 25 | +| `kb-db` | `postgres` | The knowledge-base database | |
| 26 | +| `jira` | `basic` | `jira/create_issue` (email + API token) | |
| 27 | +| `teams` | `generic` | `teams/send_message` (incoming-webhook URL) | |
| 28 | + |
| 29 | +> **Using Claude via Bedrock instead of OpenAI:** in both `ai/completion` steps, |
| 30 | +> add `provider: bedrock` and a `region:` to `params`, point `credential:` at an |
| 31 | +> `aws` credential, and set `model:` to a Bedrock model ID. `provider` defaults |
| 32 | +> to `openai`, so changing only `credential`/`model` still sends an |
| 33 | +> OpenAI-format request. |
| 34 | +
|
| 35 | +Apply the KB schema (pure Postgres full-text search, no extensions) from |
| 36 | +[`office-assistant-kb-schema.sql`](https://github.com/dvflw/mantle/blob/main/packages/site/src/content/examples/office-assistant-kb-schema.sql): |
| 37 | + |
| 38 | +```bash |
| 39 | +psql "$KB_DATABASE_URL" -f packages/site/src/content/examples/office-assistant-kb-schema.sql |
| 40 | +``` |
| 41 | + |
| 42 | +Then apply both workflows: |
| 43 | + |
| 44 | +```bash |
| 45 | +mantle apply office-assistant-ingest-meeting.yaml |
| 46 | +mantle apply office-assistant-ask.yaml |
| 47 | +``` |
| 48 | + |
| 49 | +## Ingesting a meeting |
| 50 | + |
| 51 | +Put the transcript in a values file (a YAML block scalar handles long, |
| 52 | +multi-line text cleanly — there is no input size cap on manual runs): |
| 53 | + |
| 54 | +```yaml |
| 55 | +# meeting.values.yaml |
| 56 | +inputs: |
| 57 | + title: "Q3 strategy sync" |
| 58 | + meeting_date: "2026-07-01" |
| 59 | + attendees: "Michael, CTO, Team A lead" |
| 60 | + transcript: | |
| 61 | + <paste the full transcript here — as many lines as you like> |
| 62 | +``` |
| 63 | +
|
| 64 | +```bash |
| 65 | +mantle run office-assistant-ingest-meeting --values meeting.values.yaml |
| 66 | +``` |
| 67 | + |
| 68 | +The run summarizes the transcript, stores the note, opens a Jira action-item |
| 69 | +issue (skipped if the LLM found none), and posts the summary to Teams. |
| 70 | + |
| 71 | +## Asking a question |
| 72 | + |
| 73 | +```bash |
| 74 | +mantle run office-assistant-ask \ |
| 75 | + --input question="Who else is working with client C?" \ |
| 76 | + --output json |
| 77 | +``` |
| 78 | + |
| 79 | +The `search` step ranks matching notes with `websearch_to_tsquery`, and the |
| 80 | +`answer` step's `output.text` is the grounded answer (the CLI prints step |
| 81 | +outputs with `--output json` or `-v`). To send the answer somewhere instead of |
| 82 | +reading it from the CLI, add a final `teams/send_message` step. |
| 83 | + |
| 84 | +## What you own, and the caveats |
| 85 | + |
| 86 | +This is a deliberately small v0 that fits what the engine does today. Known |
| 87 | +trade-offs: |
| 88 | + |
| 89 | +- **Retrieval is full-text search, not semantic.** The KB uses a Postgres |
| 90 | + `tsvector`; there are no embeddings. It's the simplest thing that works |
| 91 | + end-to-end with stock connectors. A native embeddings + vector-store retrieval |
| 92 | + layer is tracked by [#153](https://github.com/dvflw/mantle/issues/153); the |
| 93 | + schema comment shows the upgrade path. |
| 94 | +- **One Jira issue per meeting**, not one per action item. The engine has no |
| 95 | + loop / `for_each` construct, so the workflow opens a single checklist issue |
| 96 | + rather than fanning out. |
| 97 | +- **Manual transcription.** You paste a transcript; the bot does not join |
| 98 | + meetings or transcribe audio (tracked by |
| 99 | + [#154](https://github.com/dvflw/mantle/issues/154)). |
| 100 | +- **Request/response, not a live Teams chat.** You ask via the CLI (or API) and |
| 101 | + optionally post the answer out; there is no conversational in-Teams bot |
| 102 | + (tracked by [#155](https://github.com/dvflw/mantle/issues/155)). |
| 103 | +- **Confluence / GitHub actions** aren't included here but drop in as extra |
| 104 | + `http/request` steps (or the native `jira`/`linear` connectors already used). |
| 105 | + |
| 106 | +See [#161](https://github.com/dvflw/mantle/issues/161) for the full MVP write-up |
| 107 | +and how these pieces map to the larger office-assistant vision. |
0 commit comments