Add clickup_query_tasks tool and Press Advantage API integration plan
New tool queries ClickUp API live for tasks, with optional status and task_type filters. Fixes the execution brain instantiation bug by providing a proper @tool wrapper around ClickUpClient. Also saves the Press Advantage API integration plan for future work once API access is restored. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>cora-start
parent
019bf0ee3c
commit
7153e65ae6
|
|
@ -10,6 +10,20 @@ from . import tool
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_clickup_client(ctx: dict):
|
||||||
|
"""Create a ClickUpClient from the agent's config."""
|
||||||
|
from ..clickup import ClickUpClient
|
||||||
|
|
||||||
|
cfg = ctx["config"].clickup
|
||||||
|
if not cfg.api_token:
|
||||||
|
return None
|
||||||
|
return ClickUpClient(
|
||||||
|
api_token=cfg.api_token,
|
||||||
|
workspace_id=cfg.workspace_id,
|
||||||
|
task_type_field_name=cfg.task_type_field_name,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _get_clickup_states(db) -> dict[str, dict]:
|
def _get_clickup_states(db) -> dict[str, dict]:
|
||||||
"""Load all tracked ClickUp task states from kv_store."""
|
"""Load all tracked ClickUp task states from kv_store."""
|
||||||
pairs = db.kv_scan("clickup:task:")
|
pairs = db.kv_scan("clickup:task:")
|
||||||
|
|
@ -26,6 +40,58 @@ def _get_clickup_states(db) -> dict[str, dict]:
|
||||||
return states
|
return states
|
||||||
|
|
||||||
|
|
||||||
|
@tool(
|
||||||
|
"clickup_query_tasks",
|
||||||
|
"Query ClickUp live for tasks. Optionally filter by status (e.g. 'to do', 'in progress') "
|
||||||
|
"and/or task type (e.g. 'Press Release'). Returns task name, ID, status, type, due date, "
|
||||||
|
"and custom fields directly from the ClickUp API.",
|
||||||
|
category="clickup",
|
||||||
|
)
|
||||||
|
def clickup_query_tasks(status: str = "", task_type: str = "", ctx: dict = None) -> str:
|
||||||
|
"""Query ClickUp API for tasks, optionally filtered by status and task type."""
|
||||||
|
client = _get_clickup_client(ctx)
|
||||||
|
if not client:
|
||||||
|
return "Error: ClickUp API token not configured."
|
||||||
|
|
||||||
|
cfg = ctx["config"].clickup
|
||||||
|
if not cfg.space_id:
|
||||||
|
return "Error: ClickUp space_id not configured."
|
||||||
|
|
||||||
|
try:
|
||||||
|
statuses = [status] if status else None
|
||||||
|
tasks = client.get_tasks_from_space(cfg.space_id, statuses=statuses)
|
||||||
|
except Exception as e:
|
||||||
|
return f"Error querying ClickUp: {e}"
|
||||||
|
finally:
|
||||||
|
client.close()
|
||||||
|
|
||||||
|
if task_type:
|
||||||
|
tasks = [t for t in tasks if t.task_type.lower() == task_type.lower()]
|
||||||
|
|
||||||
|
if not tasks:
|
||||||
|
filters = []
|
||||||
|
if status:
|
||||||
|
filters.append(f"status='{status}'")
|
||||||
|
if task_type:
|
||||||
|
filters.append(f"type='{task_type}'")
|
||||||
|
filter_str = " with " + ", ".join(filters) if filters else ""
|
||||||
|
return f"No tasks found{filter_str}."
|
||||||
|
|
||||||
|
lines = []
|
||||||
|
for t in tasks:
|
||||||
|
parts = [f"**{t.name}** (ID: {t.id})"]
|
||||||
|
parts.append(f" Status: {t.status} | Type: {t.task_type or '—'}")
|
||||||
|
# Show custom fields that have values
|
||||||
|
fields = {k: v for k, v in t.custom_fields.items() if v}
|
||||||
|
if fields:
|
||||||
|
field_strs = [f"{k}: {v}" for k, v in fields.items()]
|
||||||
|
parts.append(f" Fields: {', '.join(field_strs)}")
|
||||||
|
parts.append(f" URL: {t.url}")
|
||||||
|
lines.append("\n".join(parts))
|
||||||
|
|
||||||
|
return f"**ClickUp Tasks ({len(lines)}):**\n\n" + "\n\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
@tool(
|
@tool(
|
||||||
"clickup_list_tasks",
|
"clickup_list_tasks",
|
||||||
"List ClickUp tasks that Cheddah is tracking. Optionally filter by internal state "
|
"List ClickUp tasks that Cheddah is tracking. Optionally filter by internal state "
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
# Press Advantage API Integration Plan
|
||||||
|
|
||||||
|
## Status: Blocked — waiting on PA support to fix API access
|
||||||
|
|
||||||
|
API key is in `.env` as `PRESS_ADVANTAGE_API`. Auth works (`api_token` query param) but returns "account is cancelled or past due" on all endpoints. Emailed PA support.
|
||||||
|
|
||||||
|
Test release: #81505 (draft)
|
||||||
|
|
||||||
|
## Workflow Overview
|
||||||
|
|
||||||
|
### Track 1: No Client Approval
|
||||||
|
1. `write_press_releases` tool generates 2 PRs + schemas (DONE)
|
||||||
|
2. ClickUp integration saves PRs as attachments + Google Doc (separate work, not CheddahBot)
|
||||||
|
3. Bryan picks one in chat ("I like PR A")
|
||||||
|
4. `submit_press_release` tool uploads to Press Advantage via API
|
||||||
|
5. Done
|
||||||
|
|
||||||
|
### Track 2: Client Approval Required
|
||||||
|
1. `write_press_releases` tool generates 2 PRs + schemas (DONE)
|
||||||
|
2. ClickUp integration saves PRs as attachments + Google Doc (separate work, not CheddahBot)
|
||||||
|
3. Bryan picks one, sends to client for review
|
||||||
|
4. **Waiting period** — auto-generate weekly nag email to Bryan's partner to follow up with client
|
||||||
|
5. Client approves (comes back in the doc)
|
||||||
|
6. `submit_press_release` tool uploads to Press Advantage via API
|
||||||
|
7. Done
|
||||||
|
|
||||||
|
## What To Build
|
||||||
|
|
||||||
|
### 1. `submit_press_release` tool
|
||||||
|
- New `@tool` in `cheddahbot/tools/`
|
||||||
|
- Takes: PR text (or file path), headline, organization_id, distribution type
|
||||||
|
- Calls `POST /api/customers/releases/with_content.json`
|
||||||
|
- Params: `release[organization_id]`, `release[title]`, `release[body]`, `release[distribution]`, `release[schedule_distribution]`
|
||||||
|
- Returns: release ID, status
|
||||||
|
- Need to figure out org ID mapping (company name → PA org ID)
|
||||||
|
|
||||||
|
### 2. Org ID mapping
|
||||||
|
- `GET /api/customers/organizations.json` lists all orgs with IDs
|
||||||
|
- Could cache this or add a lookup tool
|
||||||
|
- Or add PA org IDs to `skills/companies.md`
|
||||||
|
|
||||||
|
### 3. Weekly nag emails (Track 2)
|
||||||
|
- Time-driven, not chat-driven
|
||||||
|
- Options: CheddahBot heartbeat check, ClickUp automation, or cron
|
||||||
|
- Needs state tracking: which PRs are awaiting client approval and since when
|
||||||
|
|
||||||
|
## API Reference (key endpoints)
|
||||||
|
|
||||||
|
| Endpoint | Method | Purpose |
|
||||||
|
|----------|--------|---------|
|
||||||
|
| `/api/customers/releases/with_content.json` | POST | Submit finished PR |
|
||||||
|
| `/api/customers/releases.json` | GET | List all releases |
|
||||||
|
| `/api/customers/releases/{id}.json` | GET | Get release status |
|
||||||
|
| `/api/customers/releases/{id}/approve_content.json` | POST | Approve for distribution |
|
||||||
|
| `/api/customers/releases/{id}/built_urls.json` | GET | Get published URLs |
|
||||||
|
| `/api/customers/organizations.json` | GET | List orgs (get org IDs) |
|
||||||
|
|
||||||
|
## Auth
|
||||||
|
- Query param: `?api_token=<key>`
|
||||||
|
- Key stored in `.env` as `PRESS_ADVANTAGE_API`
|
||||||
Loading…
Reference in New Issue