Skip to content

feat(chatkit): Agentic UI Dashboard with Widget Actions - #21

Merged
mjunaidca merged 5 commits into
mainfrom
008-agentic-ui-dashboard
Dec 9, 2025
Merged

feat(chatkit): Agentic UI Dashboard with Widget Actions#21
mjunaidca merged 5 commits into
mainfrom
008-agentic-ui-dashboard

Conversation

@mjunaidca

Copy link
Copy Markdown
Owner

Summary

Implements a comprehensive agentic UI dashboard with interactive ChatKit widgets and captures critical debugging lessons from the implementation process.

What Changed

Backend Widget System

  • Widget Builders: Created modular widget builders for task lists, forms, audit timeline, and projects
  • Action Handler: Implemented server-side action handler with proper RequestContext usage
  • Local Tool Wrappers: Added MCP tool wrappers to trigger widget streaming via RunHooks pattern
  • Bug Fixes: Fixed Action.payload vs arguments issue, UserMessageItem validation errors

Frontend Dashboard

  • Workspace Page: New /workspace route with ChatKit integration
  • UI Components: Context badges, progress indicators, enhanced sidebar
  • ChatKit Config: Centralized configuration utilities

Documentation & Knowledge Capture

  • chatkit-actions Skill: Added critical implementation details section with common Pydantic errors
  • chatkit-integration Skill: New convergence patterns for type mismatches and auto-reload issues
  • Expert Agent: Enhanced anti-patterns and comprehensive testing checklist
  • Integration Agent: Added debugging patterns from this session

Key Technical Improvements

Fixed Critical Bugs

  1. ✅ Action object uses .payload not .arguments
  2. ✅ RequestContext should be used directly, not wrapped
  3. ✅ UserMessageItem requires: id, thread_id, created_at, inference_options
  4. ✅ UserMessageTextContent uses type="input_text" for user input

Widget Action Enhancements

  • Clear button labels (Start, Complete, Review, Approve, Reject, Unblock, Reopen)
  • Status-specific actions based on task lifecycle
  • Proper form field mapping (task.title, task.dueDate, etc.)

Knowledge Capture

All debugging lessons documented in skills/agents to prevent future similar issues:

  • Type annotation vs runtime mismatches
  • Pydantic validation requirements
  • Python auto-reload reliability warnings
  • Local tool wrapper pattern for widget streaming

Testing

  • ✅ Form widget appears and collects all fields
  • ✅ Task creation with form submission works
  • ✅ Status-specific buttons render correctly
  • ✅ Server actions (Start, Complete, Review) execute successfully
  • ✅ Widget updates after action completion
  • ✅ All validation errors resolved

Files Changed

Backend (15 files):

  • packages/api/src/taskflow_api/services/widgets/ - New widget builders
  • packages/api/src/taskflow_api/services/chatkit_server.py - Action handler fixes
  • packages/api/src/taskflow_api/services/chat_agent.py - Status workflow updates
  • packages/mcp-server/src/taskflow_mcp/tools/tasks.py - New show_task_form tool

Frontend (8 files):

  • web-dashboard/src/app/workspace/ - New workspace page
  • web-dashboard/src/components/chat/ - ChatKit widget enhancements
  • web-dashboard/src/lib/chatkit-config.ts - Configuration utilities

Documentation (4 files):

  • .claude/skills/engineering/chatkit-actions/SKILL.md
  • .claude/skills/engineering/chatkit-integration/SKILL.md
  • .claude/agents/engineering/chatkit-expert-agent.md
  • .claude/agents/engineering/chatkit-integration-agent.md

Specs & History (15 files):

  • specs/008-agentic-ui-dashboard/ - Complete spec, plan, tasks
  • history/prompts/agentic-ui-dashboard/ - PHR records

Future Work

  • Enhance MCP tool schema to support priority, assignee, due_date
  • Add widget actions for task deletion and reassignment
  • Implement real-time widget updates via WebSocket
  • Add widget action analytics/tracking

🤖 Generated with Claude Code

…et actions

## Summary
- Implemented interactive task widgets with status-specific action buttons
- Added clear button labels for all widget actions (Start, Complete, Review, etc.)
- Created comprehensive widget builders for task lists, forms, and confirmations
- Enhanced ChatKit skills/agents with critical debugging lessons and anti-patterns

## Backend Changes
- Widget builders: task_list, task_form, audit_timeline, projects
- Widget action handler with proper RequestContext handling
- Local tool wrappers for MCP → widget streaming
- Fixed Action.payload vs Action.arguments bug
- Fixed UserMessageItem required fields validation

