Skip to content

Fix(cli): detect resolve intent and report intent_source#1006

Open
AdityaPainuli wants to merge 3 commits into
potpie-ai:mainfrom
AdityaPainuli:fix/996-resolve-intent-detection
Open

Fix(cli): detect resolve intent and report intent_source#1006
AdityaPainuli wants to merge 3 commits into
potpie-ai:mainfrom
AdityaPainuli:fix/996-resolve-intent-detection

Conversation

@AdityaPainuli

Copy link
Copy Markdown

Closes #996

Problem

potpie resolve "<task>" without --intent silently hardcodes intent=feature and prints it as if it was detected. No detection ever runs, so debugging and recent-change tasks get the feature retrieval shape (no timeline family), and the output misleads users into thinking the intent was classified.

What changed

  • Added detect_context_intent(task) in domain/agent_context_port.py: a deterministic, dependency-free keyword/phrase matcher (case-insensitive, word-boundary) seeded from the trigger language in each recipe's "when" field. Multi-match ties break via a documented priority order. Returns None when nothing matches, favoring no guess over a wrong guess, mirroring the ontology_classifier discipline.
  • CLI resolve: --intent default changed from "feature" to None. Effective intent now resolves explicit → detected → default (unknown), following the (value, resolved_via) pattern from resolve_pot_id/resolve_pot_scope.
  • The selection provenance rides the existing ResolveRequest.metadataAgentEnvelope.metadata passthrough as intent_source (explicit | detected | default). No downstream signature changes.
  • Both outputs surface it: JSON gets an intent_source key, the human header shows intent=<x> (source=<...>).

Vocabulary, recipes, normalize_context_intent, DEFAULT_INTENT_INCLUDES, and the MCP/HTTP surfaces are untouched. Correct detection routes recent-change/debugging tasks to timeline-bearing includes automatically via the existing intent→includes mapping.

Behavior

Command Before After
resolve "webhook throwing a 500 error" intent=feature intent=debugging (source=detected)
resolve "what changed recently in auth?" intent=feature, zero timeline items intent=review (source=detected), timeline included
resolve "xyz" (no match) intent=feature intent=unknown (source=default)
resolve "..." --intent docs intent=docs intent=docs (source=explicit)

Testing

  • 18 new unit tests: representative task→intent mappings, recent-change phrasing selects a timeline-bearing intent, empty/ambiguous input returns None, word-boundary anti-false-match ("latest" must not trigger test), CLI precedence, and intent_source in both output formats.
  • Full unit suite: 2063 passed, 1 skipped, 0 failures.
  • ruff check and ruff format clean (repo pre-commit config, v0.14.3).

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: bb4beb13-2482-4744-a4c7-b0bf810c920d

📥 Commits

Reviewing files that changed from the base of the PR and between f4140de and bf1ccd5.

📒 Files selected for processing (1)
  • potpie/context-engine/tests/unit/test_agent_context_port.py

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • The resolve command can infer intent from the task text when no intent is provided.
    • Responses now include an intent_source indicator (explicit, detected, or default), shown in both structured and human-readable output.
  • Bug Fixes
    • Improved intent detection using deterministic, word-boundary matching with priority-based tie-breaking to reduce false positives.
    • Added safe fallback behavior for empty or unclear task descriptions.
  • Tests
    • Expanded unit coverage for intent inference, intent_source surfacing, edge cases, and regressions.

Walkthrough

The resolve CLI now detects intent from task text when --intent is omitted, records whether intent was explicit, detected, or defaulted, and exposes that source in JSON and human-readable responses. Deterministic tests cover canonical matches, priority, blank input, and substring safety.

Changes

Resolve intent selection

Layer / File(s) Summary
Deterministic task intent detection
potpie/context-engine/domain/agent_context_port.py, potpie/context-engine/tests/unit/test_agent_context_port.py
Adds prioritized, case-insensitive, word-boundary intent detection with neutral results for blank or unmatched tasks, plus unit coverage.
Resolve intent selection and propagation
potpie/context-engine/adapters/inbound/cli/commands/query.py, potpie/context-engine/tests/unit/test_cli_resolve_intent.py
Combines explicit intent with task detection, defaults to unknown, and stores the selected intent source in ResolveRequest metadata.
Intent source response visibility
potpie/context-engine/adapters/inbound/cli/commands/query.py, potpie/context-engine/tests/unit/test_cli_resolve_intent.py
Adds intent_source to JSON envelopes and displays it in human-readable resolve summaries, including default fallback behavior.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ResolveCommand
  participant IntentDetector
  participant ResolveRequest
  participant ResponseEnvelope
  User->>ResolveCommand: run resolve with task
  ResolveCommand->>IntentDetector: detect intent when --intent is omitted
  IntentDetector-->>ResolveCommand: intent or no match
  ResolveCommand->>ResolveRequest: set intent and intent_source metadata
  ResolveRequest-->>ResponseEnvelope: provide resolve metadata
  ResponseEnvelope-->>User: display intent and source
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title concisely reflects the main CLI intent-detection and intent_source change.
Description check ✅ Passed The description clearly matches the CLI intent detection and intent_source updates.
Linked Issues check ✅ Passed The changes satisfy #996 by detecting intent, using an unknown fallback, surfacing intent_source, and improving timeline routing.
Out of Scope Changes check ✅ Passed The changes appear focused on the requested CLI intent behavior and related tests, with no clear unrelated additions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
📋 Issue Planner

Built with CodeRabbit's Coding Plans for faster development and fewer bugs.

View plan used: #996


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.

@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: 1

🤖 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 `@potpie/context-engine/domain/agent_context_port.py`:
- Around line 187-281: Add a consistency assertion adjacent to _INTENT_KEYWORDS
and _INTENT_DETECTION_PRIORITY that compares their intent-key sets and fails
clearly when either structure contains an intent missing from the other. Keep
_INTENT_MATCHERS construction unchanged, and ensure the guard runs before it
accesses _INTENT_MATCHERS[intent].
🪄 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: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4eeee886-7b71-45a9-8b96-35e036a63d0e

📥 Commits

Reviewing files that changed from the base of the PR and between a6ae3da and 88aa962.

📒 Files selected for processing (4)
  • potpie/context-engine/adapters/inbound/cli/commands/query.py
  • potpie/context-engine/domain/agent_context_port.py
  • potpie/context-engine/tests/unit/test_agent_context_port.py
  • potpie/context-engine/tests/unit/test_cli_resolve_intent.py

Comment thread potpie/context-engine/domain/agent_context_port.py
"""
if not task or not task.strip():
return None
for intent in _INTENT_DETECTION_PRIORITY:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nice work! I noticed there's good coverage for representative mappings and the fallback behavior, but I couldn't find a regression test for a task matching multiple intents.

Since detect_context_intent() relies on _INTENT_DETECTION_PRIORITY to resolve ties, would it make sense to add a regression test for a multi-match phrase? That would help ensure the documented priority order remains stable over time.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good catch, added. It pins four multi-match phrases ( security > debugging > operations > review > feature), and each case also guards-asserts the lower-priority intents genuinely match the phrase, so a future keyword change can't silently reduce the test to a single-match.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks for adding it! I like the extra guard assertions—they make the priority behavior much clearer and help ensure the test stays meaningful over time.

@nndn nndn requested a review from BrhKmr23 July 14, 2026 10:22
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.

CLI: resolve defaults to feature intent without detection

2 participants