Commit Graph

18 Commits (f60928f3fac244069dd05bad7b8f14e108b8984a)

Author SHA1 Message Date
PeninsulaInd a3b8457afe Add two-phase content creation tool with human-in-the-loop outline review
Phase 1 researches competitors and generates an outline via the execution brain,
saves it to a network/local path, and pauses for human review. Phase 2 picks up
the approved outline and writes full SEO-optimized content. ClickUp integration
maps "On Page Optimization" and "Content Creation" work categories, with
"outline approved" added to poll_statuses for automatic Phase 2 triggering.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 15:10:09 -06:00
PeninsulaInd 0b3ab904de Add API cost tracking and switch planner to Grok 4.1 Fast
Track per-call token usage and estimated costs across all OpenRouter models.
Switch planner agent from Claude Sonnet 4.6 ($3/$15 per M) to Grok 4.1 Fast
($0.20/$0.50 per M) for ~25x cost reduction. Add budget alerts, a dashboard
card, and a check_api_usage tool for visibility into spending.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 18:00:11 -06:00
PeninsulaInd 30757b5bcf Generate conversation titles via LLM instead of truncating first line
- _maybe_set_title sets a quick truncated fallback immediately
- Then fires a background thread to ask the LLM for a 5-8 word summary
- Background thread doesn't block the streaming response
- Title appears in sidebar on first chunk, then upgrades when LLM responds

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 11:11:34 -06:00
PeninsulaInd d771dd5c80 Stop creating empty conversations that clutter sidebar with 'New Chat'
- agent.new_conversation() now just resets conv_id to None; DB row is
  created lazily by ensure_conversation() when user sends first message
- on_app_load no longer eagerly creates a conversation on page load
- list_conversations filters out conversations with no messages so
  orphaned empty rows don't appear in the sidebar

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 11:08:34 -06:00
PeninsulaInd 603878e095 Fix conversation titles stuck on 'New Chat' and add loop timestamps to dashboard
- Move _maybe_set_title() to run at start of respond() generator (before streaming)
  so titles are set even if the generator is closed mid-stream by Gradio
- Refresh sidebar conv list on first streaming chunk for immediate title display
- Backfilled 34 existing conversation titles from their first user messages
- Add scheduler loop status cards (heartbeat, poll, clickup, folder_watch) to
  both System Health and Notifications tabs in the HTML dashboard
- Loop cards show relative time (e.g. "3m ago") with color-coded status

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 10:54:43 -06:00
PeninsulaInd dd39fa2e94 Show tool call args in chat and raise max iterations to 15
- Display tool arguments in the calling indicator so user can see what
  each tool call is doing (e.g. Calling delegate_task(prompt='...')...)
- Bump MAX_TOOL_ITERATIONS from 5 to 15 for complex chat interactions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 21:44:41 -06:00
PeninsulaInd d9e0020b67 Fix UI errors, message formatting, scheduler auto_execute, and LLM retry
Core fixes:
- Rewrite router.py format_messages_for_llm() to properly handle tool
  call/result message pairs in OpenAI format instead of faking them as
  user messages — root cause of most LLM API errors
- Fix scheduler ignoring auto_execute:false flag, which caused all Link
  Building tasks to be incorrectly executed and moved to internal review
- Add safety check so Skipped/Error tool results don't get marked as
  completed in ClickUp

Additional improvements:
- Add LLM retry logic (2 retries on transient 5xx/timeout/rate-limit)
- Replace raw LLM tracebacks with friendly error messages
- Fix ghost assistant bubble in UI by deferring append to first chunk
- Auto-title conversations from first user message
- Consistent tool_call_id generation (resolve once, reuse everywhere)
- Reduce pipeline status polling from 3s to 10s
- Update CLAUDE.md: remove stale watchdog/autostart docs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 21:34:02 -06:00
PeninsulaInd 916bec8c0e Reformat code and update ClickUp tools to reset pattern
- Ruff format: consistent dict/call wrapping in agent.py, db.py,
  skills.py, delegate.py
- Replace clickup_approve_task/clickup_decline_task with
  clickup_reset_task/clickup_reset_all (simpler state machine)
- Add kv_delete() method to Database
- Add due_date and field filter tests to test_clickup.py
- Update test_clickup_tools.py for new reset tools

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 20:44:40 -06:00
PeninsulaInd 0f2274e6f1 Phase 4: UI — Agent selector, conversation history, chat persistence
Add sidebar layout with agent selector (Radio), conversation history
(gr.render), and BrowserState for localStorage session persistence.
Conversations tagged by agent_name for per-agent history filtering.
Sidebar auto-closes on mobile viewports via JS. 11 new tests (135 total).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 11:23:50 -06:00
PeninsulaInd 86511d5a0f 3.3: Modify Agent and ToolRegistry for multi-agent
Agent changes:
- Accept optional AgentConfig in __init__
- Add name property
- Filter tools via agent_config.tools whitelist in respond()
- Use agent-specific personality file when configured
- Pass agent name to skills registry for filtering

