Skip to content

Commit 3537fe8

Browse files
committed
docs(agent-link): document runtime boundary, events, and upload API
1 parent eae10a0 commit 3537fe8

4 files changed

Lines changed: 209 additions & 0 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ docker run --rm -p 8000:8000 --env-file .env \
226226
## API 概览
227227

228228
- `GET /health` — 健康检查
229+
- **Agent Links**`GET /agent-links``GET /agent-links/{slug}``POST /agent-links/{slug}/session``POST /agent-links/{slug}/chat`
229230
- **Topics**`GET/POST /topics``GET/PATCH /topics/{topic_id}``POST /topics/{topic_id}/close`
230231
- **Posts**`GET/POST /topics/{topic_id}/posts``POST .../posts/mention``GET .../mention/{reply_post_id}`
231232
- **Discussion**`POST /topics/{topic_id}/discussion`(支持 `skill_list``mcp_server_ids`),`GET .../discussion/status`
@@ -236,6 +237,8 @@ docker run --rm -p 8000:8000 --env-file .env \
236237
- **Experts**`GET /experts`(支持 `fields=minimal`,列表不加载 skill_content),`GET /experts/{name}/content``GET/PUT /experts/{name}`
237238
- **Libs**`POST /libs/invalidate-cache` 立即清空库 meta 缓存(热更新)
238239

240+
Agent Links 蓝图目录约定:`libs/agent_links/<blueprint_dir>/agent.json`
241+
239242
详见 [docs/api-reference.md](docs/api-reference.md)
240243

241244
## 贡献

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ This directory contains technical implementation details and design docs for Res
1212
| [mcp-config.md](mcp-config.md) | MCP config API, validation (npm/uvx/remote only, no local) |
1313
| [testing.md](testing.md) | Test layers (unit/integration), .env setup, CI notes |
1414
| [api-reference.md](api-reference.md) | API endpoint list and brief descriptions |
15+
| [agent-links-runtime.md](agent-links-runtime.md) | Agent link runtime lifecycle: per-session workspace, SSE chat, import limits |
1516
| [skills-generalization.md](skills-generalization.md) | Library design; experts in `libs/experts/`; discussion modes in `libs/moderator_modes/` |
1617
| [skills-submodule-guide.md](skills-submodule-guide.md) | Add/update skill libraries via submodule; points to Cursor skill |
1718
| [import-skill-repo.md](import-skill-repo.md) | One-click import script for external skill repos |

docs/agent-links-runtime.md

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Agent Links Runtime
2+
3+
This document describes how `agent link` sessions run in the backend.
4+
5+
## Scope
6+
7+
- This runtime applies to `/agent-links/*` endpoints only.
8+
- It does not change `/profile-helper/*` behavior.
9+
10+
## Runtime Model
11+
12+
`agent link` chat uses Claude Agent SDK and creates an isolated workspace per session.
13+
14+
Flow:
15+
16+
1. Load blueprint metadata from `libs/agent_links/<slug>/agent.json`.
17+
2. Create or bind an in-memory session (`profile_helper.sessions`).
18+
3. Create a per-session working directory at:
19+
- `WORKSPACE_BASE/agent_links_sessions/<session_id>`
20+
4. Copy full blueprint content into that directory (first use only).
21+
5. Build system prompt from blueprint `rule_file_path` content.
22+
6. Run Claude Agent SDK query stream and return SSE chunks.
23+
24+
Implementation files:
25+
26+
- `app/api/agent_links.py`
27+
- `app/services/agent_links.py`
28+
- `app/services/agent_links_runtime.py`
29+
- `app/services/profile_helper/sessions.py`
30+
31+
## Session Workspace
32+
33+
- Blueprint root in metadata (`agent_workdir`) is a source template path.
34+
- Actual runtime execution path is session-specific:
35+
- `agent_session_workdir` stored in session data.
36+
- API returns runtime path in:
37+
- `POST /agent-links/{slug}/session` response `agent_workdir`
38+
- `POST /agent-links/{slug}/chat` header `X-Agent-Workdir`
39+
40+
## Cleanup Behavior
41+
42+
- Session cleanup is still controlled by in-memory session TTL and max-count:
43+
- `PROFILE_HELPER_SESSION_TTL_SECONDS`
44+
- `PROFILE_HELPER_SESSION_MAX_COUNT`
45+
- `agent_links_runtime.ensure_session_workspace(...)` performs best-effort orphan directory cleanup:
46+
- any directory under `WORKSPACE_BASE/agent_links_sessions/` whose name is not in active session IDs is removed.
47+
48+
## Prompt and Model
49+
50+
- Prompt source:
51+
- runtime prefers loading rule content from the copied session workspace path.
52+
- fallback reads blueprint `rule_file_path` when session path cannot be resolved.
53+
- if missing/unreadable, runtime falls back to `META_SYSTEM_PROMPT`.
54+
- Runtime always appends a workspace boundary system suffix:
55+
- only paths inside current session workspace are allowed
56+
- prefer relative paths from workspace root
57+
- reject absolute/outside paths and `..` traversal
58+
- Model priority:
59+
1. request body `model`
60+
2. blueprint `default_model`
61+
3. agent config default (`ANTHROPIC_MODEL`/configured model)
62+
63+
## Tools and Permissions
64+
65+
- Allowed tools are set from `DEFAULT_ALLOWED_TOOLS`.
66+
- Permission mode is `bypassPermissions` for agent link runtime.
67+
- Runtime passes `cwd` and `add_dirs` as the session workspace.
68+
69+
## Blueprint Import Limits
70+
71+
`POST /agent-links/import` and `/agent-links/import/preview`:
72+
73+
- only `.zip` uploads are accepted
74+
- max upload size is `5MB`
75+
- zip path traversal is blocked (`Invalid zip structure`)
76+
- preview returns up to 300 file paths plus total file count
77+
78+
## Session Workspace File Upload
79+
80+
`POST /agent-links/{slug}/files/upload`:
81+
82+
- uploads a file into current session workspace
83+
- supports `target_path` (relative subdirectory; default `uploads`)
84+
- blocks path escape outside workspace
85+
- max file size is `30MB`
86+
87+
## SSE Format
88+
89+
`POST /agent-links/{slug}/chat` returns `text/event-stream`.
90+
91+
- structured events:
92+
- `data: {"type":"assistant_delta","content":"..."}`
93+
- `data: {"type":"thinking","content":"..."}`
94+
- `data: {"type":"tool_call", ...}`
95+
- `data: {"type":"tool_result", ...}`
96+
- `data: {"type":"plan", ...}`
97+
- `data: {"type":"system", ...}`
98+
- `data: {"type":"result", ...}`
99+
- error event:
100+
- `data: {"error":"..."}`
101+
- end marker:
102+
- `data: [DONE]`
103+
104+
## Agent Link Chat UI Defaults
105+
106+
Current `agent link` chat page is intentionally simplified for end users:
107+
108+
- auto-sends a hidden first user message `"你好"` after session init, so the first assistant reply acts as welcome text
109+
- by default only renders normal dialogue and `plan` blocks
110+
- hides low-level runtime events (`thinking`, `tool_call`, `tool_result`, `system`) in this page
111+
- Enter sends message, but IME composing Enter (Chinese input method candidate selection) does not send

