feat: add conversations command group (v1.1.0) - #7
Conversation
Apollo's recorded-conversation endpoints (Zoom/Teams/Meet transcripts + AI summaries) were fully supported by qodev-apollo-api but had no CLI surface. This exposes them: - `apollo conversations search [--query]` -> search_conversations - `apollo conversations get ID` -> get_conversation (full detail) The detail view surfaces the metadata, participants, associated deals, the AI call summary (outcome, pain points, objections, next steps) and the full transcript — the payload that makes the detail endpoint useful. Distinct from `calls`, which is dialer/phone-call activity, not recorded meetings. Registered in app.py; SKILL.md and README updated; command, formatter, and formatter/command tests added. Bumps to 1.1.0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Adds the new conversations command group with solid CLI wiring, docs, and formatter coverage.
Improvement: format_conversation_detail() uses getattr() for nested sections (participants/deals/summary/transcript), which won’t render if it ever receives raw dicts.
Question: please double-check q_keywords is the correct filter name for search_conversations in the underlying client/API.
Found 2 issues (0 critical, 1 improvement, 0 nits, 1 question).
| md = detail_table(data, CONVERSATION_DETAIL_FIELDS, title=f"Conversation: {topic}") | ||
|
|
||
| # Participants (richer than the participant_names list in the metadata table) | ||
| participants = getattr(data, "participants_info", None) or [] |
There was a problem hiding this comment.
Improvement: format_conversation_detail() (and _format_summary()) use getattr() for participants_info / deals / call_summary / transcript. If get_conversation() ever returns raw dicts (or nested dicts after model_dump elsewhere), these sections will silently render empty.
Fix: normalize
data/nested items via a small helper that supports both dicts and objects (or convert to a dict once and then use.get(...)throughout) so the rich detail view is robust regardless of return type.
| async def search( | ||
| *, | ||
| query: Annotated[str, Parameter(name=["--query", "-q"], help="Search keyword (topic/title)")] = "", | ||
| ) -> None: |
There was a problem hiding this comment.
Question: is q_keywords the correct filter name for search_conversations? (It’s hard to infer from the CLI alone.)
If the API uses a different param (e.g.
q_keyword/query), this will look like it “works” but never filters. A unit test that asserts the exact kwargs (you already checkq_keywords) is good — just double-check it matches the client method signature.
What
Adds a
conversationscommand group exposing Apollo's recorded-conversation endpoints (Zoom/Teams/Meet). These were already fully supported inqodev-apollo-api(search_conversations/get_conversation) but had no CLI surface.The
getdetail view surfaces metadata, participants, associated deals, the AI call summary (outcome, pain points, objections, next steps), and the full transcript — the payload that makes the detail endpoint worth calling.Not to be confused with
callscallscovers dialer/phone-call activity;conversationscovers recorded meetings. They are different Apollo endpoints. SKILL.md and README now call this out.Changes
commands/conversations.py,formatters/conversations.py(new)app.pyConversationDetailmodelSKILL.md,README.mdVerification
ruff check✓ ·ruff format --check✓ ·mypy✓ ·pytest65 passed ✓🤖 Generated with Claude Code