Commit Graph

132 Commits (645b9cfbefe0e39a90d5b8e1ad209970e65e7ccf)

Author SHA1 Message Date
PeninsulaInd 0e3e3bc945 Wire scheduler to API/UI and improve loop control and PR headlines
- Pass scheduler instance to API router and UI for loop timestamps
  and force-run endpoints
- Add interruptible waits and force_heartbeat/force_poll methods
- Record last_run timestamps for all scheduler loops in KV store
- Update press release headline examples with real client headlines

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 21:18:29 -06:00
PeninsulaInd ffa8ad49e5 Add combined Cora Reports endpoint with keyword deduplication
New /api/tasks/need-cora endpoint pulls tasks needing Cora reports
across Link Building, On Page Optimization, and Content Creation work
categories, deduplicates by Keyword field, and filters to a 30-day
window. Dashboard overview now shows Cora Reports as the first section
with color-coded type badges (LB, OPO, Content).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 21:17:50 -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 ab2c313baa Add report_issue tool and planner agent for self-improvement tracking
- New report_issue tool logs bugs/improvements to memory/improvement_requests.md
- Planner agent (Sonnet via OpenRouter) for architecture and debugging tasks
- Heartbeat checks for pending improvement requests to surface to Bryan

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 17:31:28 -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 f8320a9fea Set folder watcher completed tasks to 'complete' instead of 'internal review'
Link building runs that finish successfully are already deployed,
so they go straight to complete. PRs still go to internal review.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 22:20:56 -06:00
PeninsulaInd 3c41c6bf5f Skip tasks without due dates in status counts, remove Companies card
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 22:07:26 -06:00
PeninsulaInd 6fd565734f Filter LB status cards to relevant statuses and recent tasks
Only show To Do, In Progress, Error, Automation Underway counts.
Exclude tasks due more than 1 month ago. Add "Scheduled next month"
card showing upcoming work.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:39:39 -06:00
PeninsulaInd f9142e6669 Skip Office temp/lock files (~$) in folder watcher
Prevents the watcher from picking up ~$*.xlsx lock files created by
Excel, which would match the same ClickUp task and corrupt its status.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 21:02:06 -06:00
PeninsulaInd ee7b4cc256 Add Cora Reports to Run queue as first section on Link Building tab
Filters out automation-touched tasks (error, automation underway, complete,
closed, done, internal review) and sorts by due date. Renders with 10-at-a-time
pagination and responsive mobile layout.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 20:55:07 -06:00
PeninsulaInd 3f2798d338 Add "automation underway" and "error" ClickUp statuses for bot visibility
Tasks now show "automation underway" when the bot picks them up and "error"
on failure, replacing the old "in progress" / "to do" fallbacks that were
invisible on Bryan's ClickUp board. Folder watcher also syncs ClickUp status
on match, missing IMSURL, pipeline failure, success, and exceptions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 20:36:58 -06:00
PeninsulaInd 62186d8dec Fix folder watcher matching, notifications, and BLM venv isolation
- Remove status filter from folder watcher so tasks in any open status
  (including "internal review") are matched by keyword
- Add retry logic for stuck processing/blocked/unmatched KV states
- Fix notification ordering (newest first, limit 50) and date parsing
- Use BLM's own .venv Python instead of uv run for subprocess calls
- Document external tools venv convention in CLAUDE.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 13:35:54 -06:00
PeninsulaInd 3b4a8e47be Require IMSURL for Cora pipeline, fail early if missing
Remove placeholder URL fallback from ingest-cora args. Add early
validation in run_cora_backlinks and folder watcher — if IMSURL is
empty, block the task with a notification instead of running with a
fake URL. Update tests to pass money_site_url and add missing-URL test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 12:11:11 -06:00
PeninsulaInd 01ba657b35 Fix Cora filter, speed up Overview, add inbox path link
Remove status gate from Cora filter — LB Method is the discriminator,
not status. Derive Overview stats and Cora section from /tasks data
directly (no slow /tasks/link-building fetch). Add click-to-copy
Z:\cora-inbox path next to Cora header. Show due dates in This Month.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 11:51:29 -06:00
PeninsulaInd f67f1b9124 Rename Client field to Customer and refine Overview sections
ClickUp "Client" custom field was deleted; switch all references to
"Customer" across config, tools, tests, and docs. Refine Overview tab:
rename Due Soon to Up Next (today/tomorrow, fallback next 5), expand
This Month to include both month tag and due-date-in-month matches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 11:20:19 -06:00
PeninsulaInd 0d60b1b516 Overhaul dashboard to use Overall lists with focused views
Switch from get_tasks_from_space (all lists) to get_tasks_from_overall_lists
(only "Overall" list per folder) to reduce noise. Add tags and date_done
fields to ClickUpTask. Redesign Overview tab with Due Soon, This Month,
and Cora Reports Needed sections. Add Recently Completed and In Progress
Not Started sections to Link Building tab.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 10:59:55 -06:00
PeninsulaInd 76a0200192 Add architecture review: data consistency and robustness
Comprehensive review of ClickUp data flow, failure modes, thread
safety, and error recovery. Identifies 3 critical issues (stuck tasks
after crash, ignored API failures, duplicate execution risk), 4 high
priority items, and 5 medium priority improvements. Doc only, no code
changes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 21:55:45 -06:00
PeninsulaInd e1992fa049 Add data-driven dashboard with API backend
- New cheddahbot/api.py: FastAPI router with endpoints for tasks,
  link building, press releases, agents, system health, notifications,
  KV states, and cache management (all cached 5min)
