Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 85 additions & 58 deletions public/llms-full.txt
Original file line number Diff line number Diff line change
Expand Up @@ -446,53 +446,84 @@ Poll: GET /v1/user_jobs/{id}?agent_id={id}

Prerequisites: Agent must have connected TikTok account (via AURA). Media must be publicly accessible.

## Agent Core API (GEN-2755)
## Agent Core API

**PREFERRED way to configure an agent.** Single-endpoint read/write for the entire agent setup canvas: identity, overview (brand profile), personality, inspiration sources, voice, look (+ reference images), and the agent's own social accounts. Replaces the legacy per-resource TrendPulse calls when you're setting up a new agent or editing its configuration.
**PREFERRED way to configure an agent.** Flat read/write for the entire agent setup canvas in a single call. Every field name mirrors exactly what the GEN Setup canvas saves, so developers and the app speak the same language.

**Backing service:** `agent-core` on EC2 (ports 8800 prod, 8801 staging). Exposed through `api.gen.pro` (CloudFront) and `staging-api.gen.pro` for PAT callers, and through `trendpulse.gen.pro` / `staging-trendpulse.gen.pro` for JWT callers. All routes PAT-authenticated via `X-API-Key`.
**Base URL:** `https://api.gen.pro/v1`. All routes authenticated via `X-API-Key` header with a Personal Access Token.

### Fields

A single PATCH may touch multiple internal systems. You see one call and get `200` if all succeed, or `207 Multi-Status` with per-section status if any one section fails.

### Two critical distinctions

- **`linked_accounts` vs `monitored` vs `research_topics`.** `linked_accounts` = the agent's OWN brand socials (the TikTok/Instagram/website the agent posts from). `monitored` = inspiration sources the agent watches for trending content (other creators, hashtags, or search keywords). `research_topics` = expertise areas the agent stays current on — the platform researches each daily and feeds results into content ideas (labeled "Expertise" in the UI; only include topics where recent events matter). Not the same thing — putting a competitor's URL into `linked_accounts` will eventually show up on the agent's own "My Socials" list.
- **`description` vs `personality`.** `description` is a short 2-3 sentence brand summary, hard-capped at 500 chars. `personality` is the full persona text, max 20000 chars. A 3000-char persona dumped into `description` returns 422 by design.

### GET /v1/agents/{agent_id}/core

Returns every section of the agent setup canvas in one call.
Returns every field as a flat object.

Response:
```json
{
"identity": { "name": "Santiago", "profile_photo_url": "https://cdn.example/a.png" },
"overview": {
"agent_id": "abc123",
"brand_name": "Santiago",
"description": "Santiago is a San Antonio street food scout...",
"identity_type": "character",
"goal": "growth",
"keywords": ["streetfood", "foodtruck", "tacotok"],
"target_platforms": ["tiktok", "instagram"],
"shortform": true,
"longform": false,
"primary_format": null,
"onboarding_status": "active"
},
"personality": "Santiago grew up eating at his tia's taco stand...",
"inspiration": [{ "id": 1, "url": "https://tiktok.com/@keilapacheco", "platform": "tiktok" }],
"voice": { "voice_id": "21m00Tcm4TlvDq8ikWAM", "name": "Rachel", "source": "public" },
"look": {
"description": "Latino male early 30s, athletic build",
"reference_images": [{ "id": 11, "url": "https://cdn.example/ref1.png" }]
},
"accounts": [{ "id": 42, "url": "https://tiktok.com/@santiago_real", "platform": "tiktok" }]
"agent_id": "abc123",
"brand_name": "Santiago",
"description": "San Antonio street food scout who hunts the best tacos.",
"identity_type": "character",
"goal": "growth",
"target_platforms": ["tiktok", "instagram"],
"shortform": true,
"longform": false,
"onboarding_status": "profile_complete",
"keywords": ["streetfood", "tacotok", "sanantonioeats"],
"monitored": [
{ "handle": "https://tiktok.com/@keilapacheco", "item_type": "account" },
{ "handle": "tacotok", "item_type": "hashtag" }
],
"research_topics": [
{ "topic": "new food truck openings in San Antonio" },
{ "topic": "viral street food TikTok moments" },
{ "topic": "Texas food festival announcements" }
],
"linked_accounts": [
{ "id": 42, "url": "https://tiktok.com/@santiago_real", "platform": "tiktok", "display_name": "Santiago" }
],
"look": "Warm earthy tones, close-up street food shots, natural light. Mid-20s Latino man, often seen on bustling sidewalks with a taco in hand.",
"personality": "Santiago grew up eating at his tia's taco stand in south San Antonio...",
"default_user_voice": { "voice_id": "21m00Tcm4TlvDq8ikWAM", "name": "Rachel", "source": "public" }
}
```