## Frontend Changes
- Workspace page with ChatKit integration
- Context badges and progress indicators
- Enhanced sidebar with workspace navigation
- ChatKit configuration utilities

## Documentation Improvements
- Updated chatkit-actions skill with critical implementation details
- Added common Pydantic validation errors section
- Enhanced chatkit-integration skill with new convergence patterns
- Updated expert agent with comprehensive anti-patterns and checklist
- Added widget action testing checklist

## Key Learnings Captured
- Type annotation vs runtime mismatch (RequestContext)
- Action object uses payload, not arguments
- UserMessageItem required fields (id, thread_id, created_at, inference_options)
- Local tool wrappers needed for widget streaming via RunHooks
- Python auto-reload reliability issues

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings December 9, 2025 06:47

Copilot AI 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.

Pull request overview

This PR implements a comprehensive Agentic UI Dashboard feature that transforms the basic ChatKit integration into an interactive experience with widgets, server actions, and entity tagging. The implementation adds ~6,500 lines of code across backend widget systems, frontend workspace UI, and extensive documentation.

Key Changes

  • Backend Widget System: Modular builders for task lists, forms, audit timelines, and projects with server-side action handlers supporting widget interactions
  • Frontend Workspace: New /workspace route with full-page AI command center including context badges, progress indicators, and ChatKit integration
  • Knowledge Capture: Comprehensive documentation of debugging patterns, Pydantic validation fixes, and type annotation mismatches in skills and agent files

Reviewed changes

Copilot reviewed 41 out of 42 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
web-dashboard/src/app/workspace/page.tsx New 765-line workspace page with project context, command palette, and integrated ChatKit
web-dashboard/src/lib/chatkit-config.ts Centralized ChatKit configuration with entity tagging and streaming state types
web-dashboard/src/components/chat/ProgressIndicator.tsx Loading indicator for AI response streaming with spinner animation
web-dashboard/src/components/chat/ContextBadge.tsx Project context display with clear functionality and loading states
web-dashboard/src/components/chat/ChatKitWidget.tsx Enhanced with project name fetching, action handlers for navigation, and streaming state tracking
packages/api/src/taskflow_api/services/widgets/task_list.py 348-line task list widget builder with status-specific action buttons
packages/api/src/taskflow_api/services/widgets/task_form.py Form and confirmation widgets for task creation with validation
packages/api/src/taskflow_api/services/widgets/audit_timeline.py Timeline widget with relative timestamps and actor type indicators
packages/api/src/taskflow_api/services/chatkit_server.py Major expansion with local tool wrappers, widget streaming hooks, and action handlers (~590 lines added)
packages/api/src/taskflow_api/routers/members.py Split routers for member search (autocomplete) and project-specific members
packages/mcp-server/src/taskflow_mcp/tools/tasks.py Added show_task_form tool for triggering form widget display
.claude/skills/engineering/chatkit-actions/SKILL.md Critical implementation details section with common Pydantic errors and fixes
.claude/agents/engineering/chatkit-expert-agent.md Enhanced anti-patterns and comprehensive testing checklist (14 new items)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +104 to +125
useEffect(() => {
if (!isAuthenticated) return;

async function fetchData() {
try {
const projectsData = await api.getProjects({ limit: 10 });
if (isMountedRef.current) {
setProjects(projectsData);
if (projectsData.length > 0 && !selectedProject) {
setSelectedProject(projectsData[0]);
// Load tasks for first project
const tasks = await api.getProjectTasks(projectsData[0].id, { limit: 5 });
setRecentTasks(tasks);
}
}
} catch (error) {
console.error("[Workspace] Failed to load data:", error);
}
}

fetchData();
}, [isAuthenticated, selectedProject]);

Copilot AI Dec 9, 2025

Copy link

Choose a reason for hiding this comment

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

The useEffect dependency array includes selectedProject on line 125, which causes the effect to run whenever the project changes. However, inside the effect (line 112), it only sets the selected project if projectsData.length > 0 && !selectedProject, which will never be true after the first run. This creates an infinite loop: changing the project triggers the effect, which might trigger another change.

Consider removing selectedProject from the dependency array on line 125, or refactoring this logic to separate initial load from project changes.

Copilot uses AI. Check for mistakes.
const { user, isAuthenticated, isLoading: authLoading, login } = useAuth();
const pathname = usePathname();
const params = useParams();
const router = useRouter();

Copilot AI Dec 9, 2025

Copy link

Choose a reason for hiding this comment

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

Unused variable router.

Copilot uses AI. Check for mistakes.

def test_form_with_project_context(self) -> None:
"""Form shows project context."""
widget = build_task_form_widget(project_id=1, project_name="Test Project")

Copilot AI Dec 9, 2025