- Rewrote dashboard/index.html: replaces all hardcoded data with JS
  that fetches from /api/ endpoints. Tabs: Overview, Link Building,
  Press Releases, By Company, System Health, Agents, Notifications
- Updated __main__.py: mounts API router, removes old inline
  /api/linkbuilding/status endpoint
- Fixed run_link_building to reject empty LB Method instead of
  defaulting to Cora Backlinks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 21:53:51 -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 a1fc5a7c0f Fix lint issues across link building files
- Remove f-prefix from strings with no placeholders
- Use list unpacking instead of concatenation
- Fix import sorting in test file
- Remove unused Path import
- Use contextlib.suppress instead of try/except/pass
- Wrap long lines to stay under 100 chars

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 20:13:37 -06:00
PeninsulaInd 0f4c77adc9 Add link building API endpoint and skill file
- /api/linkbuilding/status endpoint returns pending, in-progress,
  completed, and failed pipeline states for dashboard consumption
- skills/linkbuilding.md with YAML frontmatter linking tools and agents
- Skill body documents workflow, triggers, default flags, and ClickUp fields

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 20:09:00 -06:00
PeninsulaInd 90e79b77ab Add folder watcher thread to scheduler for Cora inbox
- 4th daemon thread _folder_watch_loop scans Z:/cora-inbox
- Fuzzy-matches .xlsx filename stems to ClickUp Keyword fields
- On match: runs run_cora_backlinks, moves file to processed/
- On failure: marks in KV store, notifies via NotificationBus
- Uses existing _get_clickup_client and notification infrastructure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 20:07:24 -06:00
PeninsulaInd 40aca81e16 Add create_custom_field to ClickUp client and link building test suite
- ClickUpClient.create_custom_field() for POST /list/{id}/field
- 40+ tests covering output parsers, CLI arg builder, pipeline,
  ClickUp state machine, and folder scanning
- All tests mock subprocess.run, never call Big-Link-Man

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 20:05:54 -06:00
PeninsulaInd 2d5ed29c0d Add link building tool module with pipeline orchestration
- run_link_building: dispatcher that routes to correct pipeline by LB Method
- run_cora_backlinks: full pipeline (ingest-cora → generate-batch) with ClickUp sync
- blm_ingest_cora: standalone ingest tool
- blm_generate_batch: standalone generate tool
- scan_cora_folder: utility to inspect watch folder contents
- setup_linkbuilding_fields: one-time ClickUp field creation
- Private helpers for subprocess execution, output parsing, fuzzy matching

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 20:04:02 -06:00
PeninsulaInd e2dca938a1 Add LinkBuildingConfig and link_builder agent to config
- New LinkBuildingConfig dataclass (blm_dir, watch_folder, interval, ratio)
- YAML loading block and BLM_DIR env var override in load_config()
- Link Building skill_map entry with field mappings in config.yaml
- link_building section in config.yaml
- link_builder agent definition in agents section

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 20:01:55 -06:00
PeninsulaInd 0becf1dd89 Revert "Add link building agent with content generation pipeline"
This reverts commit 8a98b37725.
2026-02-19 18:38:51 -06:00
PeninsulaInd 8077ac5ab6 Revert "Update CLAUDE.md with link building agent documentation"
This reverts commit 2344770143.
2026-02-19 18:38:51 -06:00
PeninsulaInd 2344770143 Update CLAUDE.md with link building agent documentation
Add linkbuilder agent to architecture diagram, document the
Link Building skill_map entry, add test_linkbuilding.py to
test catalog, update test count to 187.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 11:52:57 -06:00
PeninsulaInd 8a98b37725 Add link building agent with content generation pipeline
New linkbuilder agent that handles ClickUp "Link Building" tasks.
For each keyword/company, generates three content pieces via the
execution brain: a guest article (500-700 words), a directory
listing, and a social media post — each with proper SEO anchor
text and backlinks. Integrates with ClickUp for status updates,
comments, and file attachments.

