fix(swarm): align Manager swarm-runtime default routes to HeiCode-Swarm standard

Per the HeiCode-Swarm 蜂群对接文档 §3.1, the swarm runtime standard routes are
/api/agent/swarm/* (legacy /api/swarms/* still works but is no longer default).
Swarm-only change; sub-agile (AGENT_RUNTIME_*) defaults and the agent_management
wiring are untouched.

- SWARM_RUNTIME default create/stop/approval -> /api/agent/swarm/deployments[...]
- swarm status: the runtime has no /status subpath, so status is read from the
  deployment detail endpoint GET /api/agent/swarm/deployments/{deployment_id};
  StatusPath/ArtifactContentPath defaults made mode-aware (sub keeps legacy).
- update the swarm HTTP smoke test to assert the standard runtime paths.

Verified reachable: HeiCode-Swarm at 52.139.240.116:8000 returns the standard
POST /api/agent/swarm/deployments (401 needs token, endpoint exists).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 17:45:00 +08:00
co-authored by Claude Opus 4.8
parent 78048858b9
commit 6fd294635f
2 changed files with 15 additions and 7 deletions
+13 -5
View File
@@ -100,11 +100,19 @@ func agentRuntimeClientConfigForMode(mode string) agentRuntimeConfig {
defaultCreatePath := "/api/agent/sub-agile/deployments"
defaultStopPath := "/api/agent/sub-agile/deployments/{deployment_id}/stop"
defaultApprovalPath := "/api/swarms/{swarm_id}/approvals/{approval_id}"
defaultStatusPath := "/api/swarms/{swarm_id}/status"
defaultArtifactContentPath := "/api/swarms/{swarm_id}/artifacts/{artifact_id}/content"
if mode == agentRuntimeModeSwarm {
prefix = "SWARM_RUNTIME_"
defaultCreatePath = "/api/swarms"
defaultStopPath = "/api/swarms/{swarm_id}/stop"
defaultApprovalPath = "/api/swarms/{swarm_id}/approvals/{approval_id}"
// HeiCode-Swarm standard routes (蜂群对接文档 §3.1). The runtime has no
// /status subpath — deployment status is read from the deployment detail
// endpoint. {deployment_id} resolves to the runtime deployment id.
// Legacy /api/swarms/* still works on the runtime but is no longer the
// Manager default. (sub-agile defaults above are untouched.)
defaultCreatePath = "/api/agent/swarm/deployments"
defaultStopPath = "/api/agent/swarm/deployments/{deployment_id}/stop"
defaultApprovalPath = "/api/agent/swarm/deployments/{deployment_id}/approvals/{approval_id}"
defaultStatusPath = "/api/agent/swarm/deployments/{deployment_id}"
if swarmTimeout := common.GetEnvOrDefault("SWARM_RUNTIME_TIMEOUT_SECONDS", timeoutSec); swarmTimeout > 0 {
timeoutSec = swarmTimeout
}
@@ -123,8 +131,8 @@ func agentRuntimeClientConfigForMode(mode string) agentRuntimeConfig {
Token: strings.TrimSpace(common.GetEnvOrDefaultString(prefix+"SERVICE_TOKEN", "")),
CreatePath: common.GetEnvOrDefaultString(prefix+"CREATE_PATH", defaultCreatePath),
HealthPath: common.GetEnvOrDefaultString(prefix+"HEALTH_PATH", "/api/agent/health"),
StatusPath: common.GetEnvOrDefaultString(prefix+"STATUS_PATH", "/api/swarms/{swarm_id}/status"),
ArtifactContentPath: common.GetEnvOrDefaultString(prefix+"ARTIFACT_CONTENT_PATH", "/api/swarms/{swarm_id}/artifacts/{artifact_id}/content"),
StatusPath: common.GetEnvOrDefaultString(prefix+"STATUS_PATH", defaultStatusPath),
ArtifactContentPath: common.GetEnvOrDefaultString(prefix+"ARTIFACT_CONTENT_PATH", defaultArtifactContentPath),
StopPath: common.GetEnvOrDefaultString(prefix+"STOP_PATH", defaultStopPath),
ApprovalDecisionPath: common.GetEnvOrDefaultString(prefix+"APPROVAL_DECISION_PATH", defaultApprovalPath),
Timeout: time.Duration(timeoutSec) * time.Second,
@@ -220,7 +220,7 @@ func TestSwarmRuntimeHTTPCreateUsesSwarmConfigAndPayload(t *testing.T) {
require.Equal(t, "Bearer swarm-runtime-token", r.Header.Get("Authorization"))
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"success":true,"data":{"status":"healthy","service":"heicode-swarm-runtime"}}`))
case r.Method == http.MethodPost && r.URL.Path == "/api/swarms":
case r.Method == http.MethodPost && r.URL.Path == "/api/agent/swarm/deployments":
swarmCreateCalled = true
require.Equal(t, "Bearer swarm-runtime-token", r.Header.Get("Authorization"))
require.Equal(t, "corr-swarm-smoke", r.Header.Get("X-Correlation-ID"))
@@ -242,7 +242,7 @@ func TestSwarmRuntimeHTTPCreateUsesSwarmConfigAndPayload(t *testing.T) {
require.Equal(t, "api_swarms_adapter", metadata["source"])
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"success":true,"data":{"deployment_id":"swarm-runtime-dep","swarm_id":"swarm-runtime-id","status":"running"}}`))
case r.Method == http.MethodPost && r.URL.Path == "/api/swarms/swarm-runtime-id/stop":
case r.Method == http.MethodPost && r.URL.Path == "/api/agent/swarm/deployments/swarm-runtime-dep/stop":
swarmStopCalled = true
require.Equal(t, "Bearer swarm-runtime-token", r.Header.Get("Authorization"))
w.Header().Set("Content-Type", "application/json")