ToolRegistry changes:
- get_tools_schema() accepts filter_names parameter
- get_tools_description() accepts filter_names parameter
- When filter_names is None, all tools are returned (backward compat)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:08:16 -06:00
PeninsulaInd 5311731855 2.3: Wire skills into system prompt
- router.py: build_system_prompt() gets skills_context parameter,
  injected between memory and tools sections
- agent.py: Agent gets set_skills_registry(), calls it in respond()
  to get skills prompt section
- __main__.py: Creates SkillRegistry from skills_dir, wires to agent

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:02:34 -06:00
PeninsulaInd 4a646373b6 1.5: Fix tool results — use role:tool with tool_call_id
Previously tool results were injected as role:user messages which
confuses some models. Now the live agent loop uses proper OpenAI
function-calling format:
- Assistant messages include tool_calls array with IDs
- Tool results use role:tool with matching tool_call_id

History replay in router.py is unchanged (no tool_call_ids in DB).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:00:21 -06:00
PeninsulaInd ed751d843b 1.3: Fix files parameter in agent.py — attachments now visible to LLM
Previously respond() accepted files but silently dropped them.
Now when files are attached:
- Images are base64-encoded as image_url content parts
- Text files are read and inlined as text content parts
- The last user message is converted to multipart format

Follows the same encoding pattern used in tools/image.py.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:58:44 -06:00
PeninsulaInd 0bef1e71b3 1.1: Delete dead code and fix all lint errors
Remove unused modules that were never called at startup:
- cheddahbot/skills/__init__.py (dead @skill decorator system)
- cheddahbot/providers/__init__.py (empty placeholder)
- cheddahbot/tools/build_skill.py (depends on dead skills system)
- cheddahbot/tools/build_tool.py (security risk: generates arbitrary Python)

Also fix all pre-existing ruff lint errors across the codebase:
- Fix import sorting, unused imports, line length violations
- Fix type comparisons (use `is` instead of `==`)
- Fix implicit Optional types (dict -> dict | None)
- Fix unused variables, ambiguous variable names
- Apply ruff format for consistent style

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:56:36 -06:00
PeninsulaInd b3140d3522 Add autonomous press release pipeline tool
Implements write_press_releases tool that generates 7 headlines via chat
brain, AI-judges the best 2, writes 2 full press releases via execution
brain, and generates JSON-LD schemas via Sonnet with WebSearch. Saves all
output files to data/generated/press_releases/.

Also adds tools/model pass-through in agent and LLM layers, fixes Windows
command line length limit by piping prompts via stdin, and updates model
references to current versions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 18:04:29 -06:00
PeninsulaInd 1866d48cb2 Fix chat memory persistence, duplicate tool calls, and heartbeat log noise
- Agent: deduplicate tool calls across iterations, reduce max iterations
  10→5, add system prompt instructions to prevent re-calling tools
- Router: preserve tool name in history messages, add anti-loop and
  delegate_task instructions to system prompt
- Memory: auto_flush now deletes flushed messages from DB so conversations
  don't get re-summarized repeatedly, skip tool results in summaries
- DB: add delete_messages() method, include message id in get_messages()
- Scheduler: stop logging routine heartbeat checks to daily log

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 14:23:33 -06:00
PeninsulaInd af767f9684 Implement two-brain architecture: chat brain + execution brain
Chat brain uses OpenAI-compatible APIs (OpenRouter/Ollama/LM Studio) for
all UI conversations, giving full control over system prompts so the
Cheddah personality works correctly. Execution brain uses Claude Code CLI
for heartbeat, scheduled tasks, and delegated system-level work.

- Split llm.py: chat() routes through OpenAI-compat only, new execute()
  calls Claude CLI with Bash/Read/Edit/Write/Glob/Grep tools
- Add chat_model config field (default: openai/gpt-4o-mini)
- Add delegate_task tool bridging chat brain to execution brain
- Scheduler/heartbeat now use execute_task() for real CLI power
- UI dropdown shows chat-only models with custom value support
- Updated model list to current OpenRouter top models (Feb 2026)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 22:59:32 -06:00
PeninsulaInd 1b73cf2e5d Initial implementation of CheddahBot personal AI assistant
Multi-model AI assistant with Gradio UI, persistent memory, 15+ tools,
and meta-tools for runtime tool creation. Routes Claude models through
Claude Code SDK (Max subscription), cloud models through OpenRouter,
and local models through Ollama/LM Studio.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 20:20:39 -06:00