Skip to content

Latest commit

 

History

History
2412 lines (1931 loc) · 56.4 KB

File metadata and controls

2412 lines (1931 loc) · 56.4 KB

SceneIntruderMCP API Reference

This document describes the API surface that is currently wired in the codebase.

  • REST base URL: http://localhost:8080/api
  • WebSocket base: ws://localhost:8080/ws

Common conventions

Authentication

  • Login: POST /api/auth/login
  • Logout: POST /api/auth/logout
  • Use bearer token in Authorization: Bearer <token>

Guest fallback is still supported for many scene-related routes. If the token is missing or invalid, the backend often falls back to console_user instead of failing hard.

Important exceptions:

  • /api/users/:user_id/... requires authenticated ownership.
  • /api/scripts/* requires authenticated access.
  • Some write operations explicitly use stricter auth middleware.

Response shape

Most endpoints return the unified response envelope:

{
  "success": true,
  "data": {},
  "message": "...",
  "timestamp": "...",
  "request_id": "..."
}

Long-running jobs

Many generation and analysis flows are asynchronous:

  1. start a job
  2. receive task_id
  3. subscribe to GET /api/progress/:taskID
  4. fetch the final artifact/result through its GET endpoint

SSE endpoint:

  • GET /api/progress/:taskID

Rate limiting

The /api group is rate-limited globally. Chat/interactions and analysis/upload paths use stricter rate limits than ordinary routes.

Settings and configuration APIs

Settings

  • GET /api/settings
  • POST /api/settings
  • POST /api/settings/test-connection

Notes:

  • GET /api/settings is the main frontend source of truth for llm_provider, vision_provider, video_provider, vision_models, and video_models.
  • POST /api/settings/test-connection currently validates LLM connectivity only.

LLM configuration

  • GET /api/llm/status
  • GET /api/llm/models?provider=<provider>
  • PUT /api/llm/config

Current backend-supported LLM provider names:

  • openai
  • anthropic
  • google
  • deepseek
  • qwen
  • mistral
  • grok
  • glm
  • githubmodels
  • openrouter
  • nvidia

Auth APIs

  • POST /api/auth/login
  • POST /api/auth/logout

Scene APIs

  • GET /api/scenes
  • POST /api/scenes
  • POST /api/scenes/shell
  • GET /api/scenes/:id
  • DELETE /api/scenes/:id
  • GET /api/scenes/:id/characters
  • GET /api/scenes/:id/conversations
  • GET /api/scenes/:id/nodes/:node_id/content
  • GET /api/scenes/:id/aggregate

Scene item APIs

  • GET /api/scenes/:id/items
  • POST /api/scenes/:id/items
  • GET /api/scenes/:id/items/:item_id
  • PUT /api/scenes/:id/items/:item_id
  • DELETE /api/scenes/:id/items/:item_id

Story APIs

  • GET /api/scenes/:id/story
  • POST /api/scenes/:id/story/choice
  • POST /api/scenes/:id/story/advance
  • POST /api/scenes/:id/story/command
  • POST /api/scenes/:id/story/nodes/:node_id/insert
  • POST /api/scenes/:id/story/rewind
  • GET /api/scenes/:id/story/branches
  • GET /api/scenes/:id/story/choices
  • POST /api/scenes/:id/story/batch
  • POST /api/scenes/:id/story/tasks/:task_id/objectives/:objective_id/complete
  • POST /api/scenes/:id/story/locations/:location_id/unlock
  • POST /api/scenes/:id/story/locations/:location_id/explore

Comics APIs

Base group: /api/scenes/:id/comic

  • GET /api/scenes/:id/comic
  • DELETE /api/scenes/:id/comic
  • GET /api/scenes/:id/comic/export?format=zip|html
  • POST /api/scenes/:id/comic/analysis
  • GET /api/scenes/:id/comic/analysis
  • PUT /api/scenes/:id/comic/analysis
  • POST /api/scenes/:id/comic/prompts
  • GET /api/scenes/:id/comic/prompts
  • PUT /api/scenes/:id/comic/prompts/:frameID
  • POST /api/scenes/:id/comic/key_elements
  • GET /api/scenes/:id/comic/key_elements
  • PUT /api/scenes/:id/comic/key_elements
  • POST /api/scenes/:id/comic/references
  • GET /api/scenes/:id/comic/references
  • GET /api/scenes/:id/comic/references/:elementID/image
  • DELETE /api/scenes/:id/comic/references/:elementID
  • POST /api/scenes/:id/comic/generate
  • POST /api/scenes/:id/comic/frames/generate
  • POST /api/scenes/:id/comic/frames/:frameID/regenerate
  • GET /api/scenes/:id/comic/images/:frameID

Video APIs

Base group: /api/scenes/:id/comic/video

  • POST /api/scenes/:id/comic/video/timeline
  • GET /api/scenes/:id/comic/video/timeline
  • PUT /api/scenes/:id/comic/video/frames/:frameID
  • POST /api/scenes/:id/comic/video/generate
  • POST /api/scenes/:id/comic/video/frames/:frameID/regenerate
  • GET /api/scenes/:id/comic/video
  • DELETE /api/scenes/:id/comic/video
  • GET /api/scenes/:id/comic/video/clips/:frameID/asset
  • GET /api/scenes/:id/comic/video/render
  • GET /api/scenes/:id/comic/video/export?format=zip|html

Important runtime note:

  • Some providers need a reachable image URL for reference input. In deployment, video_config.public_base_url is usually required.

Scripts APIs

Base group: /api/scripts

  • GET /api/scripts
  • POST /api/scripts
  • PUT /api/scripts/:id
  • DELETE /api/scripts/:id
  • GET /api/scripts/:id
  • GET /api/scripts/:id/characters
  • PUT /api/scripts/:id/characters
  • GET /api/scripts/:id/items
  • PUT /api/scripts/:id/items
  • PUT /api/scripts/:id/chapter_draft
  • PUT /api/scripts/:id/draft
  • POST /api/scripts/:id/generate
  • POST /api/scripts/:id/command
  • POST /api/scripts/:id/rewind
  • GET /api/scripts/:id/export?format=json|markdown|txt|html

Chat and interaction APIs

  • POST /api/chat
  • POST /api/chat/emotion
  • POST /api/interactions/trigger
  • POST /api/interactions/simulate
  • POST /api/interactions/aggregate
  • GET /api/interactions/:scene_id
  • GET /api/interactions/:scene_id/:character1_id/:character2_id

Analyze / upload / cancel APIs

  • POST /api/upload
  • POST /api/analyze
  • GET /api/progress/:taskID
  • POST /api/cancel/:taskID

Export APIs

  • GET /api/scenes/:id/export/scene
  • GET /api/scenes/:id/export/interactions
  • GET /api/scenes/:id/export/story

User APIs

Base group: /api/users/:user_id

  • GET /api/users/:user_id
  • PUT /api/users/:user_id
  • GET /api/users/:user_id/preferences
  • PUT /api/users/:user_id/preferences
  • GET /api/users/:user_id/items
  • POST /api/users/:user_id/items
  • GET /api/users/:user_id/items/:item_id
  • PUT /api/users/:user_id/items/:item_id
  • DELETE /api/users/:user_id/items/:item_id
  • GET /api/users/:user_id/skills
  • POST /api/users/:user_id/skills
  • GET /api/users/:user_id/skills/:skill_id
  • PUT /api/users/:user_id/skills/:skill_id
  • DELETE /api/users/:user_id/skills/:skill_id

Config and operations APIs

  • GET /api/config/health
  • GET /api/config/metrics
  • GET /api/ws/status
  • POST /api/ws/cleanup

WebSocket endpoints

  • GET /ws/scene/:id
  • GET /ws/user/status

The backend uses plain Gorilla WebSocket, not Socket.IO.

Practical examples

Get settings

curl -sS http://localhost:8080/api/settings

Start standalone comic analysis

curl -sS -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <token>" \
  http://localhost:8080/api/scenes/<scene_id>/comic/analysis \
  -d '{"source_text":"A detective enters the station.","target_frames":6}'

Subscribe to progress

curl -N -H "Accept: text/event-stream" \
  http://localhost:8080/api/progress/<task_id>

Save settings with NVIDIA + GLM + DashScope video

{
  "llm_provider": "nvidia",
  "llm_config": {
    "api_key": "***",
    "base_url": "https://integrate.api.nvidia.com/v1",
    "default_model": "moonshotai/kimi-k2.5"
  },
  "vision_provider": "glm",
  "vision_default_model": "glm-image",
  "vision_config": {
    "endpoint": "https://open.bigmodel.cn/api/paas/v4",
    "api_key": "***"
  },
  "video_provider": "dashscope",
  "video_default_model": "wan2.6-i2v-flash",
  "video_config": {
    "endpoint": "https://dashscope.aliyuncs.com/api/v1",
    "api_key": "***",
    "public_base_url": "https://your-domain.example"
  }
}

Fetch results:

curl -sS http://localhost:8080/api/scenes/<scene_id>/comic/analysis

curl -sS http://localhost:8080/api/scenes/<scene_id>/comic/prompts

curl -sS http://localhost:8080/api/scenes/<scene_id>/comic/key_elements

Start prompts / key elements (both return 202 + task_id; subscribe via /api/progress/<task_id>):

curl -sS -X POST -H "Content-Type: application/json" \
  http://localhost:8080/api/scenes/<scene_id>/comic/prompts -d '{}'

curl -sS -X POST -H "Content-Type: application/json" \
  http://localhost:8080/api/scenes/<scene_id>/comic/key_elements -d '{}'

Upload reference images (multipart; PNG/JPEG/WEBP; <= 5MB each):

Single upload (element_id + file):

curl -sS -X POST \
  -F "element_id=<element_id>" \
  -F "file=@./reference.png" \
  http://localhost:8080/api/scenes/<scene_id>/comic/references

Batch upload (file_<element_id> parts):

curl -sS -X POST \
  -F "file_<element_id_1>=@./ref1.png" \
  -F "file_<element_id_2>=@./ref2.jpg" \
  http://localhost:8080/api/scenes/<scene_id>/comic/references

Generate images / regenerate one frame (both return 202 + task_id):

curl -sS -X POST -H "Content-Type: application/json" \
  http://localhost:8080/api/scenes/<scene_id>/comic/generate -d '{}'

curl -sS -X POST -H "Content-Type: application/json" \
  http://localhost:8080/api/scenes/<scene_id>/comic/frames/<frame_id>/regenerate -d '{}'

Overview:

curl -sS http://localhost:8080/api/scenes/<scene_id>/comic

Export (ZIP/HTML):

curl -fSL -o comic_<scene_id>.zip \
  "http://localhost:8080/api/scenes/<scene_id>/comic/export?format=zip"

curl -fSL -o comic_<scene_id>.html \
  "http://localhost:8080/api/scenes/<scene_id>/comic/export?format=html"

Start analysis:

POST /api/scenes/<scene_id>/comic/analysis
Content-Type: application/json

{}

Standalone analysis example:

POST /api/scenes/<scene_id>/comic/analysis
Content-Type: application/json

{
  "source_text": "A detective enters the abandoned station and finds a broken clock...",
  "target_frames": 6
}

Create a standalone comic scene shell:

POST /api/scenes/shell
Content-Type: application/json
Authorization: Bearer <token>

{
  "title": "My Comic",
  "description": "Standalone comic workspace"
}

Response (202):

{
  "success": true,
  "data": { "task_id": "comic_analyze_<scene_id>_..." },
  "message": "分镜分析任务已受理",
  "timestamp": "..."
}

Fetch analysis:

GET /api/scenes/<scene_id>/comic/analysis

Response (200):

{
  "success": true,
  "data": {
    "scene_id": "<scene_id>",
    "target_frames": 8,
    "frames": [
      { "id": "frame_1", "order": 1, "description": "..." }
    ]
  },
  "message": "分镜分析结果获取成功",
  "timestamp": "..."
}

Common error codes:

  • LLM_NOT_READY: LLM is not configured or not ready (503)
  • COMIC_SERVICE_NOT_READY: ComicService/Repo is not initialized (503)
  • COMIC_ANALYSIS_NOT_FOUND: analysis is missing (404)
  • COMIC_PROMPTS_NOT_FOUND: prompts are missing (404)
  • COMIC_KEY_ELEMENTS_NOT_FOUND: key elements are missing (404)

Export comic:

GET /api/scenes/<scene_id>/comic/export?format=zip

Response (200): file download

  • Content-Type: application/zip / text/html; charset=utf-8
  • Content-Disposition: attachment; filename="comic_<scene_id>_<timestamp>.<ext>"

Scripts (New Script assistant)

  • GET /api/scripts — List scripts
  • POST /api/scripts — Create a new script project (New Script). This endpoint creates the project and initializes draft-related files; to start generation explicitly, call POST /api/scripts/:id/generate (returns a task_id for SSE progress).
  • GET /api/scripts/:id — Get script details (project metadata, active draft, outline, memory, chapter summaries, workflow items)
  • POST /api/scripts/:id/generate — Start (or restart) initial generation for the script (asynchronous). Returns { "task_id": "..." }. Subscribe to /api/progress/:task_id (SSE) for progress updates.
  • POST /api/scripts/:id/command — Execute a command (e.g., assist_mode: inspiration, completion, polish) to expand or edit a chapter/scene; may return draft/workflow ids and output.
  • PUT /api/scripts/:id/chapter_draft — Update per-chapter user_draft (best-effort persist to chapter_draft.json).
  • PUT /api/scripts/:id/draft — Save/replace a draft (creates new draft version and updates active draft).
  • POST /api/scripts/:id/rewind — Rewind to a previous draft (body: { "draft_id": "draft_xxx" }).
  • GET /api/scripts/:id/export — Export script in formats: json|markdown|txt|html (e.g., ?format=markdown|txt|html&include_meta=true).

Scene items

  • GET /api/scenes/:id/items
  • POST /api/scenes/:id/items
  • GET /api/scenes/:id/items/:item_id
  • PUT /api/scenes/:id/items/:item_id
  • DELETE /api/scenes/:id/items/:item_id

Story

  • GET /api/scenes/:id/story
  • POST /api/scenes/:id/story/choice
  • POST /api/scenes/:id/story/advance
  • POST /api/scenes/:id/story/command
  • POST /api/scenes/:id/story/nodes/:node_id/insert
  • POST /api/scenes/:id/story/rewind
  • GET /api/scenes/:id/story/branches
  • GET /api/scenes/:id/story/choices
  • POST /api/scenes/:id/story/batch
  • POST /api/scenes/:id/story/tasks/:task_id/objectives/:objective_id/complete
  • POST /api/scenes/:id/story/locations/:location_id/unlock
  • POST /api/scenes/:id/story/locations/:location_id/explore

Export

All export endpoints accept ?format= (commonly json, markdown, txt, html, and some exports also support csv depending on handler).

  • GET /api/scenes/:id/export/scene
  • GET /api/scenes/:id/export/interactions
  • GET /api/scenes/:id/export/story

Chat

  • POST /api/chat
  • POST /api/chat/emotion

Interactions

  • POST /api/interactions/trigger
  • POST /api/interactions/simulate
  • POST /api/interactions/aggregate
  • GET /api/interactions/:scene_id
  • GET /api/interactions/:scene_id/:character1_id/:character2_id

Upload / Analyze / Progress

  • POST /api/upload
  • POST /api/analyze
  • GET /api/progress/:taskID (SSE)
  • POST /api/cancel/:taskID

Progress (SSE)

Subscribe to task progress updates via Server-Sent Events.

GET /api/progress/<taskID>
Accept: text/event-stream

SSE events:

  • event: connected (sent once on connect)
  • event: progress (JSON payload)
  • event: heartbeat (keep-alive)

progress event payload schema:

{
  "progress": 42,
  "message": "...",
  "status": "running"
}

status is one of: running / completed / failed. When completed or failed, the server closes the SSE stream.

If the task does not exist, the endpoint returns a normal JSON error response (not SSE):

{
  "success": false,
  "error": { "code": "TASK_NOT_FOUND", "message": "任务不存在" },
  "timestamp": "..."
}

If the client requests SSE (e.g. Accept: text/event-stream), the server emits a single event: progress with status="failed" and then closes the stream.

Common reasons include:

  • The server restarted (progress trackers are in-memory).
  • The task was cleaned up after completion/failure.
  • The task ID is invalid.

Cancel a task

Cancel a task by its task ID:

POST /api/cancel/<taskID>
Authorization: Bearer <token>
  • If a running job exists in the JobQueue, cancellation will be propagated to it.
  • The progress tracker is marked as failed with a "用户取消" reason so SSE subscribers can converge.

Config / Metrics

  • GET /api/config/health
  • GET /api/config/metrics

Users

All user endpoints are under /api/users/:user_id and require that :user_id matches the authenticated user.

  • GET /api/users/:user_id
  • PUT /api/users/:user_id
  • GET /api/users/:user_id/preferences
  • PUT /api/users/:user_id/preferences
  • GET /api/users/:user_id/items
  • POST /api/users/:user_id/items
  • GET /api/users/:user_id/items/:item_id
  • PUT /api/users/:user_id/items/:item_id
  • DELETE /api/users/:user_id/items/:item_id
  • GET /api/users/:user_id/skills
  • POST /api/users/:user_id/skills
  • GET /api/users/:user_id/skills/:skill_id
  • PUT /api/users/:user_id/skills/:skill_id
  • DELETE /api/users/:user_id/skills/:skill_id

WebSocket admin

  • GET /api/ws/status
  • POST /api/ws/cleanup

Key request examples

Create a scene

POST /api/scenes
Content-Type: application/json
Authorization: Bearer <token>

{
  "title": "My Scene",
  "text": "...source text..."
}

Create a script (New Script assistant)

POST /api/scripts
Content-Type: application/json
Authorization: Bearer <token>

{
  "title": "My Novel",
  "type": "novel",
  "framework": {
    "genre": "mystery",
    "chapter_count": 12,
    "notes": "slow-burn mystery with 12 chapters"
  }
}

Response (201)

{
  "success": true,
  "data": {
    "id": "script_12345",
    "title": "My Novel",
    "state": { "active_draft_id": "", "cursor": { "chapter": 1, "scene": 1 } }
  },
  "message": "Script created"
}

Start generation explicitly

POST /api/scripts/{id}/generate
Content-Type: application/json
Authorization: Bearer <token>

{}

Response (202)

{
  "success": true,
  "data": { "task_id": "task_abc123" },
  "message": "Generation started; subscribe to /api/progress/{task_id} for progress (SSE)"
}

Note: The generation process posts progress events to /api/progress/:taskID (SSE). Use GET /api/progress/<taskID> with Accept: text/event-stream to receive progress events.

Start analysis with SSE progress

  1. Start analysis:
POST /api/analyze
Content-Type: application/json
Authorization: Bearer <token>

{
  "title": "My Scene",
  "text": "...source text..."
}
  1. Subscribe progress (Server-Sent Events):
GET /api/progress/<taskID>
Accept: text/event-stream

SSE events:

  • event: connected
  • event: progress
  • event: heartbeat

WebSocket

Endpoints

  • GET /ws/scene/:id?user_id=<optional>
  • GET /ws/user/status?user_id=<required>

Protocol

This backend uses plain WebSocket (Gorilla WebSocket), not Socket.IO.

Messages are JSON objects with a type field.

Client → server supported types:

  • character_interaction
  • story_choice
  • user_status_update
  • ping

Server → client examples:

  • connected
  • conversation:new
  • story:choice_confirmed
  • user:presence
  • pong
  • heartbeat
  • error

Example send (client → server):

{
  "type": "ping"
}