### PATCH /v1/agents/{agent_id}/core

Write any combination of sections in a single call. Merge semantics for `identity`, `overview`, `look.description`. Replace semantics for `personality`, `inspiration`, `voice`, `accounts`.
Flat merge-patch. Send only the fields you want to change. Unknown fields return 422.

**Field-level semantics:**
- Scalars replace: `brand_name`, `description`, `identity_type`, `goal`, `shortform`, `longform`, `onboarding_status`, `look`, `personality`
- List fields use FULL replacement (missing = deleted): `keywords`, `target_platforms`, `monitored`, `research_topics`, `linked_accounts`
- `linked_accounts` diffing: rows with `id` are updated in place, rows without `id` are inserted, rows absent from the list are deleted. To add one row without touching others, GET first, append, PATCH.
- `default_user_voice` replaces

**Keyword auto-mirror:** Sending `keywords` without `monitored` auto-populates `monitored` with `[{handle: kw, item_type: "keyword"}]` so the nightly monitoring cron stays in sync. Send both explicitly if you want different values.

Returns `200 OK` on full success. On partial failure, returns `207 Multi-Status` with per-section results:
**Validation:**
- `description` max 500 chars
- `look` max 2000 chars
- `personality` max 20000 chars
- `identity_type` enum: `"brand"` | `"character"`
- `monitored[].item_type` enum: `"account"` | `"hashtag"` | `"keyword"`
- `research_topics` max 20 items, each `topic` max 500 chars
- `linked_accounts[].url` required
- All nested objects reject unknown keys

Returns `200 OK` on full success. On partial failure, returns `207 Multi-Status` with per-**section** results (not per-field). Sections only appear if the PATCH touched at least one field they own:
```json
{
"identity": { "status": "ok", "data": { ... } },
"overview": { "status": "error", "error": "..." }
"brand": { "status": "ok", "data": { "brand_name": "Santiago", ... } },
"personality": { "status": "ok", "data": "Santiago grew up..." },
"voice": { "status": "error", "error": "voice service unavailable" }
}
```

