Skip to content

docs: office-assistant MVP example workflows#166

Merged
michaelmcnees merged 3 commits into
mainfrom
claude/office-assistant-mantle-feasibility-n8f4bk
Jul 2, 2026
Merged

docs: office-assistant MVP example workflows#166
michaelmcnees merged 3 commits into
mainfrom
claude/office-assistant-mantle-feasibility-n8f4bk

Conversation

@michaelmcnees

@michaelmcnees michaelmcnees commented Jul 2, 2026

Copy link
Copy Markdown
Collaborator

Summary

Implements the two-workflow office-assistant MVP from #161 as runnable examples plus a guide. It turns a pasted meeting transcript into structured notes and answers questions from a company-wide knowledge base, using only stock connectors.

Changes

  • examples/office-assistant-ingest-meeting.yamlai/completion (with output_schema) summarizes a pasted transcript and extracts action items → postgres/query stores the note in the KB → jira/create_issue opens a checklist issue for the action items (skipped if none) → teams/send_message posts the summary.
  • examples/office-assistant-ask.yamlpostgres/query full-text search ranks the most relevant notes → ai/completion synthesizes a grounded, cited answer (read from the CLI output).
  • examples/office-assistant-kb-schema.sql — the knowledge-base schema: a weighted tsvector column + GIN index. Pure Postgres full-text search, no extensions.
  • docs/office-assistant-mvp.md — setup (credentials + schema), usage for both workflows, and the caveats.

Design notes

  • Retrieval is full-text search, not embeddings. This keeps the whole flow runnable on existing connectors (no vector-array formatting through CEL). The schema comment documents the pgvector upgrade path; native RAG is tracked by [Feature] Knowledge base & retrieval (RAG) subsystem — embeddings, vector store, retrieval step #153.
  • One Jira issue per meeting, not per action item — the engine has no loop/for_each construct yet, so a single checklist issue is the clean one-step equivalent.
  • Cross-run state lives in Postgres, so ingesting builds a corpus that asking reads back.

