Compare commits
2 Commits
c067881415
...
4569724cec
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4569724cec | ||
|
|
557e24883d |
@@ -12,6 +12,7 @@ Use a two-phase plan/apply workflow. Optimize for correct placement, not speed.
|
||||
- Treat the product hierarchy as `operation group -> project -> work -> review round`.
|
||||
- Never use a collection/delivery-set identifier. `collections`, `notes`, and `versions` are legacy compatibility names.
|
||||
- Never infer a project or work from a partial name, page position, recent activity, or a remembered ID.
|
||||
- At the start of every invocation, discover and explicitly ask the operator to confirm the exact operation group and project. A target confirmation from an earlier invocation cannot be reused.
|
||||
- Never create a work until the operator confirms the resolved group, project, content, image order, and confirmation code.
|
||||
- Never create a new round until the operator confirms the resolved work and current round.
|
||||
- Never retry a timed-out create request. First inspect current server state; otherwise a retry can create a duplicate round.
|
||||
@@ -38,7 +39,7 @@ Do not create groups, projects, API keys, feedback, or review decisions with thi
|
||||
|
||||
For both operations, require:
|
||||
|
||||
- Delivery Desk base URL. Default to `DELIVERY_DESK_BASE_URL` or `http://127.0.0.1:3010` only for local development.
|
||||
- Use the fixed Delivery Desk API address `http://192.168.30.90:3010`. Do not ask the operator to configure it. Use `--base-url` only when the operator explicitly instructs you to migrate or test another environment.
|
||||
- A valid API key in `DELIVERY_DESK_API_KEY`.
|
||||
- Exact target project, resolved to group ID/name and project ID/name/slug.
|
||||
- Ordered public image URLs or ordered local image paths.
|
||||
@@ -57,7 +58,7 @@ For `create_round`, also require:
|
||||
|
||||
When information is missing, ask one concise question listing only the missing fields. Do not proceed to mutation.
|
||||
|
||||
## 3. Discover authoritative IDs
|
||||
## 3. Discover and confirm the authoritative target
|
||||
|
||||
Use the bundled script from the skill directory:
|
||||
|
||||
@@ -73,8 +74,9 @@ Resolution rules:
|
||||
1. Match IDs first.
|
||||
2. Validate the project ID against its returned group ID, group name, project name, and slug.
|
||||
3. If the operator supplied only names, list exact matches with IDs and ask the operator to choose when zero or multiple matches exist.
|
||||
4. Even with one match, show the resolved identity before creating the plan.
|
||||
5. For a new round, verify the work belongs to the confirmed project.
|
||||
4. Even when the request already names a target or only one project is accessible, show the resolved group name/ID and project name/ID/slug and ask: `本次操作目标是否为:运营组「<group_name>」(ID <group_id>) / 项目「<project_name>」(ID <project_id>, slug <slug>)?请回复“确认目标”。`
|
||||
5. Accept only an explicit target confirmation given during the current invocation. Do not generate `plan-work` or `plan-round` before it.
|
||||
6. For a new round, verify the work belongs to the confirmed project.
|
||||
|
||||
Do not silently choose the only project merely because an API key currently exposes one.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
interface:
|
||||
display_name: "上传 Delivery Desk 作品"
|
||||
short_description: "精确定位运营组与项目,安全创建作品或提交新的验收轮次"
|
||||
default_prompt: "Use $upload-delivery-desk-work to safely locate the exact project and upload a work or a new review round."
|
||||
default_prompt: "Use $upload-delivery-desk-work to discover and ask me to confirm the exact operation group and project before uploading a work or a new review round."
|
||||
|
||||
@@ -19,6 +19,7 @@ from urllib.parse import quote, urlsplit
|
||||
from urllib.request import Request, urlopen
|
||||
|
||||
MAX_LOCAL_IMAGE_BYTES = 20 * 1024 * 1024
|
||||
DEFAULT_BASE_URL = "http://192.168.30.90:3010"
|
||||
LOCAL_IMAGE_TYPES = {
|
||||
".jpg": "image/jpeg",
|
||||
".jpeg": "image/jpeg",
|
||||
@@ -75,7 +76,7 @@ def api_key() -> str:
|
||||
|
||||
|
||||
def base_url(value: str | None = None) -> str:
|
||||
return (value or os.getenv("DELIVERY_DESK_BASE_URL") or "http://127.0.0.1:3010").rstrip("/")
|
||||
return (value or DEFAULT_BASE_URL).rstrip("/")
|
||||
|
||||
|
||||
def request_json(base: str, path: str, *, method: str = "GET", body: dict[str, Any] | None = None) -> tuple[int, Any]:
|
||||
@@ -461,7 +462,7 @@ def cmd_apply(args: argparse.Namespace) -> None:
|
||||
|
||||
|
||||
def add_common(command: argparse.ArgumentParser) -> None:
|
||||
command.add_argument("--base-url", default=None)
|
||||
command.add_argument("--base-url", default=None, help=f"Delivery Desk API 地址(默认:{DEFAULT_BASE_URL})")
|
||||
|
||||
|
||||
def add_content(command: argparse.ArgumentParser, *, title_required: bool) -> None:
|
||||
|
||||
@@ -67,10 +67,11 @@ flowchart LR
|
||||
- 点击图片打开悬浮图片窗格;只有该窗格可以新增坐标批注,并支持原图查看、缩放和前后切换。点击窗格外会同时关闭图片窗格和验收协作面板。
|
||||
- 标题、正文和 Tag 批注保存 `start_offset`、`end_offset`、`selected_text` 及前后文,提交时校验选区仍与轮次快照一致。
|
||||
- `GET /api/works/:workId/annotations` 按轮次返回图片批注、文字批注、总体反馈和验收事件。
|
||||
- `GET /api/works/:workId/optimization-context?round=N` 聚合指定轮次的内容、图片和可执行反馈,默认排除已关闭或撤回记录,供外部内容优化流程只读使用。
|
||||
|
||||
## Agent 安全上传
|
||||
|
||||
内置 Agent Skill 采用“发现目标 → 生成计划 → 人工确认 → 单次写入 → 读取核验”的两阶段流程。计划文件只保存目标 ID、待写内容和确认摘要,不保存 API Key,并写入已被 Git 忽略的 `tmp/` 目录。
|
||||
内置 Agent Skill 固定连接 `http://192.168.30.90:3010`,采用“发现目标 → 操作者确认运营组和项目 → 生成计划 → 操作者确认内容与确认码 → 单次写入 → 读取核验”的两阶段确认流程。计划文件只保存目标 ID、待写内容和确认摘要,不保存 API Key,并写入已被 Git 忽略的 `tmp/` 目录。
|
||||
|
||||
新建作品以 `externalId` 保证幂等;新增验收轮次没有幂等键。轮次写入超时或响应不明确时,必须先重新读取作品状态,不能直接重试,以免重复创建轮次。
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ Authorization: Bearer dd_live_xxx
|
||||
|
||||
## Agent 安全上传 Skill
|
||||
|
||||
项目内置 `.agents/skills/upload-delivery-desk-work`,用于引导 Agent 精确定位运营组、项目和作品后创建作品或提交新验收轮次。它强制执行“发现 → 生成计划 → 操作者确认 → 单次提交 → 回读验证”,不允许根据名称猜测目标。
|
||||
项目内置 `.agents/skills/upload-delivery-desk-work`,用于引导 Agent 精确定位运营组、项目和作品后创建作品或提交新验收轮次。它固定连接 `http://192.168.30.90:3010`,并强制执行“发现 → 操作者确认运营组与项目 → 生成计划 → 操作者确认内容 → 单次提交 → 回读验证”,不允许根据名称猜测目标。
|
||||
|
||||
更新 Skill 后重新生成分发包:
|
||||
|
||||
@@ -113,8 +113,14 @@ curl "http://localhost:3010/api/works/12?round=2" \
|
||||
# 按轮返回该作品全部反馈和验收事件
|
||||
curl http://localhost:3010/api/works/12/annotations \
|
||||
-H "Authorization: Bearer $DELIVERY_DESK_API_KEY"
|
||||
|
||||
# 返回用于优化指定轮次内容与图片的精简上下文;默认只含未撤回的开放反馈
|
||||
curl "http://localhost:3010/api/works/12/optimization-context?round=2" \
|
||||
-H "Authorization: Bearer $DELIVERY_DESK_API_KEY"
|
||||
```
|
||||
|
||||
`optimization-context` 返回项目、作品、轮次、标题、正文、Tag、图片元信息,以及图片批注、文字批注、总体反馈和回复。需要审计已关闭或已撤回的历史反馈时增加 `include_history=true`;该接口只读,不会修改作品。
|
||||
|
||||
标题、正文和 Tag 选区批注使用:
|
||||
|
||||
```json
|
||||
|
||||
@@ -57,6 +57,8 @@ JSON URL 导入依赖活动 COS 配置。同一 COS/CDN 域名的图片直接使
|
||||
|
||||
Agent 通过 API 新建作品或提交验收轮次时,使用 `.agents/skills/upload-delivery-desk-work`。API Key 只通过 `DELIVERY_DESK_API_KEY` 环境变量注入,不写入计划文件、文档或 Git。
|
||||
|
||||
Skill 默认固定连接 `http://192.168.30.90:3010`,不读取环境变量覆盖服务地址。只有操作者明确要求迁移或测试其他环境时,才使用 `--base-url` 指定另一地址。
|
||||
|
||||
Agent 可用 `--image-url` 提交公网图片,也可用 `--image-file` 将生成在运营电脑上的本地图片直接 multipart 上传;两种模式不混用,不把图片转换为 Base64。
|
||||
|
||||
```powershell
|
||||
|
||||
Binary file not shown.
@@ -70,6 +70,21 @@ def apply_silently(path: Path, code: str) -> dict:
|
||||
|
||||
|
||||
def main() -> None:
|
||||
previous_base_url = os.environ.get("DELIVERY_DESK_BASE_URL")
|
||||
os.environ["DELIVERY_DESK_BASE_URL"] = "http://should-not-override.invalid"
|
||||
try:
|
||||
assert MODULE.base_url() == "http://192.168.30.90:3010"
|
||||
assert MODULE.base_url("https://delivery.example.com/") == "https://delivery.example.com"
|
||||
finally:
|
||||
if previous_base_url is None:
|
||||
os.environ.pop("DELIVERY_DESK_BASE_URL", None)
|
||||
else:
|
||||
os.environ["DELIVERY_DESK_BASE_URL"] = previous_base_url
|
||||
|
||||
skill_text = (SCRIPT.parents[1] / "SKILL.md").read_text(encoding="utf-8")
|
||||
assert "请回复“确认目标”" in skill_text
|
||||
assert "Do not generate `plan-work` or `plan-round` before it." in skill_text
|
||||
|
||||
original_exact_project = MODULE.exact_project
|
||||
original_request_json = MODULE.request_json
|
||||
original_request_multipart = MODULE.request_multipart
|
||||
|
||||
Reference in New Issue
Block a user