- cheddahbot/tools/linkbuilding.py: build_links tool with full pipeline
- skills/linkbuilding.md: skill prompt for SEO content generation
- config.yaml: linkbuilder agent config + Link Building skill_map entry
- tests/test_linkbuilding.py: 36 tests covering helpers, prompts,
  pipeline, file output, error handling, and ClickUp sync

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 11:52:06 -06:00
PeninsulaInd 1cce14b39f Document autostart behavior to prevent restart loops
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 09:05:33 -06:00
PeninsulaInd deae147795 Hide clickup_task_id from LLM tool schema to prevent hallucination
Removed clickup_task_id from write_press_releases function signature
so the LLM cannot see or fabricate a task ID. The parameter is now
passed through ctx by the ToolRegistry — the scheduler sets it in
args, and execute() moves it into the ctx dict before filtering.
Only system-injected task IDs can reach the tool.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 16:38:11 -06:00
PeninsulaInd 082ca6ba44 Fix PR task flow: add ClickUp status updates, comments, and attachments
The press release tool now handles its own ClickUp sync lifecycle when
a clickup_task_id is provided — sets status to "in progress" with a
starting comment, uploads docx attachments after creation, then sets
status to "internal review" with a completion comment. The scheduler
now passes clickup_task_id to tools and defers to tool-level sync when
detected, falling back to scheduler-level sync for other tools.
ToolRegistry.execute() now filters args to accepted params to prevent
TypeError when extra keys (like clickup_task_id) are passed to tools
that don't accept them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 16:36:45 -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 c311ae5909 Add Multi-Agent Configuration reference to CLAUDE.md
Comprehensive section covering AgentConfig fields, how to add a new
agent, how agents interact (delegation, execution brain, memory
scoping), and key files reference.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:33:43 -06:00
PeninsulaInd d376420025 Merge refactor/multi-agent-framework
Multi-agent architecture with markdown skills, memory scoping,
cross-agent delegation, and foundation cleanup (thread safety,
file attachments, proper tool message roles, shell approval).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:18:10 -06:00
PeninsulaInd 8a21990ba4 Update CLAUDE.md for multi-agent architecture
Add AgentRegistry, AgentConfig, delegate_to_agent, memory scoping,
and skills.py to architecture diagram, key files, and conventions.
Update test count to 124.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:14:53 -06:00
PeninsulaInd e5e9442e3d 3.6: Add delegate_to_agent tool for cross-agent delegation
New tool in delegate.py routes tasks to named agents via
agent.respond_to_prompt(). Includes thread-local depth counter
(max 3) to prevent infinite A->B->A delegation loops. Extended
ctx injection in ToolRegistry to include agent_registry. Wired
agent_registry into ToolRegistry from __main__.py.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:13:32 -06:00
PeninsulaInd 9d4d12e232 3.5: Wire multi-agent startup in __main__.py
Loop over config.agents to create per-agent LLM (when model override set),
Agent, MemorySystem (with scope), and register in AgentRegistry. Shared
ToolRegistry and SkillRegistry are wired to all agents. Scheduler and UI
use the default agent.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:12:08 -06:00
PeninsulaInd 883fee36a3 3.4: Add per-agent memory scoping
MemorySystem now accepts optional scope parameter. When set:
- Memory files go to memory/{scope}/ subdirectory
- Fallback search covers both scoped and shared directories

Unscoped agents (scope="") use the shared memory/ root directory.
This enables agents to have private memory while still searching
shared knowledge.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:09:31 -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 537e3bd528 3.2: Create AgentRegistry
New file cheddahbot/agent_registry.py. Holds multiple Agent instances
keyed by name with methods: register(), get(), list_agents(), and
default property. First registered agent is the default.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:06:56 -06:00
PeninsulaInd 6c2c28e9b0 3.1: Create AgentConfig dataclass and multi-agent config
New AgentConfig dataclass in config.py with fields:
- name, display_name, personality_file, model
- tools (whitelist), skills (filter), memory_scope

Loaded from config.yaml under agents: key. Defaults to single
agent for backward compatibility when section is omitted.

config.yaml now includes 4 agent configs: default, writer,
researcher, ops — each with appropriate tool/skill whitelists.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:06:12 -06:00
PeninsulaInd d05b589651 2.5: Update CLAUDE.md with skills.py and skill format docs
- Add cheddahbot/skills.py to Key Files table
- Update skills/ description to mention YAML frontmatter
- Add skills format to Conventions section
- Fix ctx type annotation in docs (dict -> dict | None)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:04:54 -06:00
PeninsulaInd b18855f068 2.5: Add tools and agents fields to skill frontmatter
Both press release skill files now include:
- tools: lists which tool functions they relate to
- agents: [writer, default] for future multi-agent filtering

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:04:11 -06:00
PeninsulaInd 724ccfebd6 2.4: Strip frontmatter in press_release.py _load_skill()
The _load_skill() function now strips YAML frontmatter (--- ... ---)
before returning skill content. This prevents the execution brain
from receiving metadata intended for the skill registry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:03:22 -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