Testing

  • Both workflows pass mantle validate (offline schema validation).
  • make test — n/a; this PR only touches packages/site/** (no engine code, so Engine CI path filters don't trigger).
  • End-to-end (transcript → notes/Jira/Teams, question → grounded answer) requires live OpenAI/Postgres/Jira/Teams credentials, so it can't run in CI; the guide documents how to exercise it.

Related Issues

Implements the MVP workflows described in #161 (which also tracks the broader vision — #153#160). Leaving #161 open for the maintainer to decide.


Generated by Claude Code

Summary by CodeRabbit

  • New Features

    • Added an “office assistant” MVP guide with end-to-end steps for meeting ingestion and Q&A.
    • Included new example workflows for importing meeting transcripts and asking grounded questions from stored meeting notes.
    • Added a database setup script for the meeting notes knowledge base and full-text search.
  • Documentation

    • Documented required credentials, setup commands, workflow inputs, and MVP limitations.

Two manually-run workflows plus a Postgres full-text knowledge base that
implement the office-assistant MVP:

- office-assistant-ingest-meeting.yaml: LLM summarizes a pasted
  transcript and extracts action items, stores the note in the KB,
  opens a Jira issue, and posts the summary to Teams.
- office-assistant-ask.yaml: full-text searches the KB and has an LLM
  synthesize a grounded, cited answer.
- office-assistant-kb-schema.sql: the tsvector-backed KB schema (v0
  retrieval; pgvector upgrade path noted, tracked by #153).
- docs/office-assistant-mvp.md: setup, usage, and caveats.

Retrieval is Postgres full-text search rather than embeddings so the
whole flow runs on stock connectors. Both workflows pass `mantle
validate`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WnKgCRfMvFcZAkoVbr8k79
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@michaelmcnees, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 48 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2c288936-620a-49a6-875b-1c5cd15239e1

📥 Commits

Reviewing files that changed from the base of the PR and between 6d0413e and ab1d6fb.

📒 Files selected for processing (4)
  • packages/site/src/content/docs/office-assistant-mvp.md
  • packages/site/src/content/examples/office-assistant-ask.yaml
  • packages/site/src/content/examples/office-assistant-ingest-meeting.yaml
  • packages/site/src/content/examples/office-assistant-kb-schema.sql
📝 Walkthrough

Walkthrough

Adds a new office-assistant example: a Postgres knowledge-base schema, an ingest-meeting workflow (AI summarization, DB insert, conditional Jira issue, Teams post), an ask-question workflow (full-text search plus grounded AI answer), and a documentation page describing prerequisites, usage, and MVP limitations.

Changes

Office-assistant MVP

Layer / File(s) Summary
Knowledge base schema
packages/site/src/content/examples/office-assistant-kb-schema.sql
Creates meeting_notes table with a generated weighted full-text search tsvector column and a GIN index.
Meeting ingestion workflow
packages/site/src/content/examples/office-assistant-ingest-meeting.yaml
Defines a workflow that summarizes a transcript via AI, inserts data into Postgres, conditionally creates a Jira issue, and posts a Teams notification.
Question answering workflow
packages/site/src/content/examples/office-assistant-ask.yaml
Defines a workflow that full-text searches meeting_notes and produces a grounded, cited AI answer.
MVP documentation
packages/site/src/content/docs/office-assistant-mvp.md
Documents prerequisites, schema setup, usage of both workflows, and MVP scope/limitations.

Estimated code review effort: 2 (Simple) | ~12 minutes

Possibly related issues

Poem

Hop, hop, hooray, a new KB is born,
Meetings tucked into Postgres each morn.
Ask a question, get answers with cite,
Jira and Teams pinged, all set right.
This bunny thumps twice for docs done just right! 🐇📋

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main change: new office-assistant MVP documentation and example workflows.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/office-assistant-mantle-feasibility-n8f4bk

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6d0413e0a9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +61 to +62
required:
- title

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Require every action item field in strict schema

With the default OpenAI credential used by this workflow, the AI connector sends every output_schema as response_format.json_schema with strict: true (packages/engine/internal/connector/provider_openai.go:58-65). OpenAI rejects strict object schemas when declared properties are omitted from required; this item schema declares description and owner but only requires title, so the summarize step fails with an API 400 before the meeting can be stored or posted. Make those fields required, or keep them required and allow null values for missing owners/descriptions.

Useful? React with 👍 / 👎.


| Credential name | Type | Used for |
| --------------- | ---- | -------- |
| `openai` | `openai` | `ai/completion` (summarize + answer). Swap the `credential:` and `model:` for `bedrock` to use Claude via Bedrock. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include the provider flag in Bedrock instructions

Following this guidance by changing only credential: and model: still runs the OpenAI provider, because ai/completion defaults params.provider to openai unless provider: bedrock is set (packages/engine/internal/connector/ai.go:24-27, and the Bedrock branch is selected only at ai.go:101). Users trying the documented Bedrock swap will send an OpenAI-compatible request with AWS credentials and fail; the setup should instruct them to add provider: bedrock (and usually region) in both AI steps.

Useful? React with 👍 / 👎.

Addresses PR review feedback:

- ingest-meeting: OpenAI structured output is sent with strict:true, which
  requires every declared property to appear in `required`. The
  action_items item schema listed description/owner but only required
  title, so the summarize step would 400. Make them required and nullable
  (type: [string, null]) so absent values are expressible.
- docs: the Bedrock swap needs `provider: bedrock` (+ region); provider
  defaults to openai, so changing only credential/model still sends an
  OpenAI-format request. Corrected the guidance.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WnKgCRfMvFcZAkoVbr8k79

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
packages/site/src/content/examples/office-assistant-kb-schema.sql (1)

13-31: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

No idempotency/dedup safeguard on meeting_notes.

The table has no unique/natural key. If the store-note insert in office-assistant-ingest-meeting.yaml is ever retried (transient DB error, workflow re-run), the same meeting will be duplicated in the knowledge base, degrading office-assistant-ask.yaml search results with redundant hits. Worth adding a dedup key (e.g. a hash of transcript, or a caller-supplied external_id) with a unique index, paired with ON CONFLICT DO NOTHING/DO UPDATE on insert.

♻️ Example dedup key
     transcript    TEXT NOT NULL,
     created_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
+    dedupe_key    TEXT GENERATED ALWAYS AS (md5(transcript)) STORED,
+CREATE UNIQUE INDEX IF NOT EXISTS idx_meeting_notes_dedupe
+    ON meeting_notes (dedupe_key);

Please verify whether the workflow engine retries postgres/query steps automatically — if it does, this becomes a more pressing fix.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/site/src/content/examples/office-assistant-kb-schema.sql` around
lines 13 - 31, The meeting_notes schema lacks an idempotency/dedup key, so
repeated inserts can create duplicate notes and pollute search results. Add a
unique natural key to the CREATE TABLE definition in
office-assistant-kb-schema.sql, such as an external_id or a hash-derived dedup
column, and enforce it with a unique constraint or index. Then update the
store-note insert path in office-assistant-ingest-meeting.yaml to use the new
key with ON CONFLICT DO NOTHING or DO UPDATE, and keep office-assistant-ask.yaml
compatible with the deduped records.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/site/src/content/docs/office-assistant-mvp.md`:
- Around line 29-34: The KB schema setup command in the office-assistant-mvp
docs uses a relative filename that only works from the examples directory, so
update the text around the office-assistant-kb-schema.sql reference and the psql
command to use a path readers can run from the repo root or explicitly instruct
them to cd into the examples directory first. Make the command in
office-assistant-mvp.md match the actual location of
office-assistant-kb-schema.sql so copy/paste works without guessing.
- Around line 68-70: The `office-assistant-ask` example is using `--input
question=...`, which may not match the documented runnable workflow for this
command. Update the example in the office-assistant MVP docs to use the same
invocation style as the rest of the `office-assistant-ask`/`mantle run`
workflow, and verify the CLI flags supported by `office-assistant-ask` so the
snippet is copy/pasteable without relying on unsupported `--input` syntax.

In `@packages/site/src/content/examples/office-assistant-ingest-meeting.yaml`:
- Around line 99-113: The create-action-items step is sending markdown directly
to jira/create_issue, which wraps description as plain-text ADF and will render
the checklist literally. Update the create-action-items params to convert
steps['summarize'].output.json.action_items_markdown into Jira-compatible ADF
before passing it to jira/create_issue, keeping the summarize output and
action-items flow intact.
- Around line 80-97: The store-note postgres/query step is missing both a
deadline and deduplication protection, so update the meeting note insert to use
an explicit timeout in the step context and make the write idempotent with a
dedupe key plus ON CONFLICT handling. Locate the change in the store-note block
and adjust the insert into meeting_notes and its args so retries or re-runs
won’t create duplicate rows.

---

Nitpick comments:
In `@packages/site/src/content/examples/office-assistant-kb-schema.sql`:
- Around line 13-31: The meeting_notes schema lacks an idempotency/dedup key, so
repeated inserts can create duplicate notes and pollute search results. Add a
unique natural key to the CREATE TABLE definition in
office-assistant-kb-schema.sql, such as an external_id or a hash-derived dedup
column, and enforce it with a unique constraint or index. Then update the
store-note insert path in office-assistant-ingest-meeting.yaml to use the new
key with ON CONFLICT DO NOTHING or DO UPDATE, and keep office-assistant-ask.yaml
compatible with the deduped records.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f9129535-f31e-45e3-9e58-67b41c999aa1

📥 Commits

Reviewing files that changed from the base of the PR and between bbdaf9e and 6d0413e.

📒 Files selected for processing (4)
  • packages/site/src/content/docs/office-assistant-mvp.md
  • packages/site/src/content/examples/office-assistant-ask.yaml
  • packages/site/src/content/examples/office-assistant-ingest-meeting.yaml
  • packages/site/src/content/examples/office-assistant-kb-schema.sql

Comment thread packages/site/src/content/docs/office-assistant-mvp.md
Comment on lines +68 to +70
mantle run office-assistant-ask \
--input question="Who else is working with client C?" \
--output json

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Align the ask command with the runnable workflow.

The paired office-assistant-ask example is documented as a values-file run, but this snippet switches to --input question=.... If --input is not supported here, the example won’t copy/paste cleanly.

Proposed fix
 mantle run office-assistant-ask \
-  --input question="Who else is working with client C?" \
+  --values q.yaml \
   --output json
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
mantle run office-assistant-ask \
--input question="Who else is working with client C?" \
--output json
mantle run office-assistant-ask \
--values q.yaml \
--output json
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/site/src/content/docs/office-assistant-mvp.md` around lines 68 - 70,
The `office-assistant-ask` example is using `--input question=...`, which may
not match the documented runnable workflow for this command. Update the example
in the office-assistant MVP docs to use the same invocation style as the rest of
the `office-assistant-ask`/`mantle run` workflow, and verify the CLI flags
supported by `office-assistant-ask` so the snippet is copy/pasteable without
relying on unsupported `--input` syntax.

CodeRabbit review follow-ups on the office-assistant MVP:

- KB schema: add a dedupe_key (md5(transcript)) + unique index; the
  store-note insert now uses ON CONFLICT DO NOTHING so retries/re-runs
  don't create duplicate notes that would pollute search.
- ingest: gate the Jira and Teams steps on rows_affected > 0 so a
  duplicate re-ingest is a clean no-op; add a 15s timeout to the DB write
  (and to the ask search).
- ingest: jira/create_issue wraps description as plain-text ADF, so
  markdown rendered literally — the LLM now emits a plain-text action-item
  rendering (action_items_text) used as the Jira description.
- docs: use the full repo-root path in the psql schema-load command.

Kept the `ask` example's `--input question=...` — that flag is supported
by `mantle run`. Both workflows still pass `mantle validate`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WnKgCRfMvFcZAkoVbr8k79

Copy link
Copy Markdown
Collaborator Author

Thanks — addressed the review in ab1d6fb:

  • Dedup / idempotency ✅ — added a dedupe_key (md5(transcript)) + unique index to the schema; store-note now uses ON CONFLICT (dedupe_key) DO NOTHING. I also gated the Jira and Teams steps on rows_affected > 0, so re-ingesting the same transcript is a clean no-op (no duplicate note, no duplicate issue/notification). Confirmed the engine only retries steps that opt in via retry: (none here), but this also covers manual re-runs.
  • Timeout ✅ — added timeout: "15s" to the DB write (and to the ask search).
  • Jira description ✅ — jira/create_issue wraps description as a plain-text ADF paragraph, so markdown rendered literally. The LLM now emits a plain-text action_items_text rendering, which is what the Jira description uses.
  • Schema path in docs ✅ — command now uses the full repo-root path.
  • ask uses --input question=... — keeping this: mantle run does support --input key=value (repeatable), so the snippet is copy-pasteable as written; --input is the simplest form for a single value.

Both workflows still pass mantle validate.


Generated by Claude Code

@michaelmcnees michaelmcnees merged commit 32557fc into main Jul 2, 2026
5 checks passed
@michaelmcnees michaelmcnees deleted the claude/office-assistant-mantle-feasibility-n8f4bk branch July 2, 2026 03:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants