feat: agent definition v2 (registry, persistence, developerInstructions channel)
Registry: POST /tasks accepts agent_name, loading <name>.json from repo-root agents/ (traversal-guarded, skill-pack re-validated); agent and agent_name together is a 400. Persistence: tasks gains agent_name/agent_version/agent_instructions (migrate + PG schema), returned by GET /tasks; stored prompt stays clean. Channel: local and docker dispatch pass --developer-instructions to host.py dispatch -> create_thread(developerInstructions=...); run/fork do not re-send. Cloud executor has no such channel, so the worker falls back to the v1 marked header in the in-memory dispatch prompt only (DB prompt stays clean). Goal/coordinator tasks still reject instructions. Tests: test_agent_def_v2.py (7 tests) + updated v1 suite.
This commit is contained in:
1 parent
7bb3c37a10
commit
1672ab9ff2
8 files changed
+361
-35
No files matched your search
+20
-4
@@ -351,7 +351,8 @@ class LocalExecutor(Executor):
|
||||
self.model = model
|
||||
|
||||
def _base_command(self, model=None, effort=None, approval=None,
|
||||
sandbox=None, model_provider=None):
|
||||
sandbox=None, model_provider=None,
|
||||
developer_instructions=None):
|
||||
cmd = [sys.executable, self.host_py_path]
|
||||
if self.config_path is not None:
|
||||
cmd += ["--config", self.config_path]
|
||||
@@ -367,6 +368,13 @@ class LocalExecutor(Executor):
|
||||
if effort:
|
||||
cmd += ["--effort", effort]
|
||||
cmd += _approval_cli_args(approval)
|
||||
# agent 定义 v2:仅 dispatch_task 传,run/fork/goal
|
||||
# 不传(线程已建好指令,续跑不重复发;fork 靠线程
|
||||
# 分叉继承,goal 不接受指令)。空值不传参,旧命令
|
||||
# 逐字节不变。
|
||||
if developer_instructions:
|
||||
cmd += ["--developer-instructions",
|
||||
developer_instructions]
|
||||
# 显式沙箱放最后:argparse 里后出现的 --sandbox 覆盖前面
|
||||
# 的(approval=full 自带 danger-full-access);server 侧
|
||||
# 已拒绝 plan+full 同存,这里是第二道防线。
|
||||
@@ -545,7 +553,9 @@ class LocalExecutor(Executor):
|
||||
approval=task.get("approval"),
|
||||
sandbox=("read-only"
|
||||
if task.get("plan") else None),
|
||||
model_provider=model_provider)
|
||||
model_provider=model_provider,
|
||||
developer_instructions=task.get(
|
||||
"agent_instructions"))
|
||||
cmd += ["dispatch", "--name", self._host_name(task),
|
||||
"--task", task["prompt"]]
|
||||
repo = task.get("repo") or self.repo
|
||||
@@ -1162,7 +1172,8 @@ class DockerExecutor(Executor):
|
||||
|
||||
def _inner_host_command(self, *args, model=None, effort=None,
|
||||
approval=None, sandbox=None,
|
||||
model_provider=None):
|
||||
model_provider=None,
|
||||
developer_instructions=None):
|
||||
"""容器内 host.py 命令:python3 /app/host.py [args...]。
|
||||
|
||||
config_path 若已给,容器内用 /app/<basename> 指代它——
|
||||
@@ -1191,6 +1202,10 @@ class DockerExecutor(Executor):
|
||||
cmd += _approval_cli_args(approval)
|
||||
if sandbox:
|
||||
cmd += ["--sandbox", sandbox]
|
||||
# agent 定义 v2:仅 dispatch_task 传,语义同本地版。
|
||||
if developer_instructions:
|
||||
cmd += ["--developer-instructions",
|
||||
developer_instructions]
|
||||
cmd += list(args)
|
||||
return cmd
|
||||
|
||||
@@ -1421,7 +1436,8 @@ class DockerExecutor(Executor):
|
||||
"--task", task["prompt"], model=task.get("model"),
|
||||
effort=task.get("effort"), approval=task.get("approval"),
|
||||
sandbox=("read-only" if task.get("plan") else None),
|
||||
model_provider=model_provider)
|
||||
model_provider=model_provider,
|
||||
developer_instructions=task.get("agent_instructions"))
|
||||
repo = task.get("repo")
|
||||
if repo:
|
||||
inner += ["--repo", repo]
|
||||
|
||||
Reference in new issue
Block a user