Skip to content

feat(api): chat AI tools — tag CRUD, full executor routing, declarative ordering#185

Merged
thomasluizon merged 1 commit into
mainfrom
feature/chat-ai-tools
Jun 5, 2026
Merged

feat(api): chat AI tools — tag CRUD, full executor routing, declarative ordering#185
thomasluizon merged 1 commit into
mainfrom
feature/chat-ai-tools

Conversation

@thomasluizon

Copy link
Copy Markdown
Owner

Summary

One backend PR bundling four correlated chat-agent changes (implemented in dependency order: tag/goal chat tools + hard-case prerequisites → executor routing → ordering refactor).

#83 — Tag CRUD chat tools

  • New ListTagsTool/CreateTagTool/UpdateTagTool/DeleteTagTool (in TagTools.cs), each delegating to its existing MediatR handler.
  • Registered as IAiTool in DI and catalogued: tags.readlist_tags, tags.writecreate_tag/update_tag, tags.deletedelete_tag.

#89 — reorder_goals + write-tool test coverage

  • New ReorderGoalsTool (mirrors ReorderHabitsTool, schema positions[]={goal_id,position}, sends ReorderGoalsCommand); added to goals.write.
  • Unit tests for the four tag tools, reorder_goals, and get_referral_code; metadata test registers all six.

#88 — Full executor routing (no direct-MediatR mutation exceptions)

  • Every mutating MCP method in GoalTools, TagTools, ProfileTools, NotificationTools, UserFactTools, SubscriptionTools now routes through McpExecutorBridgeIAgentOperationExecutor (AgentExecutionSurface.Mcp), sharing policy evaluation + the AgentAuditLogs trail. Reads stay on MediatR.
  • Mismatched MCP methods map to consolidated chat ops (update_profile_preferences, update_notifications, delete_notifications, delete_user_facts).
  • Hard case Security hardening + DRY refactor #1assign_tags: AssignTagsTool gains an optional tag_ids id-path (tracked-load by id, replace-all, no auto-create); MCP forwards tag_ids, preserving its id-based external contract. The tag_names auto-create path is unchanged.
  • Hard case Add comprehensive unit test suite (282 tests) #2get_referral_code: new GetReferralCodeTool + new ReferralsWrite capability (referrals.write) + WriteReferrals scope (added to ClaudeDefaultScopes); get_referral_code removed from ReferralsRead.mcpTools.
  • Destructive routed deletes (goal/tag/notification/user-fact) accept and forward a confirmation token.
  • Additional mismatch found and fixed: chat update_goal_progress only accepted goal_name; widened to also accept goal_id so the MCP method can route losslessly.

#87 — Declarative tool ordering

  • int Order => int.MaxValue; default-interface member on IAiTool; create_habit=0, create_sub_habit=1, assign_tags=2.
  • ProcessUserChatCommand ordering uses registry.GetTool(name)?.Order ?? int.MaxValue (hardcoded switch removed; unknown tools now run last instead of tying with create_sub_habit).
  • New Chat/Tools/README.md documents the IAiTool contract, Order convention, the catalog-entry-required startup invariant, and the MCP-routes-through-executor relationship.

Validation

  • dotnet build Orbit.slnx: PASS (0 errors).
  • Orbit.Application.Tests: 1718 passed. Orbit.Infrastructure.Tests: 936 passed (incl. the six MCP toolset test files migrated to the executor-routed pattern).
  • McpMutationExecutorRoutingTests (new) + McpHabitExecutorRoutingTests: 9 passed — per-toolset audit-row + read-only-credential-denial assertions, the assign_tags id-path tag replacement, get_referral_codereferrals.write, and delete_user_facts pending-confirmation.
  • Pre-existing/environmental integration failures only (live-LLM chat tests with no provider in CI; ApiKeyTests 403s — both confirmed identical on the clean baseline).

Refs thomasluizon/orbit-ui-mobile#83, thomasluizon/orbit-ui-mobile#89, thomasluizon/orbit-ui-mobile#88, thomasluizon/orbit-ui-mobile#87

🤖 Generated with Claude Code

…ve ordering

Bundles four correlated chat-agent changes:

- #83: tag chat tools (list/create/update/delete_tag) delegating to existing
  MediatR handlers, registered in DI and catalogued under tags.read/write/delete.
- #89: ReorderGoalsTool (mirrors ReorderHabitsTool) + unit tests for the new/write
  tag and goal tools; reorder_goals added to GoalsWrite.chatTools.
- #88: full executor routing — every mutating MCP method (GoalTools, TagTools,
  ProfileTools, NotificationTools, UserFactTools, SubscriptionTools) now routes
  through McpExecutorBridge → IAgentOperationExecutor for shared policy + audit,
  mapping mismatched methods to their consolidated chat ops. Hard cases routed too:
  assign_tags via a new tag_ids id-path on AssignTagsTool (id-based, replace-all,
  no auto-create; MCP id contract unchanged) and get_referral_code via a new
  GetReferralCodeTool + ReferralsWrite capability + WriteReferrals scope (added to
  ClaudeDefaultScopes). Destructive routed deletes (goal/tag/notification/user-fact)
  accept and forward a confirmation token. No mutating MCP method remains on direct
  MediatR. update_goal_progress widened to accept goal_id so its MCP method can route.
- #87: tool ordering is now data — int Order default-interface member on IAiTool
  (create_habit=0, create_sub_habit=1, assign_tags=2, default int.MaxValue); the
  hardcoded switch in ProcessUserChatCommand is replaced by the registry lookup.
  Adds Chat/Tools/README.md documenting the contract, Order, catalog invariant, and
  MCP-routing relationship.

Existing MCP toolset unit tests migrated to the executor-routed pattern.

Refs thomasluizon/orbit-ui-mobile#83, thomasluizon/orbit-ui-mobile#89,
thomasluizon/orbit-ui-mobile#88, thomasluizon/orbit-ui-mobile#87

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@claude claude 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.

This lands four correlated chat-agent changes cleanly. The executor-routing refactor is the biggest structural move — every MCP mutation now flows through McpExecutorBridge → IAgentOperationExecutor, giving uniform ownership pre-checks, policy gating, and audit trails where previously each tool called MediatR directly. The new chat tools (tag CRUD, reorder_goals, get_referral_code) are all properly registered in DI and catalogued in AgentCatalogService (startup throws on any unmapped tool, so the catalog invariant is enforced). The IAiTool.Order default interface member cleanly replaces the hardcoded switch. The assign_tags id-path addition is backward-compatible, and moving get_referral_code to isMutation: true under referrals.write is semantically correct. Test coverage is solid: unit tests for all new tools, MCP unit tests migrated to the executor-routed pattern, and a dedicated McpMutationExecutorRoutingTests integration suite that verifies audit rows, PendingConfirmation gate, and read-only credential denial across the newly-routed toolsets.

@thomasluizon
thomasluizon merged commit f3ed8a8 into main Jun 5, 2026
4 checks passed
@thomasluizon
thomasluizon deleted the feature/chat-ai-tools branch June 5, 2026 21:16
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.

1 participant