docs/api-reference.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,100 @@
1212
|--------|------|-------------|
1313
| POST | `/libs/invalidate-cache` | Clear meta cache for skills/mcp/moderator_modes (hot-reload) |
1414

15+
## Agent Links (Link as Agent)
16+
17+
| Method | Path | Description |
18+
|--------|------|-------------|
19+
| GET | `/agent-links` | List shareable agent blueprints |
20+
| GET | `/agent-links/{slug}` | Get one blueprint detail |
21+
| POST | `/agent-links/import/preview` | Preview zip file list before import |
22+
| POST | `/agent-links/import` | Import a blueprint zip into `libs/agent_links` |
23+
| POST | `/agent-links/{slug}/session` | Start (or bind) a chat session from a blueprint |
24+
| POST | `/agent-links/{slug}/chat` | Stream chat via blueprint-defined agent (SSE) |
25+
| POST | `/agent-links/{slug}/files/upload` | Upload a file to current session workspace |
26+
27+
### Blueprint Directory Convention
28+
29+
Blueprints can be placed under `libs/agent_links/<blueprint_dir>/` with an `agent.json`:
30+
31+
- `rule_file_path` points to the role/task rule file (for example: `.cursor/rules/profile-collector.mdc`)
32+
- `agent_workdir` in `agent.json` is the blueprint source directory
33+
- `welcome_message` is returned when a session starts
34+
35+
Example layout:
36+
37+
```text
38+
libs/agent_links/tashan-profile-helper_demo/
39+
├── agent.json
40+
├── .cursor/
41+
│ ├── rules/profile-collector.mdc
42+
│ └── skills/**/SKILL.md
43+
├── doc/*.md
44+
└── profiles/_template.md
45+
```
46+
47+
### `POST /agent-links/{slug}/session` response highlights
48+
49+
- `session_id`
50+
- `agent_link` (full blueprint metadata)
51+
- `welcome_message`
52+
- `agent_workdir` (runtime per-session workspace)
53+
54+
### `POST /agent-links/{slug}/chat` behavior
55+
56+
- Uses SSE (`text/event-stream`)
57+
- Runtime is Claude Agent SDK with per-session workspace copied from the blueprint
58+
- Response headers include:
59+
- `X-Session-Id`
60+
- `X-Agent-Link`
61+
- `X-Agent-Workdir` (runtime per-session workspace)
62+
- System prompt is derived from the blueprint `rule_file_path` content
63+
- Stream payload supports structured events:
64+
- `assistant_delta` (`content`)
65+
- `thinking`
66+
- `tool_call`
67+
- `tool_result`
68+
- `plan`
69+
- `system`
70+
- `result`
71+
- UI consumers may choose a subset (for example: dialogue + `plan`) and hide low-level events.
72+
73+
### `POST /agent-links/import/preview` behavior
74+
75+
- Accepts multipart zip file upload (`.zip` only)
76+
- Maximum zip size is `5MB`
77+
- Returns:
78+
- `files`: first 300 file paths from zip
79+
- `total`: total file count in zip
80+
81+
### `POST /agent-links/import` behavior
82+
83+
- Accepts multipart fields:
84+
- `file` (`.zip`, required)
85+
- `name` (required)
86+
- `rule_file_path` (required)
87+
- `welcome_message` (required)
88+
- `slug`, `description`, `default_model`, `overwrite` (optional)
89+
- Maximum zip size is `5MB`
90+
- Validation:
91+
- zip traversal is blocked (`Invalid zip structure`)
92+
- `rule_file_path` must resolve to a file inside imported blueprint
93+
94+
For runtime details, see [agent-links-runtime.md](agent-links-runtime.md).
95+
96+
### `POST /agent-links/{slug}/files/upload` behavior
97+
98+
- Accepts multipart fields:
99+
- `file` (required)
100+
- `session_id` (optional; if empty, backend creates a new bound session)
101+
- `target_path` (optional, default `uploads`)
102+
- Maximum file size is `30MB`
103+
- `target_path` must be relative and inside session workspace
104+
- Response:
105+
- `session_id`
106+
- `path` (relative path in workspace)
107+
- `size` (bytes)
108+
15109
## Topics
16110

17111
| Method | Path | Description |

0 commit comments

Comments
 (0)