chore: update external connector deployment flow

This commit is contained in:
2026-06-05 17:27:05 +08:00
parent 2c5205b06e
commit e0bc6c55b0
12 changed files with 318 additions and 93 deletions

View File

@ -15,7 +15,9 @@ class AgentRegistry:
self.path = self.workspace / "agents" / "registry.json"
self.path.parent.mkdir(parents=True, exist_ok=True)
if not self.path.exists():
self._write_agents(_builtin_agents())
self._write_agents([])
else:
self._drop_legacy_builtin_agents()
def list_agents(self, *, include_disabled: bool = True) -> list[RegisteredAgent]:
agents = self._read_agents()
@ -125,72 +127,14 @@ class AgentRegistry:
payload = {"version": 1, "agents": [agent.to_dict() for agent in agents]}
self.path.write_text(json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True) + "\n", encoding="utf-8")
def _drop_legacy_builtin_agents(self) -> None:
agents = self._read_agents()
migrated = [agent for agent in agents if agent.source != "builtin"]
if len(migrated) != len(agents):
self._write_agents(migrated)
def _terms(text: str) -> set[str]:
normalized = "".join(ch.lower() if ch.isalnum() else " " for ch in text)
return {part for part in normalized.split() if part}
def _builtin_agents() -> list[RegisteredAgent]:
return [
RegisteredAgent(
agent_id="researcher",
name="researcher",
display_name="Researcher",
role="research",
description="Finds facts, references, constraints, and implementation options.",
system_prompt="You are a research specialist. Gather concise evidence and tradeoffs for the parent task.",
capabilities=["research", "analysis", "source review", "requirements"],
tags=["planning", "research"],
priority=50,
source="builtin",
),
RegisteredAgent(
agent_id="implementer",
name="implementer",
display_name="Implementer",
role="implementation",
description="Builds scoped implementation slices and proposes concrete changes.",
system_prompt="You are an implementation specialist. Produce practical, scoped implementation output.",
capabilities=["implementation", "coding", "refactor", "integration"],
tags=["coding", "build"],
priority=45,
source="builtin",
),
RegisteredAgent(
agent_id="reviewer",
name="reviewer",
display_name="Reviewer",
role="review",
description="Reviews plans, code, outputs, and risks before final synthesis.",
system_prompt="You are a review specialist. Focus on defects, missing requirements, and risks.",
capabilities=["review", "quality", "risk", "verification"],
tags=["review", "quality"],
priority=45,
source="builtin",
),
RegisteredAgent(
agent_id="tester",
name="tester",
display_name="Tester",
role="testing",
description="Designs and executes verification checks for task outputs.",
system_prompt="You are a testing specialist. Identify focused checks and report pass/fail evidence.",
capabilities=["testing", "verification", "regression", "qa"],
tags=["test", "quality"],
priority=40,
source="builtin",
),
RegisteredAgent(
agent_id="documenter",
name="documenter",
display_name="Documenter",
role="documentation",
description="Writes and reconciles user-facing and internal documentation updates.",
system_prompt="You are a documentation specialist. Produce concise docs aligned with the implementation.",
capabilities=["documentation", "explanation", "migration notes", "release notes"],
tags=["docs", "communication"],
priority=35,
source="builtin",
),
]

View File

@ -2,6 +2,7 @@
from __future__ import annotations
import os
from typing import Any
from .models import ChannelRuntimeSpec, ValidationResult
@ -37,6 +38,7 @@ class ExternalConnectorBase:
self.credential_store = credential_store
self.sidecar_client = sidecar_client
self.sidecar_base_url = sidecar_base_url
self.callback_base_url = _callback_base_url()
async def start_session(
self,
@ -63,7 +65,7 @@ class ExternalConnectorBase:
"connectionId": connection.connection_id,
"channelId": connection.channel_id,
"displayName": connection.display_name,
"callbackBaseUrl": "",
"callbackBaseUrl": self.callback_base_url,
"options": dict(options),
}
view = dict(await self.sidecar_client.start_session(payload))
@ -176,6 +178,14 @@ def _policy_runtime_config(options: dict[str, Any]) -> dict[str, Any]:
return result
def _callback_base_url() -> str:
for name in ("EXTERNAL_CONNECTOR_CALLBACK_BASE_URL", "BEAVER_CONNECTOR_CALLBACK_BASE_URL"):
value = os.environ.get(name, "").strip()
if value:
return value.rstrip("/")
return ""
def _string_list(value: Any) -> list[str]:
if isinstance(value, str):
raw_items = value.replace("\n", ",").split(",")