Carry output format and tool surface on delegation requests (Q3 WP3)
Why: the delegation task brief must state goal, output format, tools and boundaries (Q3 acceptance); Request had no carriers for the two new sections, so delegate_task callers could not declare them. Evidence: TestDelegateToolRoundTrip extended to assert output_format and tools survive the tool-call round trip; runtime suite green (SELF); CI authoritative (GATE). Impact: additive Request fields + delegate_task schema/description; empty fields keep today's behavior (task brief sections omitted). Refs: Q3 plan WP3; Dev card .task/feature-agent-stack-q3.md
This commit is contained in:
@@ -27,6 +27,13 @@ type Request struct {
|
|||||||
NonGoals string `json:"non_goals,omitempty"`
|
NonGoals string `json:"non_goals,omitempty"`
|
||||||
DoneCriteria string `json:"done_criteria,omitempty"`
|
DoneCriteria string `json:"done_criteria,omitempty"`
|
||||||
Deliverables []string `json:"deliverables,omitempty"`
|
Deliverables []string `json:"deliverables,omitempty"`
|
||||||
|
// OutputFormat 交付物的结构/格式要求(Q3 WP3:委派模板四要素之一,
|
||||||
|
// 任务书「输出格式」节;空 = 由子代理自行决定)。
|
||||||
|
OutputFormat string `json:"output_format,omitempty"`
|
||||||
|
// Tools 允许子代理使用的工具面(Q3 WP3:任务书「工具面」节;空 = 沿用
|
||||||
|
// 子代理画像默认。宿主可按此收窄,不得用于扩权——子代理权限恒不超过
|
||||||
|
// 委派方)。
|
||||||
|
Tools []string `json:"tools,omitempty"`
|
||||||
// Deadline / MaxToolCalls 是宿主注入的预算余量(模型不可自行扩权)。
|
// Deadline / MaxToolCalls 是宿主注入的预算余量(模型不可自行扩权)。
|
||||||
Deadline time.Time `json:"-"`
|
Deadline time.Time `json:"-"`
|
||||||
MaxToolCalls int `json:"-"`
|
MaxToolCalls int `json:"-"`
|
||||||
@@ -67,7 +74,7 @@ func RegisterWithHooks(r *tools.Registry, factory Factory, bus *hooks.Bus) {
|
|||||||
|
|
||||||
func (t *delegateTool) Name() string { return "delegate_task" }
|
func (t *delegateTool) Name() string { return "delegate_task" }
|
||||||
func (t *delegateTool) Description() string {
|
func (t *delegateTool) Description() string {
|
||||||
return "Delegate a self-contained subtask to a fresh sub-agent. Fill every field: goal, inputs (with versions), write_scope (directory the sub-agent may write), non_goals, done_criteria, deliverables. The sub-agent cannot exceed your permissions; report back its conclusion and files."
|
return "Delegate a self-contained subtask to a fresh sub-agent. Fill every field: goal, inputs (with versions), write_scope (directory the sub-agent may write), non_goals, done_criteria, deliverables, output_format (structure/format the deliverables must follow), tools (tool names the sub-agent should use). The sub-agent cannot exceed your permissions; report back its conclusion and files."
|
||||||
}
|
}
|
||||||
func (t *delegateTool) Parameters() json.RawMessage {
|
func (t *delegateTool) Parameters() json.RawMessage {
|
||||||
return json.RawMessage(`{"type":"object","required":["goal","done_criteria"],"properties":{
|
return json.RawMessage(`{"type":"object","required":["goal","done_criteria"],"properties":{
|
||||||
@@ -77,6 +84,8 @@ func (t *delegateTool) Parameters() json.RawMessage {
|
|||||||
"non_goals":{"type":"string"},
|
"non_goals":{"type":"string"},
|
||||||
"done_criteria":{"type":"string"},
|
"done_criteria":{"type":"string"},
|
||||||
"deliverables":{"type":"array","items":{"type":"string"}},
|
"deliverables":{"type":"array","items":{"type":"string"}},
|
||||||
|
"output_format":{"type":"string"},
|
||||||
|
"tools":{"type":"array","items":{"type":"string"}},
|
||||||
"background":{"type":"boolean"}
|
"background":{"type":"boolean"}
|
||||||
}}`)
|
}}`)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ func TestDelegateToolRoundTrip(t *testing.T) {
|
|||||||
"write_scope":"research/",
|
"write_scope":"research/",
|
||||||
"non_goals":"不做实现",
|
"non_goals":"不做实现",
|
||||||
"done_criteria":"产出三来源对照表",
|
"done_criteria":"产出三来源对照表",
|
||||||
"deliverables":["notes.md","data/table.csv"]
|
"deliverables":["notes.md","data/table.csv"],
|
||||||
|
"output_format":"Markdown:结论先行,附三来源对照表",
|
||||||
|
"tools":["web_search","read_file"]
|
||||||
}`))
|
}`))
|
||||||
if res.IsError {
|
if res.IsError {
|
||||||
t.Fatal(res.Content)
|
t.Fatal(res.Content)
|
||||||
@@ -44,6 +46,11 @@ func TestDelegateToolRoundTrip(t *testing.T) {
|
|||||||
if got.Goal != "调研主题 X" || got.WriteScope != "research/" || got.DoneCriteria != "产出三来源对照表" {
|
if got.Goal != "调研主题 X" || got.WriteScope != "research/" || got.DoneCriteria != "产出三来源对照表" {
|
||||||
t.Fatalf("delegation fields lost: %+v", got)
|
t.Fatalf("delegation fields lost: %+v", got)
|
||||||
}
|
}
|
||||||
|
// Q3 WP3:输出格式与工具面随委派请求透传(任务书两节的声明源)。
|
||||||
|
if got.OutputFormat != "Markdown:结论先行,附三来源对照表" ||
|
||||||
|
strings.Join(got.Tools, ",") != "web_search,read_file" {
|
||||||
|
t.Fatalf("output_format/tools lost: %+v", got)
|
||||||
|
}
|
||||||
if !strings.Contains(res.Content, "[sub-agent succeeded]") ||
|
if !strings.Contains(res.Content, "[sub-agent succeeded]") ||
|
||||||
!strings.Contains(res.Content, "调研完成") ||
|
!strings.Contains(res.Content, "调研完成") ||
|
||||||
!strings.Contains(res.Content, "files: data/table.csv, notes.md") {
|
!strings.Contains(res.Content, "files: data/table.csv, notes.md") {
|
||||||
|
|||||||
Reference in New Issue
Block a user