Copy link

Choose a reason for hiding this comment

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

Keyword argument 'project_name' is not a supported parameter name of function build_task_form_widget.

Suggested change
widget = build_task_form_widget(project_id=1, project_name="Test Project")
widget = build_task_form_widget(project_id=1)

Copilot uses AI. Check for mistakes.

# Get project info from context
project_id = context.context.project_id
project_name = context.context.project_name

Copilot AI Dec 9, 2025

Copy link

Choose a reason for hiding this comment

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

Variable project_name is not used.

Suggested change
project_name = context.context.project_name

Copilot uses AI. Check for mistakes.
raise ValueError("task_id required")

# Call MCP tool to complete task
result = await mcp_server.call_tool(

Copilot AI Dec 9, 2025

Copy link

Choose a reason for hiding this comment

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

Variable result is not used.

Suggested change
result = await mcp_server.call_tool(
await mcp_server.call_tool(

Copilot uses AI. Check for mistakes.
raise ValueError("task_id required")

# Call MCP tool to start task
result = await mcp_server.call_tool(

Copilot AI Dec 9, 2025

Copy link

Choose a reason for hiding this comment

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

Variable result is not used.

Suggested change
result = await mcp_server.call_tool(
await mcp_server.call_tool(

Copilot uses AI. Check for mistakes.
Comment on lines +1082 to +1083
due_date = payload.get("task.dueDate") or payload.get("due_date")

Copilot AI Dec 9, 2025

Copy link

Choose a reason for hiding this comment

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

Variable due_date is not used.

Suggested change
due_date = payload.get("task.dueDate") or payload.get("due_date")

Copilot uses AI. Check for mistakes.
# Import all tool modules to register their @mcp.tool() decorators
# These imports have side effects: they register tools with the mcp instance
import taskflow_mcp.tools.tasks # noqa: F401 - 9 task tools
import taskflow_mcp.tools.tasks # noqa: F401 - 10 task tools

Copilot AI Dec 9, 2025

Copy link

Choose a reason for hiding this comment

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

Import of 'taskflow_mcp' is not used.

Copilot uses AI. Check for mistakes.
Comment on lines +16 to +17
import pytest

Copilot AI Dec 9, 2025

Copy link

Choose a reason for hiding this comment

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

Import of 'pytest' is not used.

Suggested change
import pytest

Copilot uses AI. Check for mistakes.
mjunaidca and others added 4 commits December 9, 2025 11:51
**Linting Fixes:**
- Move httpx import to top of file (E402)
- Fix line length issues in comments (E501)
- Remove unused variables (F841): project_name, result, due_date
- Fix import sorting (I001)
- Fix type annotations (UP045): Optional[X] → X | None

**Test Fixes:**
- Update test_build_empty_task_list to match Card widget structure
- Note: Widget tests need updates for new API surface (8 tests failing)
- All core tests pass (41/41 tests)

**Changes:**
- `chatkit_server.py`: Import fixes, unused variable removal, line wrapping
- `main.py`: Comment line wrapping
- `chat_agent.py`: Multiple line wrapping fixes for long comments
- `members.py`: Auto-fixed by ruff (Optional → X | None)
- `test_widgets.py`: Updated empty task list test expectations

**Widget Test Status:**
- Core functionality tests: ✅ 41/41 passing
- Widget structure tests: ⚠️ 8/15 failing (API surface changes)
- Widget tests need follow-up to match new Card/ListView structure

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
**Copilot Feedback Fixes:**

Frontend:
- Fix useEffect infinite loop in workspace/page.tsx
  - Removed selectedProject from dependency array
  - Effect only runs on initial auth, not on project changes
- Remove unused router import/variable in ChatKitWidget.tsx

Backend Tests:
- Update all widget tests to match current API surface
- All 15 widget tests now passing ✅

**Widget Test Updates:**

TaskListWidget (3 tests):
- Update to use widget["children"] instead of widget["items"]
- Update item type from "Box" to "ListViewItem"
- Fix button label assertions

TaskFormWidget (4 tests):
- Update widget type from "Box" to "Card"
- Remove project_name parameter (doesn't exist)
- Simplify assertions to match nested Form structure
- Add _flatten_children helper for button detection

TaskCreatedConfirmation (1 test):
- Update widget type from "Box" to "Card"
- Fix field name from "content" to "value"
- Check Title/Text/Caption types for success message

**Test Results:**
- Widget tests: ✅ 15/15 passing (was 7/15)
- Core tests: ✅ 41/41 passing
- Total: ✅ 56/56 tests passing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@mjunaidca
mjunaidca merged commit 1771277 into main Dec 9, 2025
3 checks passed
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