Expand All @@ -502,34 +533,30 @@ curl -X PATCH https://api.gen.pro/v1/agents/abc123/core \
-H "X-API-Key: $GEN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"identity": { "name": "Santiago" },
"overview": {
"brand_name": "Santiago",
"description": "Santiago is a San Antonio street food scout...",
"identity_type": "character",
"goal": "growth",
"keywords": ["streetfood", "tacotok"],
"target_platforms": ["tiktok", "instagram"],
"shortform": true
},
"personality": "Santiago grew up eating at his tia\u0027s taco stand...",
"inspiration": [{ "url": "https://tiktok.com/@keilapacheco", "platform": "tiktok" }],
"look": { "description": "Latino male early 30s, athletic build" },
"voice": { "voice_id": "21m00Tcm4TlvDq8ikWAM", "source": "public" },
"accounts": [{ "url": "https://tiktok.com/@santiago_real", "platform": "tiktok" }]
"brand_name": "Santiago",
"description": "San Antonio street food scout who hunts the best tacos.",
"identity_type": "character",
"goal": "growth",
"target_platforms": ["tiktok", "instagram"],
"shortform": true,
"longform": false,
"keywords": ["streetfood", "tacotok", "sanantonioeats"],
"monitored": [
{ "handle": "https://tiktok.com/@keilapacheco", "item_type": "account" }
],
"research_topics": [
{ "topic": "new food truck openings in San Antonio" },
{ "topic": "viral street food TikTok moments" }
],
"linked_accounts": [
{ "url": "https://tiktok.com/@santiago_real", "platform": "tiktok", "display_name": "Santiago" }
],
"look": "Warm earthy tones, close-up street food shots, natural light. Mid-20s Latino man, often seen on bustling sidewalks with a taco in hand.",
"personality": "Santiago grew up eating at his tia\u0027s taco stand in south San Antonio. 28, easy-going, trusts his tongue over reviews, and will fight anyone who says Austin has better tacos.",
"default_user_voice": { "voice_id": "21m00Tcm4TlvDq8ikWAM", "source": "public" }
}'
```

### Item-level endpoints (append single items without replacing the list)

- POST /v1/agents/{agent_id}/core/identity/profile-photo — multipart `file=@photo.jpg`
- POST /v1/agents/{agent_id}/core/inspiration — body `{url, platform?}`
- DELETE /v1/agents/{agent_id}/core/inspiration/{item_id}
- POST /v1/agents/{agent_id}/core/accounts — body `{url, platform?, display_name?}`
- DELETE /v1/agents/{agent_id}/core/accounts/{account_id}
- POST /v1/agents/{agent_id}/core/look/reference-images — body `{url}`
- DELETE /v1/agents/{agent_id}/core/look/reference-images/{image_id}

## Voice API (Agent Core)

All under `/v1/agents/{agent_id}/voice/*`. PAT auth.
Expand Down Expand Up @@ -697,9 +724,9 @@ Each idea includes:
- rationale — why this idea works, with specific data points

### Asset Sources
- Social content (TikTok/IG/YouTube): assets.gen.buzz (permanent S3 URLs)
- Web research assets: gen-agentic-assets S3 bucket
- User uploads: Rails ContentResource
- Social content (TikTok/IG/YouTube): permanent CDN URLs
- Web research assets: sourced by the research agent
- User uploads: via the Content Resources API

### Research-Backed Generation
The agent automatically:
Expand Down
75 changes: 45 additions & 30 deletions public/llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> GEN is an Autonomous Social Media Agent platform. It detects trends, generates video content, publishes across platforms, and improves automatically.

Two surfaces: **Agent Core** (`api.gen.pro/v1/agents/{id}/core` + `/voice`) for setting up an agent's identity, personality, voice, and brand; and **Auto Content Engine** (`api.gen.pro/v1/autocontentengine/*`) for producing videos from those agents. Both authenticate with an X-API-Key PAT.
Two surfaces: **Agent Core** (`api.gen.pro/v1/agents/{id}/core` + `/voice`) for setting up an agent's brand, personality, inspiration sources, and voice; and **Auto Content Engine** (`api.gen.pro/v1/autocontentengine/*`) for producing videos from those agents. Both authenticate with an X-API-Key PAT.

For any new agent, **start with Agent Core**. Generating content before the agent is configured gives you generic results; configuring it first means every downstream feature (content ideas, template fills, voice) speaks in the agent's voice from the first call.

Expand Down Expand Up @@ -33,29 +33,42 @@ The GEN workflow has two halves — configure the agent, then let it generate co

### Step 1: Configure the Agent Core (most important step for any new agent)

One PATCH writes identity, overview (brand profile), personality, inspiration, voice, look, and accounts. This is what every downstream feature (content ideas, template fills, voice generation) reads from. A blank agent produces generic ideas. A richly configured agent produces specific, on-brand ones.
One flat PATCH writes every field the GEN Setup canvas can save: brand, inspiration sources, personality, voice. Every field name maps 1:1 to how the FE saves it. This is what every downstream feature (content ideas, template fills, voice generation) reads from. A blank agent produces generic ideas. A richly configured agent produces specific, on-brand ones.

PATCH /v1/agents/{agent_id}/core
```json
{
"identity": { "name": "Santiago" },
"overview": {
"brand_name": "Santiago",
"description": "Santiago is a San Antonio street food scout...",
"identity_type": "character",
"goal": "growth",
"keywords": ["streetfood", "foodtruck", "tacotok"],
"target_platforms": ["tiktok", "instagram"],
"shortform": true
},
"personality": "Santiago grew up eating at his tias taco stand...",
"inspiration": [{ "url": "https://tiktok.com/@keithlee", "platform": "tiktok" }],
"look": { "description": "Latino male early 30s, athletic build" },
"voice": { "voice_id": "21m00Tcm4TlvDq8ikWAM", "source": "public" },
"accounts": [{ "url": "https://tiktok.com/@santiago_sa", "platform": "tiktok" }]
"brand_name": "Santiago",
"description": "San Antonio street food scout who hunts the best tacos.",
"identity_type": "character",
"goal": "growth",
"target_platforms": ["tiktok", "instagram"],
"shortform": true,
"longform": false,
"keywords": ["streetfood", "foodtruck", "tacotok"],
"monitored": [
{ "handle": "https://tiktok.com/@keithlee", "item_type": "account" },
{ "handle": "sanantonioeats", "item_type": "hashtag" }
],
"linked_accounts": [
{ "url": "https://tiktok.com/@santiago_sa", "platform": "tiktok" }
],
"personality": "Santiago grew up eating at his tia's taco stand in south San Antonio. 28, easy-going, trusts his tongue over reviews.",
"look": "Warm earthy tones, close-up food shots, natural light",
"content_themes": ["street food", "local spots", "food reviews"],
"persona_inspirations": ["@keilapacheco", "@thetacochronicles"],
"timezone": "America/Chicago",
"default_user_voice": { "voice_id": "21m00Tcm4TlvDq8ikWAM", "source": "public" }
}
```
Returns 200 on full success or 207 Multi-Status with per-section results.
Returns 200 with the full updated agent core object. Upstream Rails failures (timezone, voice, ElevenLabs key) are logged but don't affect the HTTP status — local fields save first.

**Field distinctions:**
- `linked_accounts` = the agent's OWN brand socials (what it posts from). `monitored` = inspiration sources (creators/hashtags to watch).
- `description` is a short 2-3 sentence summary (max 500 chars); full persona text goes in `personality` (max 20000 chars).
- `content_themes` = content pillars (e.g. "street food", "travel"). `persona_inspirations` = creator accounts whose style to emulate.
- `look` = visual style description for reference image generation (max 2000 chars).
- `timezone` + `eleven_lab_api_key` = Rails-owned fields forwarded automatically; they appear in GET responses alongside the local brand fields.

### Step 2: Generate content ideas

Expand Down Expand Up @@ -302,19 +315,21 @@ Column roles: ingredient (user-creatable), video, final_video, stats (system-man
- POST /v1/user_jobs?agent_id={id} — publish content (body: {user_job_type: "publish_content", data: JSON string})

### Agent Core (GEN-2755, recommended for agent setup)
One-call read/write for the entire agent setup canvas (identity, overview, personality, inspiration, voice, look, accounts). Prefer this over per-resource TrendPulse calls when configuring an agent.
Flat one-call read/write for the entire agent setup canvas. Field names mirror what the FE saves — no sections, no wrappers. Prefer this over per-resource TrendPulse calls.

- GET /v1/agents/{agent_id}/core — read all fields in one call
- PATCH /v1/agents/{agent_id}/core — write any subset; 200 on full success, 207 Multi-Status on partial failure

- GET /v1/agents/{agent_id}/core — read all sections in one call
- PATCH /v1/agents/{agent_id}/core — write any combination of sections; 200 on full success, 207 Multi-Status on partial failure
- POST /v1/agents/{agent_id}/core/identity/profile-photo — multipart upload
- POST /v1/agents/{agent_id}/core/inspiration — append inspiration URL
- DELETE /v1/agents/{agent_id}/core/inspiration/{id}
- POST /v1/agents/{agent_id}/core/accounts — append the agent's own social URL
- DELETE /v1/agents/{agent_id}/core/accounts/{id}
- POST /v1/agents/{agent_id}/core/look/reference-images — add look reference image URL
- DELETE /v1/agents/{agent_id}/core/look/reference-images/{id}
Fields:
- brand_name, description, identity_type ("brand" | "character"), goal, target_platforms, shortform, longform, onboarding_status
- keywords (flat list of strings)
- monitored (list of {handle, item_type: "account"|"hashtag"|"keyword"}) — inspiration sources
- research_topics (list of {topic: string}, max 20 items, each max 500 chars) — subjects the agent stays current on (labeled "Expertise" in UI). Platform researches daily and feeds results into content ideas. Leave empty for evergreen niches.
- linked_accounts (list of {id?, url, platform, display_name}) — the agent's OWN brand socials
- personality (string, max 20000 chars) — full persona text
- default_user_voice ({voice_id, source}) — default TTS voice

Merge semantics: identity, overview, look.description. Replace semantics: personality, inspiration, voice, accounts.
Full-list replacement: `keywords`, `monitored`, `research_topics`, `target_platforms`, `linked_accounts`. To add one row without touching others, GET first, append, PATCH. Sending `keywords` without `monitored` auto-mirrors keywords into monitored with item_type='keyword'. `description` is hard-capped at 500 chars. Unknown fields return 422.

### Voice (Agent Core)
- GET /v1/agents/{agent_id}/voice/library?source={public|user_designed|user_trained|user_elevenlabs} — merged voice list
Expand All @@ -335,7 +350,7 @@ Voice delete + preview:
- POST /v1/agents/{agent_id}/voice/{voice_id}/preview — enqueue TTS preview job (ASYNC, returns `{user_job_id}`)
- GET /v1/agents/{agent_id}/voice/preview/{job_id} — poll preview job status

Auth: PAT (`X-API-Key`). Runs on `agent-core` service on EC2, exposed via `api.gen.pro` CloudFront + `staging-api.gen.pro` staging.
Auth: PAT (`X-API-Key`) via `api.gen.pro`.

## Agentic Chat API

Expand Down
Loading