Sync sub-mode runtime docs and k8s updates

This commit is contained in:
elipitc
2026-06-01 23:10:33 +08:00
parent 9bc172b22a
commit 1b49887819
19 changed files with 511 additions and 384 deletions
Vendored
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
+4 -4
View File
@@ -220,11 +220,11 @@ async def emit_sub_mode_lifecycle_callbacks(
)
def get_agnet_namespace(user_id: str, binding_scope: str) -> str:
"""Generate namespace for Heicode deployments."""
def get_agent_namespace(user_id: str, binding_scope: str) -> str:
"""Generate namespace for Heicode agent deployments."""
combined = f"{user_id}:{binding_scope}"
hash_suffix = hashlib.sha256(combined.encode()).hexdigest()[:6]
namespace = f"agnet-{user_id}-{hash_suffix}"[:63]
namespace = f"agent-{user_id}-{hash_suffix}"[:63]
return namespace.lower().replace("_", "-")
@@ -399,7 +399,7 @@ async def create_deployment(
user_id = user_id or plan_user_context.get("user_id") or "default"
binding_scope = binding_scope or plan_user_context.get("binding_scope") or f"task-{plan_summary.get('intent_id') or deployment_id}"
correlation_id = correlation_id or request.metadata.get("correlation_id")
namespace = get_agnet_namespace(user_id, binding_scope)
namespace = get_agent_namespace(user_id, binding_scope)
# Create deployment record
deployment = Deployment(
+2 -2
View File
@@ -175,7 +175,7 @@ class ResourceGrant(BaseModel):
class CallbackConfig(BaseModel):
"""Callback configuration for Agnet -> Heicode event delivery."""
"""Callback configuration for Agent Runtime -> Heicode event delivery."""
url: str = Field(..., description="HTTPS callback endpoint")
signing_secret_ref: str = Field(..., description="Vault path to callback signing secret")
subscribed_events: List[str] = Field(
@@ -209,7 +209,7 @@ class CreateDeploymentRequest(BaseModel):
budget: Optional[BudgetConfig] = Field(None, description="Budget configuration")
billing_context: Optional[BillingContext] = Field(None, description="Billing and model gateway config")
resource_grants: List[ResourceGrant] = Field(default_factory=list, description="Resource grants")
callback: Optional[CallbackConfig] = Field(None, description="Agnet -> Heicode callback configuration")
callback: Optional[CallbackConfig] = Field(None, description="Agent Runtime -> Heicode callback configuration")
agile_context: Optional[Dict[str, Any]] = Field(None, description="Heicode sub-mode agile context")
sub_mode: Optional[str] = Field(None, description="Heicode sub mode: agile or waterfall")
metadata: Dict[str, Any] = Field(default_factory=dict, description="Additional metadata")
+1 -1
View File
@@ -40,7 +40,7 @@ def _utc_iso() -> str:
def _env_name_from_secret_ref(secret_ref: str) -> str:
"""Map azkv secret names to ENV names, e.g. agnet-callback-key."""
"""Map azkv secret names to ENV names, e.g. agent-callback-key."""
secret_name = secret_ref.rstrip("/").split("/")[-1]
return secret_name.upper().replace("-", "_")
+110
View File
@@ -460,6 +460,58 @@ class SwarmOrchestrator:
# Send message to agent
response = await client.send_message({"text": task})
if isinstance(response, dict) and response.get("error"):
error = response.get("error") or {}
message_text = error.get("message") if isinstance(error, dict) else str(error)
error_data = error.get("data") if isinstance(error, dict) else {}
if self._is_retryable_runtime_error(message_text or "") and agent_record:
retry_task = self._build_retry_task(agent_record, task, message_text or "gateway timeout")
retry_message = SwarmMessage(
message_id=str(uuid.uuid4()),
swarm_id=self.swarm_id,
from_agent_id=None,
to_agent_id=client.agent_id,
message_type="task_retry",
content=retry_task,
message_metadata={
"retry_reason": message_text,
"retryable": True,
},
)
self.db.add(retry_message)
self.db.commit()
self.swarm.total_messages += 1
agent_record.current_task = retry_task
self.db.commit()
await self._emit_tool_event(
"sk_tool.called",
client.agent_id,
{
"tool_name": "agent_task_retry",
"tool_invocation_id": retry_message.message_id,
"summary": "Retrying agent task with a reduced output contract",
"arguments_redacted": True,
},
)
response = await client.send_message({"text": retry_task})
if not (isinstance(response, dict) and response.get("error")):
usage = self._extract_usage(response)
model_metadata = self._extract_model_metadata(response)
await self._emit_tool_event(
"sk_tool.completed",
client.agent_id,
{
"tool_name": "agent_task_retry",
"tool_invocation_id": retry_message.message_id,
"summary": "Agent retry task completed",
"result_preview": str(response)[:500],
"model_usage": usage,
"newapi_request_id": model_metadata.get("newapi_request_id"),
"model_api_format": model_metadata.get("api_format"),
},
)
if isinstance(response, dict) and response.get("error"):
error = response.get("error") or {}
message_text = error.get("message") if isinstance(error, dict) else str(error)
@@ -812,8 +864,63 @@ class SwarmOrchestrator:
"Agile context: "
+ json.dumps(project_context["agile_context"], ensure_ascii=False, sort_keys=True)
)
prompt_parts.append(self._role_output_contract(agent.role))
return "\n".join(prompt_parts)
def _role_output_contract(self, role: Optional[str]) -> str:
"""Return a compact output contract tuned for runtime stability."""
normalized_role = (role or "worker").lower()
common = (
"Output contract: keep the response concise and implementation-oriented. "
"Prefer a minimal viable skeleton over a full project. "
"Do not exceed 12 bullets. Do not exceed 120 lines of code total."
)
role_contracts = {
"backend": (
"Return only: 1) a short API/data-model summary, "
"2) one compact Python/FastAPI code skeleton, "
"3) a brief test checklist."
),
"frontend": (
"Return only: 1) a short UI/component summary, "
"2) one compact React/JSX/CSS skeleton, "
"3) a brief interaction checklist."
),
"reviewer": (
"Return only: 1) major risks, 2) test cases, 3) release/blocking notes. "
"No long prose and no large code blocks."
),
"architect": (
"Return only: 1) architecture outline, 2) core modules, 3) key interfaces. "
"No large code blocks."
),
}
fallback = "Return a short implementation summary and one minimal code skeleton if needed."
return f"{common} {role_contracts.get(normalized_role, fallback)}"
def _build_retry_task(self, agent: Optional[SwarmAgent], original_task: str, error: str) -> str:
"""Build a smaller retry prompt when the first generation overloads the model gateway."""
role = agent.role if agent else "worker"
retry_instructions = (
"Previous attempt failed at the model gateway. Retry with a much smaller response. "
"Return only the single most important implementation skeleton for your role. "
"Limit output to at most 6 bullets and at most 60 lines of code total. "
"Skip optional explanations, examples, and secondary files."
)
return f"{original_task}\nRole: {role}\nRetry reason: {error}\n{retry_instructions}"
def _is_retryable_runtime_error(self, message: str) -> bool:
"""Classify model-gateway errors that benefit from a smaller retry."""
normalized = (message or "").lower()
retry_markers = (
"504 gateway time-out",
"504 gateway timeout",
"timed out",
"timeout",
"upstream request timeout",
)
return any(marker in normalized for marker in retry_markers)
def _response_summary(self, response: Any) -> str:
"""Return a readable response summary for logs, artifacts, and callbacks."""
text = self._extract_deliverable_text(response)
@@ -973,6 +1080,7 @@ class SwarmOrchestrator:
"redacted": True,
"agent_role": role,
"runtime_deployment_id": self.swarm_id,
"summary_only": False,
}
if stored:
metadata.update(
@@ -1057,6 +1165,8 @@ class SwarmOrchestrator:
"source": "agent-manager-sub-mode-runtime",
"runtime_deployment_id": self.swarm_id,
"agent_count": len(agents),
"synthesized": True,
"summary_only": True,
}
if stored:
metadata.update(
+1
View File
@@ -109,6 +109,7 @@ def _synthesized_artifacts_for_swarm(db: Session, swarm: Swarm) -> list[Dict[str
"source": "agent-manager-sub-mode-runtime",
"runtime_deployment_id": swarm.swarm_id,
"synthesized": True,
"summary_only": True,
"agent_count": len(agents),
"content_hash": stored.content_hash if stored else None,
"download_path": runtime_artifact_download_path(swarm.swarm_id, artifact_id),
+1 -1
View File
@@ -17,7 +17,7 @@ class Settings(BaseSettings):
IDEMPOTENCY_TTL_SECONDS: int = 86400 # 24 hours
# Kubernetes
NAMESPACE_PREFIX: str = "agnet"
NAMESPACE_PREFIX: str = "agent"
# Model gateways
HEICODE_NEWAPI_BASE_URL: str = "https://code.xinghanlab.com/v1"
+1 -1
View File
@@ -37,5 +37,5 @@ echo ""
echo "📝 Next steps:"
echo " 1. Port forward: kubectl port-forward -n agent-manager svc/agent-manager 8000:80"
echo " 2. Test health: curl http://localhost:8000/api/agent/health"
echo " 3. Compatibility health: curl http://localhost:8000/api/agnet/health"
echo " 3. Compatibility health (legacy): curl http://localhost:8000/api/agnet/health"
echo ""
+18 -18
View File
@@ -1,4 +1,4 @@
# Agnet → Heicode Manager 反向 Callback 契约 v1(提案)
# Agent Runtime → Heicode Manager 反向 Callback 契约 v1(提案)
> **状态**:DRAFT — 由 Heicode Manager 团队起草,发回给 Agent Manager 团队评审
> **配套阅读**:`HEICODE_API_INTEGRATION.md`(v2.0.0,正向:Heicode → Agent Manager)
@@ -29,10 +29,10 @@
### 1.1 正向(已实现,文档 v2.0.0)
```
Heicode Manager ──POST /api/agnet/deployments──▶ Agent Manager
──GET /api/agnet/.../logs────▶
──GET /api/agnet/.../events──▶
──GET /api/agnet/.../metrics─▶
Heicode Manager ──POST /api/agent/sub-agile/deployments──▶ Agent Manager
──GET /api/agent/.../logs────▶
──GET /api/agent/.../events──▶
──GET /api/agent/.../metrics─▶
```
### 1.2 反向(**未定义** — 本文要解决的)
@@ -67,7 +67,7 @@ Heicode Manager ◀──??? Agent Manager 怎么告诉我们:
│ │ │ 审批等事件触发 │
│ │ │ │
│ ③ 接收回调 │ ◀──POST {callback_url}───│ │
│ /api/agnet │ 含 HMAC 签名 + │ │
│ /api/agent │ 含 HMAC 签名 + │ │
│ /callback │ X-Agnet-Event-Id 幂等 │ │
│ │ │ │
│ ④ 200 OK 回执 │ ────────────────────────▶│ │
@@ -78,18 +78,18 @@ Heicode Manager ◀──??? Agent Manager 怎么告诉我们:
---
## 3. Heicode 侧注册(callback_url 怎么告诉 Agnet)
## 3. Heicode 侧注册(callback_url 怎么告诉 Agent Runtime)
### 3.1 创建部署时携带
扩展 `POST /api/agnet/deployments` 请求体,新增可选字段:
扩展 `POST /api/agent/sub-agile/deployments` 请求体,新增可选字段:
```json
{
"orchestration_plan": "...",
"agents": [ ... ],
"callback": {
"url": "https://code.xinghanlab.com/api/agnet/callbacks/swarm-events",
"url": "https://code.xinghanlab.com/api/agent/callbacks/runtime-events",
"signing_secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/agnet-callback-signing-key",
"subscribed_events": [
"phase.changed",
@@ -114,7 +114,7 @@ Heicode Manager ◀──??? Agent Manager 怎么告诉我们:
### 3.2 后绑定 / 修改(可选 P2 阶段)
```
PATCH /api/agnet/deployments/{deployment_id}/callback
PATCH /api/agent/sub-agile/deployments/{deployment_id}/callback
```
允许在部署运行期间更换 callback URL(例如 Heicode 灰度发布切换接收端)。
@@ -127,12 +127,12 @@ PATCH /api/agnet/deployments/{deployment_id}/callback
| 方法 | URL | 说明 |
|------|-----|------|
| `POST` | `{callback_url}` | Agnet 推送事件 |
| `POST` | `{callback_url}` | Agent Runtime 推送事件 |
Heicode 生产端点(建议):
```
POST https://code.xinghanlab.com/api/agnet/callbacks/swarm-events
POST https://code.xinghanlab.com/api/agent/callbacks/runtime-events
```
### 4.2 必需 Headers
@@ -405,7 +405,7 @@ HTTP/1.1 400 Bad Request
**Heicode 拿到这个事件后做什么**:
1. 推到桌面客户端的审批 UI(已有契约)
2. 用户点同意 / 拒绝
3. Heicode 调正向接口:`POST /api/agnet/deployments/{id}/approvals/{approval_id}` body `{ "decision": "granted" | "rejected", "reason": "..." }`
3. Heicode 调正向接口:`POST /api/agent/sub-agile/deployments/{id}/approvals/{approval_id}` body `{ "decision": "granted" | "rejected", "reason": "..." }`
### 5.6 `approval.granted` / 5.7 `approval.rejected`
@@ -521,11 +521,11 @@ stopped / failed 时 `failure_code` / `failure_message` 必填。
为了让 Heicode 这边在没有真实部署的情况下也能联调 callback 接收逻辑:
```
POST /api/agnet/_mock/emit_event
POST /api/agent/_mock/emit_event
Authorization: Bearer <SERVICE_TOKEN>
{
"callback_url": "https://code.xinghanlab.com/api/agnet/callbacks/swarm-events",
"callback_url": "https://code.xinghanlab.com/api/agent/callbacks/runtime-events",
"event_type": "phase.changed",
"deployment_id": "dep_mock_001",
"data": { "from_phase": null, "to_phase": "requirements" }
@@ -542,7 +542,7 @@ Authorization: Bearer <SERVICE_TOKEN>
```
agnet-cli mock-emit \
--target https://staging.heicode.local/api/agnet/callbacks \
--target https://staging.heicode.local/api/agent/callbacks \
--event sk_tool.called \
--deployment dep_mock_001 \
--signing-secret "$(cat /tmp/test-secret)"
@@ -578,7 +578,7 @@ agnet-cli mock-emit \
- Heicode 端校验 `X-Agnet-Timestamp` 落在 `now ± 5 分钟` 内
- 超出 → 返回 `400 SIGNATURE_INVALID`(防止回放)
- Agnet 端**必须**用 NTP 同步时钟,最大允许偏移 ±60 秒
- Agent Runtime 端**必须**用 NTP 同步时钟,最大允许偏移 ±60 秒
---
@@ -616,7 +616,7 @@ agnet-cli mock-emit \
- [ ] 实现 §6 mock-emit 接口
**Heicode Manager 侧**(不依赖 Agent Manager 完成):
- [ ] 实现 `/api/agnet/callbacks/swarm-events` 接收端
- [ ] 实现 `/api/agent/callbacks/runtime-events` 接收端
- [ ] 实现 §4.3 HMAC 校验、§4.4 幂等去重(复用 Redis SETNX,参考 V2 device-signature nonce 实现)
- [ ] 事件入审计表(复用 `agnet_audit_events`)
- [ ] 给桌面客户端 push 接口(已有 SSE 通道复用)
+66 -66
View File
@@ -23,7 +23,7 @@
- **当前 AKS 镜像 digest**: `sha256:b1931c1172fc23da8234e96dbdca34c4704644c2b2099391b362a48c47dc68f4`
- **Base URL(当前联调)**: `http://20.212.121.126`
- **Base URL(域名待切换)**: `https://agent-manager.taijiagnet.com`
- **主 API 前缀**: `/api/agnet`
- **主 API 前缀**: `/api/agent`
- **Runtime 兼容前缀**: `/api/swarms`
### 1.2 核心功能
@@ -50,7 +50,7 @@
▼
┌─────────────────────────────┐
│ Agent Manager API │
│ /api/agnet/* │
│ /api/agent/* │
└──────┬──────────────────────┘
│
▼
@@ -69,7 +69,7 @@
| 系统 | 职责 | 说明 |
|------|------|------|
| Heicode Manager | 用户、资源绑定、模型网关配置、审批、部署草稿、权限清单、回调持久化、artifact/timeline 展示 | 已有本地控制面和生产页面 |
| Agent Manager / Agnet Runtime | 接收 Manager 传入的部署计划,真实创建/调度子 Agent,执行任务,按回调协议回写状态、产物、用量和审批请求 | 需要支持本文定义的请求与回调字段 |
| Agent Manager / Agent Runtime | 接收 Manager 传入的部署计划,真实创建/调度子 Agent,执行任务,按回调协议回写状态、产物、用量和审批请求 | 需要支持本文定义的请求与回调字段 |
| Azure Key Vault | 长期密钥托管 | Manager/Runtime 只能使用 `azkv://...` 引用,不能传明文密钥 |
| NewAPI / CodeGW | 模型网关与计费入口 | Runtime 使用 Manager 提供的模型、预算和 `secret_ref` 上下文 |
@@ -89,7 +89,7 @@
| Callback HMAC 验签 | 已支持 | 支持 `X-Agnet-Signature` / `X-Agnet-Timestamp` / `X-Agnet-Event-Id` |
| Callback 旧认证兼容 | 已支持 | 过渡期仍接受 `X-Agnet-Service-Token` 或 `Authorization: Bearer` |
| Callback 幂等 | 已支持 | 优先读 `X-Agnet-Event-Id`,兼容 body `event_id` |
| Runtime 主动回调 | 已支持 | `/api/agnet/deployments` 与 `/api/swarms` 创建的 Runtime 执行阶段会主动推送 status/phase/timeline/agent/tool/artifact 事件 |
| Runtime 主动回调 | 已支持 | `/api/agent/sub-agile/deployments` 与 `/api/swarms` 创建的 Runtime 执行阶段会主动推送 status/phase/timeline/agent/tool/artifact 事件 |
| 普通 sub 真实 artifact 回调 | 已支持 | 普通 sub agent 真正执行后会生成 `artifact.created`,不再只返回 completed |
| Runtime artifact 内容读取 | 已支持 | Runtime 会优先用 K8s Secret 中的 Azure Blob 凭据上传完整产物;失败时回落本地 artifact store,metadata 中返回 URI、`content_hash` 和下载路径 |
| 普通 sub task 终态回调 | 已支持 | 新增 `task.completed` / `task.failed` / `task.blocked` 事件 |
@@ -103,7 +103,7 @@
| 顶层 `resource_grants` | 已支持 | 兼容 `agents[].resource_grants` 汇总 |
| legacy ResourceGrant 字段 | 已支持 | 兼容 `type / permissions / ref` 与 `resource_type / permission_scope / secret_ref` |
| artifact/timeline/SK snapshot 查询 | 已支持 | 从 callback 事件投影到用户态查询接口 |
| `approval.requested` / decision | 已支持 | callback 会持久化审批请求;Runtime 接收 `/api/swarms/{swarm_id}/approvals/{approval_id}` 与 `/api/agnet/deployments/{deployment_id}/approvals/{approval_id}` decision |
| `approval.requested` / decision | 已支持 | callback 会持久化审批请求;Runtime 接收 `/api/swarms/{swarm_id}/approvals/{approval_id}` 与 `/api/agent/sub-agile/deployments/{deployment_id}/approvals/{approval_id}` decision |
| `/api/swarms` 运行期查询 | 已支持 | 兼容 `status`、`stop`、`logs`、`events`、`metrics` 查询/控制路径 |
| `/api/swarms` 创建校验 | 已支持 | 缺少 `orchestration_plan` / `callback.url` / `sub_mode` / `user_context.user_id` 返回 422;`dry_run:true` 返回 422 且不创建真实 run |
| `/api/swarms` 幂等 | 已支持 | 同一个 `X-Idempotency-Key` 返回已有 run,不重复创建 |
@@ -124,14 +124,14 @@
| 场景 | 推荐接口 | 当前状态 |
|------|----------|----------|
| 健康检查 | `GET /api/agnet/health` | 已支持,无需业务 Header |
| 健康检查 | `GET /api/agent/health` | 已支持,无需业务 Header |
| 普通 sub 创建 Runtime run | `POST /api/swarms` | 已支持,要求结构化 `orchestration_plan` 和 `callback.url` |
| 旧版 Agent 部署创建 | `POST /api/agnet/deployments` | 已支持,可兼容结构化 sub plan |
| Runtime 主动事件回写 | `POST /api/agnet/callbacks/swarm-events` | 已支持 HMAC / 旧 token 过渡认证和幂等 |
| 旧版 Agent 部署创建 | `POST /api/agent/sub-agile/deployments` | 已支持,可兼容结构化 sub plan |
| Runtime 主动事件回写 | `POST /api/agent/callbacks/runtime-events` | 已支持 HMAC / 旧 token 过渡认证和幂等 |
| 查询 Runtime 状态 | `GET /api/swarms/{swarm_id}` 或 `/status` | 已支持,`deployment_id` 与 `swarm_id` 当前同值 |
| 查询产物 | `GET /api/agnet/user/deployments/{deployment_id}/artifacts` | 已支持,由 callback event 投影 |
| 查询时间线 | `GET /api/agnet/user/deployments/{deployment_id}/timeline` | 已支持,由 callback event 合并 |
| 查询 SK snapshot | `GET /api/agnet/user/deployments/{deployment_id}/sk-snapshots` | 已支持投影查询,独立解析接口待增强 |
| 查询产物 | `GET /api/agent/user/deployments/{deployment_id}/artifacts` | 已支持,由 callback event 投影 |
| 查询时间线 | `GET /api/agent/user/deployments/{deployment_id}/timeline` | 已支持,由 callback event 合并 |
| 查询 SK snapshot | `GET /api/agent/user/deployments/{deployment_id}/sk-snapshots` | 已支持投影查询,独立解析接口待增强 |
| 审批 decision | `POST /api/swarms/{swarm_id}/approvals/{approval_id}` | 已支持 `approved` / `rejected` |
当前实现边界:
@@ -149,8 +149,8 @@
1. 创建 Runtime run 后保存返回的 `deployment_id` / `swarm_id`。当前实现里二者同值。
2. 通过 callback 里的 `artifact.created` 事件,或轮询 `GET /api/swarms/{swarm_id}/status` 判断是否已有 artifact。
3. 调用 `GET /api/agnet/user/deployments/{deployment_id}/artifacts` 获取产物列表。
4. 从列表中取 `artifact_id`,调用 `GET /api/agnet/user/deployments/{deployment_id}/artifacts/{artifact_id}/content` 下载完整内容。
3. 调用 `GET /api/agent/user/deployments/{deployment_id}/artifacts` 获取产物列表。
4. 从列表中取 `artifact_id`,调用 `GET /api/agent/user/deployments/{deployment_id}/artifacts/{artifact_id}/content` 下载完整内容。
5. 如果 Manager 需要直接访问 Runtime 兼容层,也可以调用 `GET /api/swarms/{swarm_id}/artifacts/{artifact_id}/content`。
示例:
@@ -162,7 +162,7 @@ DEPLOYMENT_ID="swm_xxx"
curl -sS \
-H "Authorization: Bearer ${TOKEN}" \
"${BASE_URL}/api/agnet/user/deployments/${DEPLOYMENT_ID}/artifacts"
"${BASE_URL}/api/agent/user/deployments/${DEPLOYMENT_ID}/artifacts"
```
列表响应中的关键字段:
@@ -198,7 +198,7 @@ ARTIFACT_ID="art_backend_patch_001"
curl -L \
-H "Authorization: Bearer ${TOKEN}" \
-o "${ARTIFACT_ID}.txt" \
"${BASE_URL}/api/agnet/user/deployments/${DEPLOYMENT_ID}/artifacts/${ARTIFACT_ID}/content"
"${BASE_URL}/api/agent/user/deployments/${DEPLOYMENT_ID}/artifacts/${ARTIFACT_ID}/content"
```
生产环境产物存储规则:
@@ -256,7 +256,7 @@ Authorization: Bearer <HEICODE_SERVICE_TOKEN>
| `X-Idempotency-Key` | ⚪ | 幂等性键(推荐) | `idem_abc123` |
| `Content-Type` | ✅ | 内容类型 | `application/json` |
> `GET /api/agnet/health` 用于 K8s / LB 探活,不要求 `Authorization` 或业务追踪 Header。
> `GET /api/agent/health` 用于 K8s / LB 探活,不要求 `Authorization` 或业务追踪 Header。
### 2.3 获取 Service Token
@@ -268,13 +268,13 @@ Authorization: Bearer <HEICODE_SERVICE_TOKEN>
### 3.1 健康检查
#### `GET /api/agnet/health`
#### `GET /api/agent/health`
检查服务状态。
**请求示例**:
```bash
curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/health"
curl -X GET "https://agent-manager.taijiagnet.com/api/agent/health"
```
**响应示例**:
@@ -294,7 +294,7 @@ curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/health"
### 3.2 创建部署
#### `POST /api/agnet/deployments`
#### `POST /api/agent/sub-agile/deployments`
创建一个新的 Agent 部署。
@@ -332,7 +332,7 @@ curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/health"
}
],
"callback": {
"url": "https://code.xinghanlab.com/api/agnet/callbacks/swarm-events",
"url": "https://code.xinghanlab.com/api/agent/callbacks/runtime-events",
"signing_secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/agnet-callback-signing-key",
"subscribed_events": [
"phase.changed",
@@ -389,13 +389,13 @@ curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/health"
- `orchestration_plan.billing_context.default_model_id` / `allowed_model_ids` / `secret_ref` 会透传到 Runtime 配置。
- `resource_grants` 可放在顶层,也可放在 `agents[].resource_grants`,Runtime 会做兼容汇总。
- 如果请求包含 `callback`,Runtime 会按订阅事件主动回调 `deployment.status_changed`、`phase.changed`、`timeline.updated`、`agent.started`、`artifact.created`,并在需要审批时回调 `approval.requested`。
- `callback.url` 在 `/api/agnet/deployments` 中必须为 `https://`,`callback.signing_secret_ref` 必须为 `azkv://`。
- `callback.url` 在 `/api/agent/sub-agile/deployments` 中必须为 `https://`,`callback.signing_secret_ref` 必须为 `azkv://`。
---
### 3.3 列出部署
#### `GET /api/agnet/deployments`
#### `GET /api/agent/sub-agile/deployments`
获取部署列表,支持过滤和分页。
@@ -410,7 +410,7 @@ curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/health"
**请求示例**:
```bash
curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/deployments?user_id=user_123&status=running&limit=10" \
curl -X GET "https://agent-manager.taijiagnet.com/api/agent/sub-agile/deployments?user_id=user_123&status=running&limit=10" \
-H "Authorization: Bearer sk_xxx" \
-H "X-User-ID: user_123" \
-H "X-Binding-Scope: workspace_abc" \
@@ -445,7 +445,7 @@ curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/deployments?user_id=
### 3.4 获取部署详情
#### `GET /api/agnet/deployments/{deployment_id}`
#### `GET /api/agent/sub-agile/deployments/{deployment_id}`
获取指定部署的详细信息。
@@ -454,7 +454,7 @@ curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/deployments?user_id=
**请求示例**:
```bash
curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/deployments/dep_a1b2c3d4e5f6" \
curl -X GET "https://agent-manager.taijiagnet.com/api/agent/sub-agile/deployments/dep_a1b2c3d4e5f6" \
-H "Authorization: Bearer sk_xxx" \
-H "X-User-ID: user_123" \
-H "X-Binding-Scope: workspace_abc" \
@@ -510,7 +510,7 @@ curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/deployments/dep_a1b2
### 3.5 停止部署
#### `POST /api/agnet/deployments/{deployment_id}/stop`
#### `POST /api/agent/sub-agile/deployments/{deployment_id}/stop`
停止一个正在运行的部署。
@@ -527,7 +527,7 @@ curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/deployments/dep_a1b2
**请求示例**:
```bash
curl -X POST "https://agent-manager.taijiagnet.com/api/agnet/deployments/dep_a1b2c3d4e5f6/stop" \
curl -X POST "https://agent-manager.taijiagnet.com/api/agent/sub-agile/deployments/dep_a1b2c3d4e5f6/stop" \
-H "Authorization: Bearer sk_xxx" \
-H "X-User-ID: user_123" \
-H "X-Binding-Scope: workspace_abc" \
@@ -551,7 +551,7 @@ curl -X POST "https://agent-manager.taijiagnet.com/api/agnet/deployments/dep_a1b
### 3.6 获取部署日志
#### `GET /api/agnet/deployments/{deployment_id}/logs`
#### `GET /api/agent/sub-agile/deployments/{deployment_id}/logs`
获取部署的实时日志。
@@ -567,7 +567,7 @@ curl -X POST "https://agent-manager.taijiagnet.com/api/agnet/deployments/dep_a1b
**请求示例**:
```bash
curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/deployments/dep_a1b2c3d4e5f6/logs?limit=50" \
curl -X GET "https://agent-manager.taijiagnet.com/api/agent/sub-agile/deployments/dep_a1b2c3d4e5f6/logs?limit=50" \
-H "Authorization: Bearer sk_xxx" \
-H "X-User-ID: user_123" \
-H "X-Binding-Scope: workspace_abc" \
@@ -604,7 +604,7 @@ curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/deployments/dep_a1b2
### 3.7 获取部署事件
#### `GET /api/agnet/deployments/{deployment_id}/events`
#### `GET /api/agent/sub-agile/deployments/{deployment_id}/events`
获取部署的事件历史。
@@ -629,7 +629,7 @@ curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/deployments/dep_a1b2
**请求示例**:
```bash
curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/deployments/dep_a1b2c3d4e5f6/events" \
curl -X GET "https://agent-manager.taijiagnet.com/api/agent/sub-agile/deployments/dep_a1b2c3d4e5f6/events" \
-H "Authorization: Bearer sk_xxx" \
-H "X-User-ID: user_123" \
-H "X-Binding-Scope: workspace_abc" \
@@ -670,7 +670,7 @@ curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/deployments/dep_a1b2
### 3.8 获取资源指标
#### `GET /api/agnet/deployments/{deployment_id}/metrics`
#### `GET /api/agent/sub-agile/deployments/{deployment_id}/metrics`
获取部署的资源使用指标。
@@ -679,7 +679,7 @@ curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/deployments/dep_a1b2
**请求示例**:
```bash
curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/deployments/dep_a1b2c3d4e5f6/metrics" \
curl -X GET "https://agent-manager.taijiagnet.com/api/agent/sub-agile/deployments/dep_a1b2c3d4e5f6/metrics" \
-H "Authorization: Bearer sk_xxx" \
-H "X-User-ID: user_123" \
-H "X-Binding-Scope: workspace_abc" \
@@ -730,11 +730,11 @@ curl -X GET "https://agent-manager.taijiagnet.com/api/agnet/deployments/dep_a1b2
### 3.9 Runtime Callback 回写
#### `POST /api/agnet/callbacks/swarm-events`
#### `POST /api/agent/callbacks/runtime-events`
Agent Manager / Runtime 使用该接口向 Heicode Manager 回写 sub 模式事件、阶段变化、产物、预算告警、审批请求和 SK 工具调用结果。该接口是反向通知协议,不能仅依赖 `/events` 轮询替代。
#### `GET /api/agnet/callbacks/swarm-events/schema`
#### `GET /api/agent/callbacks/runtime-events/schema`
联调前可读取 callback schema。该接口只返回事件类型、分类、必填字段、阶段枚举和 artifact 类型,不返回 token、secret 或任何明文密钥。
@@ -826,7 +826,7 @@ Runtime 发送端签名密钥解析顺序:
| 触发时机 | 事件 |
|----------|------|
| `/api/agnet/deployments` 创建 accepted/running | `deployment.status_changed`、`phase.changed`、`timeline.updated`、`agent.started`、`artifact.created` |
| `/api/agent/sub-agile/deployments` 创建 accepted/running | `deployment.status_changed`、`phase.changed`、`timeline.updated`、`agent.started`、`artifact.created` |
| Swarm 初始化 / 运行 / 完成 / 失败 / 停止 | `deployment.status_changed` |
| 规划、实现、检查、完成等阶段变化 | `phase.changed`、`timeline.updated` |
| Agent 可运行 | `agent.started` |
@@ -879,22 +879,22 @@ Runtime 发送端签名密钥解析顺序:
| 方法 | 路径 | 调用方 | 用途 |
|------|------|--------|------|
| `POST` | `/api/agnet/user/tasks/{task_id}/deployment-draft` | Heicode 客户端 / Manager 前端 | 从任务卡生成 Agnet deployment draft |
| `POST` | `/api/agnet/user/deployments` | Heicode 客户端 / Manager 前端 | 用户态创建部署记录 |
| `GET` | `/api/agnet/user/deployments` | Heicode 客户端 / Manager 前端 | 用户态部署列表 |
| `GET` | `/api/agnet/user/deployments/{deployment_id}` | Heicode 客户端 / Manager 前端 | 用户态部署详情 |
| `POST` | `/api/agent/user/tasks/{task_id}/deployment-draft` | Heicode 客户端 / Manager 前端 | 从任务卡生成 Agent deployment draft |
| `POST` | `/api/agent/user/deployments` | Heicode 客户端 / Manager 前端 | 用户态创建部署记录 |
| `GET` | `/api/agent/user/deployments` | Heicode 客户端 / Manager 前端 | 用户态部署列表 |
| `GET` | `/api/agent/user/deployments/{deployment_id}` | Heicode 客户端 / Manager 前端 | 用户态部署详情 |
| `POST` | `/api/swarms` | Runtime 对接适配 / Manager | 创建 Swarm Run 的兼容入口,目前映射到 Manager 本地部署控制面 |
| `POST` | `/api/agnet/callbacks/swarm-events` | Agent Manager / Runtime | Runtime 回写状态、事件、artifact |
| `GET` | `/api/agnet/user/deployments/{deployment_id}/artifacts` | Heicode 客户端 / Manager 前端 | 查询部署产物 |
| `GET` | `/api/agnet/user/deployments/{deployment_id}/artifacts/{artifact_id}/content` | Heicode 客户端 / Manager 前端 | 下载完整产物内容 |
| `GET` | `/api/agnet/user/deployments/{deployment_id}/sk-snapshots` | Heicode 客户端 / Manager 前端 | 查询 SK 快照 |
| `GET` | `/api/agnet/user/deployments/{deployment_id}/timeline` | Heicode 客户端 / Manager 前端 | 查询合并时间线 |
| `POST` | `/api/agent/callbacks/runtime-events` | Agent Manager / Runtime | Runtime 回写状态、事件、artifact |
| `GET` | `/api/agent/user/deployments/{deployment_id}/artifacts` | Heicode 客户端 / Manager 前端 | 查询部署产物 |
| `GET` | `/api/agent/user/deployments/{deployment_id}/artifacts/{artifact_id}/content` | Heicode 客户端 / Manager 前端 | 下载完整产物内容 |
| `GET` | `/api/agent/user/deployments/{deployment_id}/sk-snapshots` | Heicode 客户端 / Manager 前端 | 查询 SK 快照 |
| `GET` | `/api/agent/user/deployments/{deployment_id}/timeline` | Heicode 客户端 / Manager 前端 | 查询合并时间线 |
说明:
1. `POST /api/swarms` 当前返回 `deployment_id` 和 `swarm_id`;当前二者同值,均可用于 Runtime 查询和停止。
2. 后续如果 Runtime 返回自己的真实 `swarm_id`,Manager 需要保存 `deployment_id <-> swarm_id` 映射。
3. Runtime 侧不能只支持 `/api/agnet/deployments`,否则无法覆盖 Heicode 用户态任务流。
3. Runtime 侧不能只支持 `/api/agent/sub-agile/deployments`,否则无法覆盖 Heicode 用户态任务流。
#### `POST /api/swarms`
@@ -951,7 +951,7 @@ Heicode sub 模式兼容入口。该接口接受结构化 `orchestration_plan`
"resource_grants": []
},
"callback": {
"url": "https://code.xinghanlab.com/api/agnet/callbacks/swarm-events",
"url": "https://code.xinghanlab.com/api/agent/callbacks/runtime-events",
"signing_secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/agnet-callback-signing-key"
}
}
@@ -980,7 +980,7 @@ Heicode sub 模式兼容入口。该接口接受结构化 `orchestration_plan`
}
},
"callback": {
"url": "https://code.xinghanlab.com/api/agnet/callbacks/swarm-events",
"url": "https://code.xinghanlab.com/api/agent/callbacks/runtime-events",
"signing_secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/agnet-callback-signing-key"
}
}
@@ -1039,7 +1039,7 @@ Heicode sub 模式兼容入口。该接口接受结构化 `orchestration_plan`
如果普通 sub 不走 `/api/swarms`,也支持:
```http
POST /api/agnet/deployments/{deployment_id}/approvals/{approval_id}
POST /api/agent/sub-agile/deployments/{deployment_id}/approvals/{approval_id}
```
**响应示例**:
@@ -1087,7 +1087,7 @@ POST /api/agnet/deployments/{deployment_id}/approvals/{approval_id}
}
```
#### `GET /api/agnet/user/deployments/{deployment_id}/artifacts`
#### `GET /api/agent/user/deployments/{deployment_id}/artifacts`
查询 Runtime 通过 `artifact.created` callback 回写的产物。当前 Manager 从 callback event payload 投影生成响应;大文件只返回 `uri`、摘要、大小和 hash 信息,完整内容需要继续调用 artifact content 接口读取。完整操作流程见 [1.7 产物获取速查](#17-产物获取速查)。
@@ -1119,7 +1119,7 @@ POST /api/agnet/deployments/{deployment_id}/approvals/{approval_id}
}
```
#### `GET /api/agnet/user/deployments/{deployment_id}/artifacts/{artifact_id}/content`
#### `GET /api/agent/user/deployments/{deployment_id}/artifacts/{artifact_id}/content`
读取 Runtime artifact 的完整内容。该接口是 Manager / 前端获取产物正文的推荐入口,要求携带 `Authorization: Bearer <HEICODE_SERVICE_TOKEN>`。
@@ -1138,7 +1138,7 @@ Azure Blob 凭据来自 `RUNTIME_ARTIFACT_BLOB_SECRET_NAMESPACE` / `RUNTIME_ARTI
curl -L \
-H "Authorization: Bearer <HEICODE_SERVICE_TOKEN>" \
-o artifact-output.txt \
"https://agent-manager.taijiagnet.com/api/agnet/user/deployments/{deployment_id}/artifacts/{artifact_id}/content"
"https://agent-manager.taijiagnet.com/api/agent/user/deployments/{deployment_id}/artifacts/{artifact_id}/content"
```
如果调用方已经持有 Runtime `swarm_id`,也可以直接使用兼容接口:
@@ -1150,7 +1150,7 @@ curl -L \
"https://agent-manager.taijiagnet.com/api/swarms/{swarm_id}/artifacts/{artifact_id}/content"
```
#### `GET /api/agnet/user/deployments/{deployment_id}/timeline`
#### `GET /api/agent/user/deployments/{deployment_id}/timeline`
查询合并时间线。当前 Manager 会合并 `timeline.updated`、阶段变化、Agent 状态、预算告警、审批请求、artifact 与 SK 工具事件。
@@ -1180,7 +1180,7 @@ curl -L \
}
```
#### `GET /api/agnet/user/deployments/{deployment_id}/sk-snapshots`
#### `GET /api/agent/user/deployments/{deployment_id}/sk-snapshots`
查询 Runtime 回写的 SK snapshot。当前 Manager 从 `sk_tool.called/completed/failed` 和包含 `sk_snapshot` 的 artifact 事件投影生成响应。
@@ -1322,7 +1322,7 @@ Heicode sub 模式使用扩展 Resource Grant 表达任务资源授权。Runtime
### 4.8 Artifact 回写模型
Runtime 通过 `/api/agnet/callbacks/swarm-events` 回写产物事件,Manager 将其持久化后供用户态接口查询。
Runtime 通过 `/api/agent/callbacks/runtime-events` 回写产物事件,Manager 将其持久化后供用户态接口查询。
```json
{
@@ -1458,7 +1458,7 @@ create_payload = {
}
response = requests.post(
f"{BASE_URL}/api/agnet/deployments",
f"{BASE_URL}/api/agent/sub-agile/deployments",
headers=headers,
json=create_payload
)
@@ -1471,7 +1471,7 @@ time.sleep(120) # 等待 2 分钟
# 3. 获取部署详情
response = requests.get(
f"{BASE_URL}/api/agnet/deployments/{deployment_id}",
f"{BASE_URL}/api/agent/sub-agile/deployments/{deployment_id}",
headers=headers
)
details = response.json()
@@ -1479,7 +1479,7 @@ print(f"📊 部署状态: {details['status']}")
# 4. 获取实时日志
response = requests.get(
f"{BASE_URL}/api/agnet/deployments/{deployment_id}/logs?limit=20",
f"{BASE_URL}/api/agent/sub-agile/deployments/{deployment_id}/logs?limit=20",
headers=headers
)
logs = response.json()
@@ -1487,7 +1487,7 @@ print(f"📝 最新日志: {len(logs['logs'])} 条")
# 5. 获取资源指标
response = requests.get(
f"{BASE_URL}/api/agnet/deployments/{deployment_id}/metrics",
f"{BASE_URL}/api/agent/sub-agile/deployments/{deployment_id}/metrics",
headers=headers
)
metrics = response.json()
@@ -1499,7 +1499,7 @@ stop_payload = {
"reason": "Task completed successfully"
}
response = requests.post(
f"{BASE_URL}/api/agnet/deployments/{deployment_id}/stop",
f"{BASE_URL}/api/agent/sub-agile/deployments/{deployment_id}/stop",
headers=headers,
json=stop_payload
)
@@ -1527,14 +1527,14 @@ headers = {
# 第一次请求
response1 = requests.post(
f"{BASE_URL}/api/agnet/deployments",
f"{BASE_URL}/api/agent/sub-agile/deployments",
headers=headers,
json=create_payload
)
# 重复请求(使用相同的 idempotency_key)
response2 = requests.post(
f"{BASE_URL}/api/agnet/deployments",
f"{BASE_URL}/api/agent/sub-agile/deployments",
headers=headers,
json=create_payload
)
@@ -1589,7 +1589,7 @@ payload = {
]
},
"callback": {
"url": "https://code.xinghanlab.com/api/agnet/callbacks/swarm-events",
"url": "https://code.xinghanlab.com/api/agent/callbacks/runtime-events",
"signing_secret_ref": "azkv://heicode-kv.vault.azure.net/secrets/agnet-callback-signing-key"
}
}
@@ -1604,7 +1604,7 @@ status.raise_for_status()
print(status.json()["status"])
timeline = requests.get(
f"{BASE_URL}/api/agnet/user/deployments/{run['deployment_id']}/timeline",
f"{BASE_URL}/api/agent/user/deployments/{run['deployment_id']}/timeline",
headers={"Authorization": f"Bearer {TOKEN}"}
)
timeline.raise_for_status()
@@ -1655,7 +1655,7 @@ print(len(timeline.json()["timeline"]))
```python
try:
response = requests.post(
f"{BASE_URL}/api/agnet/deployments",
f"{BASE_URL}/api/agent/sub-agile/deployments",
headers=headers,
json=create_payload
)
@@ -1763,7 +1763,7 @@ except requests.exceptions.HTTPError as e:
| v2.1.6 | 2026-05-29 | 修复普通 sub 真实执行后缺失 `artifact.created` 的问题,新增 `task.completed` / `task.failed` / `task.blocked` 事件,修复 deployment 与 agents 终态不一致,`/api/swarms/{id}/logs` 改为返回 Runtime 聚合摘要;部署镜像更新为 `heicode-v2-20260529120632` |
| v2.1.5 | 2026-05-28 | 文档修订:新增 v2.1.4 联调速查,补充 `/api/swarms` 最小请求、校验失败、状态响应和普通 sub 联调示例;修正 callback 当前实现为失败只记录 warning,重试/死信/replay 为后续增强 |
| v2.1.4 | 2026-05-28 | 按普通 sub 联调整改要求补齐 `/api/swarms` 参数校验、`dry_run` 拒绝、`deployment_id` 返回、detail 根路径、幂等创建和 usage/cost callback 字段;当前联调 Base URL 明确为 `http://20.212.121.126`,部署镜像更新为 `heicode-v2-20260528164612` |
| v2.1.3 | 2026-05-28 | 按普通 sub 敏捷模式任务清单补齐 `/api/agnet/deployments` 主动回调、`role_template` 兼容、callback schema、`/api/swarms/{id}` stop/status/logs/events/metrics、approval decision 接收路径,部署镜像更新为 `heicode-v2-20260528161931` |
| v2.1.3 | 2026-05-28 | 按普通 sub 敏捷模式任务清单补齐 `/api/agent/sub-agile/deployments` 主动回调、`role_template` 兼容、callback schema、`/api/swarms/{id}` stop/status/logs/events/metrics、approval decision 接收路径,部署镜像更新为 `heicode-v2-20260528161931` |
| v2.1.2 | 2026-05-28 | Agent Manager Runtime 支持按 callback 配置主动推送 status/phase/timeline/agent/tool/artifact 事件,补充发送端签名密钥解析顺序和失败策略,部署镜像更新为 `heicode-v2-20260528144233` |
| v2.1.1 | 2026-05-27 | 同步 Manager 当前实现状态:callback HMAC/旧 token 兼容、payload 投影、默认 subscribed_events、artifact/timeline/SK snapshot 查询示例、部署镜像版本 |
| v2.1.0 | 2026-05-26 | 补充 Heicode sub 模式敏捷开发契约、`/api/swarms` 兼容入口、`azkv://` secret_ref、artifact/timeline/SK snapshot 模型 |
+23 -23
View File
@@ -33,10 +33,10 @@
| deployment/agent 状态一致性 | ✅ 完成 | deployment 完成或失败时,agents 会同步进入终态 |
| `/api/swarms/{id}/logs` 兜底日志 | ✅ 完成 | 返回 Runtime 聚合日志摘要,而不是固定占位文本 |
| Callback HMAC/幂等接收 | ✅ 完成 | 支持 v2.1 HMAC,兼容旧 service token |
| artifact 查询 | ✅ 完成 | `GET /api/agnet/user/deployments/{deployment_id}/artifacts` |
| timeline 查询 | ✅ 完成 | `GET /api/agnet/user/deployments/{deployment_id}/timeline` |
| SK snapshot 查询投影 | ✅ 完成 | `GET /api/agnet/user/deployments/{deployment_id}/sk-snapshots` |
| 审批 decision | ✅ 完成 | 支持 `/api/swarms/.../approvals/...` 与 `/api/agnet/deployments/.../approvals/...` |
| artifact 查询 | ✅ 完成 | `GET /api/agent/user/deployments/{deployment_id}/artifacts` |
| timeline 查询 | ✅ 完成 | `GET /api/agent/user/deployments/{deployment_id}/timeline` |
| SK snapshot 查询投影 | ✅ 完成 | `GET /api/agent/user/deployments/{deployment_id}/sk-snapshots` |
| 审批 decision | ✅ 完成 | 支持 `/api/swarms/.../approvals/...` 与 `/api/agent/sub-agile/deployments/.../approvals/...` |
---
@@ -48,17 +48,17 @@
| 接口 | 路径 | 状态 | 文件位置 |
|------|------|------|----------|
| 1️⃣ 健康检查 | `GET /api/agnet/health` | ✅ 完成 | `api/agnet/router.py:20` |
| 2️⃣ 创建部署 | `POST /api/agnet/deployments` | ✅ 完成 | `api/agnet/deployments.py:123` |
| 3️⃣ 列出部署 | `GET /api/agnet/deployments` | ✅ 完成 | `api/agnet/deployments.py:346` |
| 4️⃣ 获取部署详情 | `GET /api/agnet/deployments/{id}` | ✅ 完成 | `api/agnet/deployments.py:408` |
| 5️⃣ 停止部署 | `POST /api/agnet/deployments/{id}/stop` | ✅ 完成 | `api/agnet/deployments.py:469` |
| 6️⃣ 获取日志 | `GET /api/agnet/deployments/{id}/logs` | ✅ 完成 | `api/agnet/deployments.py:596` |
| 7️⃣ 获取事件 | `GET /api/agnet/deployments/{id}/events` | ✅ 完成 | `api/agnet/deployments.py:679` |
| 8️⃣ 获取指标 | `GET /api/agnet/deployments/{id}/metrics` | ✅ 完成 | `api/agnet/deployments.py:731` |
| 1️⃣ 健康检查 | `GET /api/agent/health` | ✅ 完成 | `api/agnet/router.py:20` |
| 2️⃣ 创建部署 | `POST /api/agent/sub-agile/deployments` | ✅ 完成 | `api/agnet/deployments.py:123` |
| 3️⃣ 列出部署 | `GET /api/agent/sub-agile/deployments` | ✅ 完成 | `api/agnet/deployments.py:346` |
| 4️⃣ 获取部署详情 | `GET /api/agent/sub-agile/deployments/{id}` | ✅ 完成 | `api/agnet/deployments.py:408` |
| 5️⃣ 停止部署 | `POST /api/agent/sub-agile/deployments/{id}/stop` | ✅ 完成 | `api/agnet/deployments.py:469` |
| 6️⃣ 获取日志 | `GET /api/agent/sub-agile/deployments/{id}/logs` | ✅ 完成 | `api/agnet/deployments.py:596` |
| 7️⃣ 获取事件 | `GET /api/agent/sub-agile/deployments/{id}/events` | ✅ 完成 | `api/agnet/deployments.py:679` |
| 8️⃣ 获取指标 | `GET /api/agent/sub-agile/deployments/{id}/metrics` | ✅ 完成 | `api/agnet/deployments.py:731` |
| 9️⃣ Runtime 兼容入口 | `POST /api/swarms` | ✅ 完成 | `api/swarm/router.py` |
| 🔟 Callback 接收 | `POST /api/agnet/callbacks/swarm-events` | ✅ 完成 | `api/agnet/callbacks.py` |
| 1️⃣1️⃣ 用户态观测 | `/api/agnet/user/deployments/{id}/{artifacts,timeline,sk-snapshots}` | ✅ 完成 | `api/agnet/callbacks.py` |
| 🔟 Callback 接收 | `POST /api/agent/callbacks/runtime-events` | ✅ 完成 | `api/agnet/callbacks.py` |
| 1️⃣1️⃣ 用户态观测 | `/api/agent/user/deployments/{id}/{artifacts,timeline,sk-snapshots}` | ✅ 完成 | `api/agnet/callbacks.py` |
**实现亮点**:
- ✅ 完整的请求/响应模型定义
@@ -220,7 +220,7 @@ def create_service_account(self, namespace: str, role: str, user_id: str):
### 1. SSE 实时日志流
**接口**: `GET /api/agnet/deployments/{id}/logs/stream`
**接口**: `GET /api/agent/sub-agile/deployments/{id}/logs/stream`
**状态**: ❌ 未实现
@@ -247,7 +247,7 @@ async def stream_logs(deployment_id: str):
### 2. 资源作用域监控快照
**接口**: `GET /api/agnet/projects/{binding_scope}/dashboard-snapshot`
**接口**: `GET /api/agent/projects/{binding_scope}/dashboard-snapshot`
**状态**: ⚠️ 后续增强
@@ -263,7 +263,7 @@ async def stream_logs(deployment_id: str):
### 3. SK 快照解析
**接口**: `POST /api/agnet/sk-snapshots/resolve`
**接口**: `POST /api/agent/sk-snapshots/resolve`
**状态**: ⚠️ 后续增强
@@ -273,7 +273,7 @@ async def stream_logs(deployment_id: str):
### 4. SK 快照查询
**接口**: `GET /api/agnet/user/deployments/{id}/sk-snapshots`
**接口**: `GET /api/agent/user/deployments/{id}/sk-snapshots`
**状态**: ✅ 已实现(v2.1.4)
@@ -402,11 +402,11 @@ async def get_deployment_logs(...):
**优先级: 中**
1. ⚪ 实现资源作用域监控快照
- `GET /api/agnet/projects/{binding_scope}/dashboard-snapshot`
- `GET /api/agent/projects/{binding_scope}/dashboard-snapshot`
2. ⚪ 实现 SK 快照功能
- `POST /api/agnet/sk-snapshots/resolve`
- `GET /api/agnet/deployments/{id}/sk-snapshots`
- `POST /api/agent/sk-snapshots/resolve`
- `GET /api/agent/sub-agile/deployments/{id}/sk-snapshots`
### Phase 3: 基础设施配置(3-5 天)
@@ -425,7 +425,7 @@ async def get_deployment_logs(...):
**优先级: 低**
1. ⚪ 实现 SSE 实时日志流
- `GET /api/agnet/deployments/{id}/logs/stream`
- `GET /api/agent/sub-agile/deployments/{id}/logs/stream`
---
@@ -458,7 +458,7 @@ async def get_deployment_logs(...):
### AKS 部署版本
**当前 AKS 上的版本是 `heicode-v2-20260529120632`**,包含:
- ✅ 完整的 Heicode Agent API (`/api/agnet/*`)
- ✅ 完整的 Heicode Agent API (`/api/agent/*`)
- ✅ `/api/swarms` Runtime 兼容入口
- ✅ Runtime 主动 callback、artifact、timeline、SK snapshot 查询
- ✅ 普通 sub 真实执行后的 `artifact.created` 与 `task.*` 终态回调
+246 -233
View File
@@ -1,142 +1,120 @@
# Heicode Sub Mode Runtime 对接指南
# Heicode Sub Mode Runtime 接入说明
更新时间:2026-06-01
本文档是给 **Manager / 客户端 / 平台接入方** 的 sub mode 对接指南。目标不是解释历史背景,而是让别人能够基于本文档直接接通当前仓库提供的 **Sub Agile / 普通 sub 模式 Runtime**。
本文档描述当前仓库作为 **Sub Agile / 普通 sub 模式 Runtime** 时,对 Manager 暴露的接入契约。
## 1. 先记结论
这不是客户端主调用协议。
生产客户端主调用协议应由 `heicode-manager` 的 `/api/heicode/*` 定义并统一归口。
## 1. 文档边界
当前仓库只负责:
- `sub_agile` / 普通 sub 模式 Runtime
- Manager 下发后已校验的执行计划
- Runtime 事实回传:状态、事件、产物、审批请求、诊断信息
当前仓库不负责:
- 真正的 Swarm 产品模式
- 独立的 swarm-only API
- 客户端主调用协议
- 客户端展示状态裁决
- 本地修改的最终可信版本管理
- 云部署目标选择与云密钥直连
命名约定:
- `agent`:主命名,新的标准入口
- `agnet`:兼容命名,旧调用方继续可用
- `/api/swarms`:仅是 sub-mode compatibility API,不代表当前仓库实现独立 swarm 产品
- `agnet`:兼容命名,历史调用方继续可用
- `/api/swarms`:sub-mode compatibility API,不表示当前仓库实现独立 Swarm 系统
推荐接入原则:
生产调用边界:
1. 新接入统一走 `/api/agent/*`
2. 旧系统暂时可继续走 `/api/agnet/*`
3. 只有历史 Runtime 兼容方才使用 `/api/swarms`
```text
客户端 -> Manager /api/heicode/sub-agile/*
Manager -> agent_management /api/agent/sub-agile/*
agent_management -> Manager /api/agent/callbacks/runtime-events
客户端 <- Manager display_status / workflow / artifacts / diagnostics
```
## 2. 推荐接法
结论:
### 2.1 健康检查
- 生产客户端不应直连本 Runtime
- 本文档面向 Runtime 接入方、Manager 调用方、联调工程师
主路径:
## 2. 主路径与兼容路径
### 2.1 主路径
```text
GET /api/agent/health
POST /api/agent/sub-agile/deployments
GET /api/agent/sub-agile/deployments
GET /api/agent/sub-agile/deployments/{deployment_id}
POST /api/agent/sub-agile/deployments/{deployment_id}/stop
POST /api/agent/sub-agile/deployments/{deployment_id}/approvals/{approval_id}
GET /api/agent/sub-agile/deployments/{deployment_id}/logs
GET /api/agent/sub-agile/deployments/{deployment_id}/events
GET /api/agent/sub-agile/deployments/{deployment_id}/metrics
POST /api/agent/callbacks/runtime-events
GET /api/agent/callbacks/runtime-events/schema
```
兼容路径:
### 2.2 兼容路径
```text
GET /api/agnet/health
```
返回示例:
```json
{
"success": true,
"data": {
"status": "healthy",
"service": "agent-manager-sub-mode-runtime",
"version": "1.0.0",
"phase": "sub-mode-runtime"
}
}
```
### 2.2 创建 deployment
主路径:
```text
POST /api/agent/sub-agile/deployments
```
兼容路径:
```text
POST /api/agnet/deployments
GET /api/agnet/deployments
GET /api/agnet/deployments/{deployment_id}
POST /api/agnet/deployments/{deployment_id}/stop
POST /api/agnet/deployments/{deployment_id}/approvals/{approval_id}
GET /api/agnet/deployments/{deployment_id}/logs
GET /api/agnet/deployments/{deployment_id}/events
GET /api/agnet/deployments/{deployment_id}/metrics
POST /api/agnet/callbacks/swarm-events
GET /api/agnet/callbacks/swarm-events/schema
```
Runtime 兼容创建路径:
### 2.3 Legacy compatibility API
```text
POST /api/swarms
```
如果你是新接入方,优先使用:
```text
POST /api/agent/sub-agile/deployments
```
### 2.3 查询状态
主路径:
```text
GET /api/agent/sub-agile/deployments/{deployment_id}
```
兼容路径:
```text
GET /api/agnet/deployments/{deployment_id}
GET /api/swarms/{swarm_id}
GET /api/swarms/{swarm_id}/status
```
### 2.4 停止与审批
主路径:
```text
POST /api/agent/sub-agile/deployments/{deployment_id}/stop
POST /api/agent/sub-agile/deployments/{deployment_id}/approvals/{approval_id}
```
兼容路径:
```text
POST /api/agnet/deployments/{deployment_id}/stop
POST /api/agnet/deployments/{deployment_id}/approvals/{approval_id}
POST /api/swarms/{swarm_id}/stop
GET /api/swarms/{swarm_id}/logs
GET /api/swarms/{swarm_id}/events
GET /api/swarms/{swarm_id}/metrics
GET /api/swarms/{swarm_id}/artifacts/{artifact_id}/content
POST /api/swarms/{swarm_id}/approvals/{approval_id}
```
### 2.5 读取产物
### 2.4 用户态产物 / 时间线查询
推荐路径:
当前仓库仍保留以下内部 / 兼容查询面:
```text
GET /api/agent/user/deployments/{deployment_id}/artifacts
GET /api/agent/user/deployments/{deployment_id}/artifacts/{artifact_id}/content
GET /api/agent/user/deployments/{deployment_id}/timeline
GET /api/agent/user/deployments/{deployment_id}/sk-snapshots
```
兼容路径:
说明:
```text
GET /api/agnet/user/deployments/{deployment_id}/artifacts
GET /api/agnet/user/deployments/{deployment_id}/artifacts/{artifact_id}/content
GET /api/swarms/{swarm_id}/artifacts/{artifact_id}/content
```
- 这些路径更适合作为 Runtime / Manager 内部或兼容查询面
- 生产客户端不应直接消费这些路径
- 生产客户端应通过 Manager 的 `/api/heicode/*` 查询 artifacts / workflow / diagnostics
## 3. 状态语义
## 3. 状态语义与裁决边界
当前对外统一投影为以下状态:
### 3.1 Runtime 当前返回状态集合
当前 Runtime 对外统一投影:
```text
accepted
@@ -147,26 +125,51 @@ failed
stopped
```
含义建议:
### 3.2 Runtime 状态不等于客户端展示状态
- `accepted`:Runtime 已接单,尚未进入明确执行态
- `running`:至少有一个 subagent 正在执行
- `waiting_approval`:Runtime 请求用户审批,等待 decision
- `completed`:任务完成,并且已经有终态结果或产物
- `failed`:执行失败
- `stopped`:被显式停止
统一方案中应区分:
注意:
```text
client_task_status
cloud_deployment_status
runtime_execution_status
display_status
```
- 新创建 deployment 默认返回 `accepted`
- `approval.requested` 会把展示状态投影为 `waiting_approval`
- `/api/swarms` 虽然内部复用旧表和旧 runtime 记录,但对外也返回同一套状态集合
当前 Runtime 返回的 `status` 更接近:
```text
runtime_execution_status
```
尤其需要注意:
- Runtime `completed` 不等于用户最终看到的 `completed`
- 最终 `display_status` 必须由 Manager 根据结构化产物事实裁决
Manager 可能额外裁决出:
```text
queued
runtime_syncing
runtime_accepted
waiting_input
completed_without_deliverable
needs_codegen
offline_pending
```
推荐裁决原则:
```text
Runtime completed + has_deliverable=true + summary_only=false -> completed
Runtime completed + summary_only=true -> completed_without_deliverable 或 needs_codegen
Runtime completed + 无真实 artifact -> completed_without_deliverable 或 needs_codegen
```
## 4. 推荐请求结构
### 4.1 新接入推荐请求
推荐你用结构化 sub mode 请求,而不是只发自然语言字符串。
建议 Manager 传入结构化 sub mode 计划,而不是裸自然语言。
示例:
@@ -204,12 +207,6 @@ stopped
"template": "a2a_litellm_agent",
"model": "gpt-5.4",
"capabilities": ["code", "api", "test"]
},
{
"role": "frontend",
"template": "a2a_litellm_agent",
"model": "gpt-5.4",
"capabilities": ["ui", "react", "css"]
}
]
},
@@ -219,99 +216,46 @@ stopped
}
```
### 4.2 最低必填项
如果走 `/api/swarms` 兼容入口,最低要求至少要有:
最低必填项:
- `orchestration_plan`
- `orchestration_plan.sub_mode`
- `orchestration_plan.user_context.user_id`
- `callback.url`
否则会返回 `422`
## 5. 模型来源与信任边界
## 5. 创建响应与查询响应
生产环境中,Runtime 不应信任客户端直传的模型选择。
### 5.1 创建响应示例
正确边界:
```json
{
"deployment_id": "swm_xxx",
"swarm_id": "swm_xxx",
"status": "accepted",
"agents": [
{
"agent_id": "agi_backend_xxx",
"role": "backend",
"status": "pending",
"namespace": "swarm-swm-xxxx-backend",
"service_url": "http://agent-....svc.cluster.local:8000"
}
],
"created_at": "2026-06-01T12:00:00Z",
"estimated_ready_at": "2026-06-01T12:02:00Z"
}
```text
客户端选择模型
Manager 校验模型、套餐、权限、预算、allowed_model_ids
Manager 下发已校验 orchestration_plan
Runtime 只消费 Manager 下发的 model / billing_context / allowed_model_ids
```
字段说明:
约定:
- `deployment_id`:对外主标识
- `swarm_id`:仅为兼容字段;当前通常与 `deployment_id` 相同
- `agents`:当前 runtime 里为本次执行创建的 subagent 实例
### 5.2 状态响应示例
```json
{
"deployment_id": "swm_xxx",
"swarm_id": "swm_xxx",
"status": "completed",
"phase": "development",
"progress": 100,
"agents": [
{
"agent_id": "agi_backend_xxx",
"role": "backend",
"status": "completed",
"output": "后端实现摘要..."
}
],
"metrics": {
"total_messages": 4,
"tokens_used": 1514,
"elapsed_seconds": 33
},
"artifacts": [
{
"artifact_id": "art_xxx_backend_1",
"artifact_type": "code_patch",
"title": "backend task delivery",
"summary": "后端实现摘要...",
"uri": "azblob://...",
"metadata": {
"runtime_deployment_id": "swm_xxx",
"download_path": "/api/swarms/swm_xxx/artifacts/art_xxx_backend_1/content"
}
}
]
}
```
- Runtime 只信任 Manager 已校验的 `orchestration_plan`
- Runtime 不应把客户端未校验的 `model` 视为最终可信配置
## 6. 回调事件
### 6.1 主回调入口
主回调入口:
```text
POST /api/agent/callbacks/runtime-events
```
### 6.2 兼容回调入口
兼容回调入口:
```text
POST /api/agnet/callbacks/swarm-events
```
### 6.3 当前支持的关键事件
当前支持的关键事件:
- `deployment.status_changed`
- `phase.changed`
@@ -329,94 +273,161 @@ POST /api/agnet/callbacks/swarm-events
- `sk_tool.failed`
- `budget.alert`
### 6.4 接入建议
对接方至少应该消费:
最小消费建议:
1. `deployment.status_changed`
2. `phase.changed`
3. `artifact.created`
4. `approval.requested`
如果你只做最小接入,这四类事件足够支撑:
## 7. 产物语义
- 状态展示
- 阶段进度
- 产物列表刷新
- 审批按钮展示
### 7.1 当前真实 artifact
## 7. 产物读取约定
当前 Runtime 真实产物通常以:
### 7.1 推荐读取顺序
- `code_patch`
- `document`
推荐按照这个顺序读取结果:
返回,并提供:
1. 查询 deployment 状态
2. 等待 `status=completed`,或者在 `artifacts` 不为空时提前读取
3. 调用 artifacts list 接口获取 `artifact_id`
4. 再通过 content 接口拉完整正文
- `artifact_id`
- `summary`
- `uri`
- `metadata.download_path`
### 7.2 synthesized fallback artifact
### 7.2 fallback artifact
如果真实 agent 没有产出具体 artifact,runtime 会生成 fallback artifact。
当真实 agent 没有产出具体 artifact 时,Runtime 会生成 fallback artifact。
约定:
- fallback artifact 仍然会出现在 artifacts 列表中
- 它的用途是让 Manager 和客户端至少有一个可展示终态结果
- 识别方式是:
从本次升级开始,fallback artifact 必须稳定标记:
```json
{
"metadata": {
"synthesized": true
"synthesized": true,
"summary_only": true
}
}
```
## 8. 真实联调建议
语义说明:
这是本次线上验证后的建议,不是理论建议。
- `synthesized=true`:说明该产物是 Runtime 合成的兼容性结果
- `summary_only=true`:说明该产物只适合展示失败 / 总结,不应直接作为代码类任务的有效交付依据
### 8.1 当前稳定范围
Manager 不应将 `summary_only=true` 的 artifact 作为代码任务 `completed` 的充分条件。
当前 runtime 对以下任务更稳定:
### 7.3 project_folder artifact(推荐扩展)
对于结构性代码交付,统一方案推荐优先使用:
```text
artifact_type = project_folder
```
推荐形态:
```json
{
"artifact_id": "art_project_xxx",
"artifact_type": "project_folder",
"title": "Oracle Cloud Agency Site",
"summary": "包含 frontend、backend、docs 和部署配置的完整项目。",
"metadata": {
"root_dir": "oracle-cloud-agency-site",
"manifest_uri": "runtime://run_xxx/artifacts/art_project_xxx/manifest",
"archive_uri": "runtime://run_xxx/artifacts/art_project_xxx/archive.zip",
"content_hash": "sha256:project-tree-hash",
"file_count": 42,
"directory_count": 8
}
}
```
当前仓库尚未将 `project_folder` 作为默认真实产物类型,但后续扩展建议以此为主,而不是长期停留在单正文 `content` 下载模式。
## 8. 本地修改与 artifact revision(推荐扩展)
统一方案要求:
- 用户本地修改项目文件夹,不等于云端产物自动更新
- 客户端必须显式上传 local edit
- Manager 保存 `project artifact revision`
- Runtime 后续执行必须以最新 accepted revision 为基线
当前仓库尚未把这套 revision 协议实现为正式 Runtime 接口,但建议保留以下扩展方向:
```text
POST /api/agent/sub-agile/deployments/{deployment_id}/artifact-edits
```
推荐事件形态:
```json
{
"event_type": "artifact.local_edit_received",
"task_id": "task_xxx",
"deployment_id": "dep_xxx",
"runtime_deployment_id": "run_xxx",
"artifact_id": "art_project_xxx",
"project_revision": 2,
"source": "client_local_edit",
"manifest_uri": "manager://tasks/task_xxx/artifacts/art_project_xxx/revisions/2/manifest",
"archive_uri": "manager://tasks/task_xxx/artifacts/art_project_xxx/revisions/2/archive",
"content_hash": "sha256:new"
}
```
## 9. 云部署生命周期(推荐扩展)
统一方案中,云部署不应由客户端直传云密钥并直接驱动 Runtime。
正确边界:
```text
客户端只选择 target / environment / resource_binding_id
Manager 负责校验、审批、凭证解析、预算和审计
Runtime 或 Deploy Worker 执行 provider adapter
部署结果通过 deployment_manifest artifact 和 deployment events 回传
```
当前 Runtime 文档仅做说明,不将云部署声明为本仓库已完整实现能力。
## 10. 真实联调建议
### 10.1 当前稳定范围
当前 Runtime 更稳定的任务类型:
- 小型单文件函数生成
- 小型 React 组件生成
- 中小型实现摘要 / 代码骨架任务
- 经输出收缩后的中型真实编程任务
### 8.2 当前不稳定范围
### 10.2 当前高风险任务
当前 runtime 在以下任务上可能失败:
高风险特征:
- 单次 prompt 很长的真实开发任务
- 要求一次性输出大段后端 + 前端 + reviewer 的任务
- 输出内容过大、tokens 较高的代码生成任务
- 一次性要求完整项目所有文件
- 单 agent 输出过长代码、长解释、长测试、长部署说明
- 多角色同时高负载、每个角色都要求大体量正文
实际线上现象:
真实现象:
- 较大的真实编程任务可能在模型网关返回 `504 Gateway Time-out`
- 较大的任务可能在模型网关返回 `504 Gateway Time-out`
### 8.3 推荐任务拆分方式
### 10.3 推荐拆分方式
为了让 sub mode 更稳定,建议把一个大任务拆成多个小任务,例如:
建议把一个大任务拆成多个小任务:
- 先生成数据模型与 API 列表
- 再生成 CRUD 路由代码骨架
- 再生成 pytest 用例
- 前端单独生成为组件与样式骨架
- 再生成 CRUD 路由骨架
- 再生成测试样例
- 前端组件与样式单独生成
- reviewer 单独作为收尾检查任务
不要一上来就发:
- “生成完整后端项目”
- “生成完整前后端联调代码”
- “一次性给出所有页面、接口、测试和审查报告”
## 9. 模型网关配置要求
这是当前最容易踩坑的地方。
## 11. 模型网关配置要求
当前 runtime agent 需要一个真正返回模型 JSON 的 OpenAI 兼容基址。
@@ -443,9 +454,9 @@ https://code.xinghanlab.com
- `HEICODE_NEWAPI_BASE_URL=https://code.xinghanlab.com/v1`
- `LITELLM_BASE_URL=https://code.xinghanlab.com/v1`
## 10. 最小验证流程
## 12. 最小验证流程
### 10.1 服务与契约验证
### 12.1 服务与契约验证
```bash
curl http://127.0.0.1:8000/api/agent/health
@@ -453,7 +464,7 @@ curl http://127.0.0.1:8000/api/agnet/health
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest tests/test_sub_mode_runtime_contract.py -q
```
### 10.2 真实 smoke 验证
### 12.2 真实 smoke 验证
建议至少跑一条小型真实编程任务,例如:
@@ -463,11 +474,12 @@ PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python3 -m pytest tests/test_sub_mode_runtime_c
成功标准:
1. 创建响应返回 `accepted`
2. 最终状态到 `completed`
2. Runtime 最终状态到 `completed`
3. `artifacts` 非空
4. `artifacts/{artifact_id}/content` 返回可读正文,而不是 UUID、HTML 或空串
5. fallback artifact 必须带 `synthesized=true` / `summary_only=true`
## 11. 相关文件
## 13. 相关文件
主入口与兼容入口:
@@ -487,8 +499,9 @@ K8s 部署与配置:
---
如果接入方只想记最关键的三件事,只需要记:
如果接入方只想记最关键的四件事,只需要记:
1. 新接入统一走 `/api/agent/sub-agile/*`
2. 结果读取统一走 `deployment_id -> artifacts -> artifact content`
3. 模型网关基址必须是 `https://code.xinghanlab.com/v1`
1. 生产客户端只调用 Manager 的 `/api/heicode/*`
2. Manager 调 Runtime 统一走 `/api/agent/sub-agile/*`
3. Runtime `completed` 只是 runtime_execution_status,不等于最终 display_status
4. `summary_only=true` 的 artifact 不能直接当代码类任务有效交付物
+15 -15
View File
@@ -14,14 +14,14 @@
核心变化:
- `/api/swarms` 新增 Runtime 兼容入口,可接收 Heicode Manager 的结构化 `orchestration_plan`。
- `/api/agnet/deployments` 支持普通 sub 结构化计划,并会主动发出 Runtime 生命周期 callback。
- `/api/agent/sub-agile/deployments` 支持普通 sub 结构化计划,并会主动发出 Runtime 生命周期 callback。
- 修复普通 sub 真实执行后缺失 `artifact.created` 的问题,并补齐用户态 artifacts 可见性。
- 新增 `task.completed` / `task.failed` / `task.blocked` 事件,用于补齐普通 sub 子任务终态。
- 修复 deployment 已完成但 `agents[].status` 仍为 `running` 的状态不一致问题。
- `/api/swarms/{swarm_id}/logs` 不再返回 Phase 2 固定占位文本,而是输出 Runtime 聚合日志摘要。
- Callback 协议升级到 v2.1 形态,支持 HMAC 签名、幂等事件、`payload.*` 格式和旧 token 过渡兼容。
- 新增 artifact、timeline、SK snapshot 用户态查询接口,数据由 Runtime callback event 投影生成。
- 新增审批 decision 接收路径,覆盖 `/api/swarms` 和 `/api/agnet/deployments` 两种运行入口。
- 新增审批 decision 接收路径,覆盖 `/api/swarms` 和 `/api/agent/sub-agile/deployments` 两种运行入口。
- K8s/Docker 部署配置补充 Heicode、Vault、Redis、模型网关相关环境变量和代码目录。
---
@@ -55,10 +55,10 @@
响应兼容:
- `deployment_id` 与 `swarm_id` 同时返回;当前两者同值。
- `/api/agnet/deployments/{deployment_id}` 可查询 `/api/swarms` 创建出的 run。
- `/api/agnet/deployments/{deployment_id}/stop` 可停止 `/api/swarms` 创建出的 run。
- `/api/agent/sub-agile/deployments/{deployment_id}` 可查询 `/api/swarms` 创建出的 run。
- `/api/agent/sub-agile/deployments/{deployment_id}/stop` 可停止 `/api/swarms` 创建出的 run。
### 2.2 `/api/agnet/deployments` 普通 sub 兼容
### 2.2 `/api/agent/sub-agile/deployments` 普通 sub 兼容
创建部署现在可以直接接收结构化 `orchestration_plan`,并将字段提升到旧版模型:
@@ -94,7 +94,7 @@
### 3.1 Runtime 主动回调
`/api/agnet/deployments` 和 `/api/swarms` 创建的任务会根据 `callback.subscribed_events` 主动推送事件。
`/api/agent/sub-agile/deployments` 和 `/api/swarms` 创建的任务会根据 `callback.subscribed_events` 主动推送事件。
默认事件集:
@@ -126,7 +126,7 @@
新增接收接口:
```http
POST /api/agnet/callbacks/swarm-events
POST /api/agent/callbacks/runtime-events
```
支持能力:
@@ -142,7 +142,7 @@ POST /api/agnet/callbacks/swarm-events
联调 schema 接口:
```http
GET /api/agnet/callbacks/swarm-events/schema
GET /api/agent/callbacks/runtime-events/schema
```
该接口只返回事件类型、分类、必填字段、阶段枚举和 artifact 类型,不返回 token 或明文密钥。
@@ -153,9 +153,9 @@ GET /api/agnet/callbacks/swarm-events/schema
| 方法 | 路径 | 数据来源 |
|------|------|----------|
| `GET` | `/api/agnet/user/deployments/{deployment_id}/artifacts` | `artifact.created` callback payload |
| `GET` | `/api/agnet/user/deployments/{deployment_id}/timeline` | timeline、phase、agent、approval、budget、artifact、SK tool 事件合并 |
| `GET` | `/api/agnet/user/deployments/{deployment_id}/sk-snapshots` | `sk_tool.*` 与携带 `sk_snapshot` 的 artifact 事件 |
| `GET` | `/api/agent/user/deployments/{deployment_id}/artifacts` | `artifact.created` callback payload |
| `GET` | `/api/agent/user/deployments/{deployment_id}/timeline` | timeline、phase、agent、approval、budget、artifact、SK tool 事件合并 |
| `GET` | `/api/agent/user/deployments/{deployment_id}/sk-snapshots` | `sk_tool.*` 与携带 `sk_snapshot` 的 artifact 事件 |
注意:当前 artifact/timeline/SK snapshot 不是独立表字段化存储,而是由 callback event payload 投影生成。
@@ -168,7 +168,7 @@ GET /api/agnet/callbacks/swarm-events/schema
| 场景 | 接口 |
|------|------|
| `/api/swarms` run | `POST /api/swarms/{swarm_id}/approvals/{approval_id}` |
| 普通 deployment | `POST /api/agnet/deployments/{deployment_id}/approvals/{approval_id}` |
| 普通 deployment | `POST /api/agent/sub-agile/deployments/{deployment_id}/approvals/{approval_id}` |
decision 只接受:
@@ -221,14 +221,14 @@ Docker 镜像:
## 7. 建议联调清单
1. 调用 `GET /api/agnet/health` 确认服务可用。
2. 调用 `GET /api/agnet/callbacks/swarm-events/schema` 确认 callback schema 与事件类型。
1. 调用 `GET /api/agent/health` 确认服务可用。
2. 调用 `GET /api/agent/callbacks/runtime-events/schema` 确认 callback schema 与事件类型。
3. 使用 `POST /api/swarms` 创建普通 sub 敏捷 run,并传入 `X-Idempotency-Key`。
4. 重复第 3 步确认幂等返回已有 run。
5. 使用缺失 `callback.url`、缺失 `user_context.user_id`、`dry_run:true` 的 payload 验证 `422`。
6. 查询 `/api/swarms/{swarm_id}` 和 `/api/swarms/{swarm_id}/status` 验证 `deployment_id` / `swarm_id` 兼容。
7. 验证普通 sub 实际执行后会收到 `task.completed` / `task.failed` 回调。
8. 验证 Runtime 主动 callback 是否写入 `/api/agnet/user/deployments/{deployment_id}/timeline`。
8. 验证 Runtime 主动 callback 是否写入 `/api/agent/user/deployments/{deployment_id}/timeline`。
9. 验证普通 sub 实际执行后会收到 `artifact.created`,并查询 artifacts 不再为 0。
10. 发送 `sk_tool.completed` 或带 `sk_snapshot` 的 artifact callback 后查询 SK snapshots。
11. 触发或模拟 `approval.requested` 后调用 approval decision 接口验证 `approved` / `rejected`。
+1 -1
View File
@@ -31,7 +31,7 @@ spec:
containers:
- name: agent-manager
image: agnettaiji.azurecr.io/ai-agents/agent-manager:heicode-v2-runtime-20260601195848-arm64
image: agnettaiji.azurecr.io/ai-agents/agent-manager:heicode-v2-runtime-20260601225417-arm64
imagePullPolicy: Always
ports:
+1 -1
View File
@@ -22,7 +22,7 @@ spec:
- name: acr-secret
containers:
- name: agent-manager
image: agnettaiji.azurecr.io/ai-agents/agent-manager:heicode-v2-runtime-20260601195848-arm64
image: agnettaiji.azurecr.io/ai-agents/agent-manager:heicode-v2-runtime-20260601225417-arm64
imagePullPolicy: Always
ports:
- containerPort: 8000
+1 -1
View File
@@ -20,7 +20,7 @@ spec:
- name: acr-secret
containers:
- name: agent-manager
image: agnettaiji.azurecr.io/ai-agents/agent-manager:heicode-v2-runtime-20260601195848-arm64
image: agnettaiji.azurecr.io/ai-agents/agent-manager:heicode-v2-runtime-20260601225417-arm64
imagePullPolicy: Always
ports:
- containerPort: 8000
+4 -1
View File
@@ -2466,7 +2466,10 @@ echo "Identity volume initialized successfully"
or billing_context.get("timeout_seconds")
or (600 if stream_enabled else 300)
)
max_tokens = int(billing_context.get("max_tokens") or 4096)
requested_max_tokens = int(billing_context.get("max_tokens") or 4096)
role_token_cap = 1600 if role in {"backend", "frontend", "coder", "engineer", "fullstack"} else 1200
# Clamp per-agent output size to keep sub-mode runtime tasks stable on the gateway.
max_tokens = max(256, min(requested_max_tokens, role_token_cap))
# Get template image
# TODO: Load from template database