Why: agent-document-renderer 31fbe54 publishes company.default@1.0.0 with review status approved and publicationAllowed true (owner decision 2026-10-16: A4, ~2.5cm margins, SimSun + Times New Roman 12pt body, SimHei headings, no logo). Backend still hard-coded Candidate=true and every prompt, skill and tool text called the default a pending-human-visual-review candidate. Evidence: go vet ./... exit 0; gofmt -l on changed packages empty; go test -count=1 ./internal/docgen/... ./internal/prompts/... ./internal/skills/... ./internal/tools/... ok; go test -count=1 ./... exit 0 (42 packages ok); go build ./... and CGO_ENABLED=0 go build ./cmd/agent-system ok; git diff --cached --check clean. New tests failed before the change. Impact: bump deps/agent-document-renderer 0d1c512 -> 31fbe54 and regenerate the renderer identity. The manifest profile receipt now reports the renderer's own review status and derives Candidate from the snapshot state (false for the published default). Prompts (base.deliverables v12, tool.render_document v2, task.report v4, task.doc-minutes v4), docx-author and house-style skills, the render_document tool description and comparison exception details describe the default as published (approved by owner 2026-10-16) while still limiting it to ordinary uncontrolled workspace working/preview Word. Routing is unchanged: project, controlled, special-template, review and approved outputs still go to RDM, with no Backend default fallback and no legacy Word builder fallback. Refs: unified renderer plan Tasks 7/10 Co-authored-by: Cursor <cursoragent@cursor.com>
102 lines
4.0 KiB
Go
102 lines
4.0 KiB
Go
package tools
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
|
|
"agent-document-renderer/render"
|
|
"agent-system-backend/internal/docgen"
|
|
core "agent-system-core"
|
|
)
|
|
|
|
func registerDocumentRenderer(r *Registry) error {
|
|
return r.Register(core.ToolDesc{
|
|
Name: "render_document", Source: core.SourceBuiltin, Edits: true, Risk: "medium",
|
|
Description: "把普通工作区 Markdown 通过统一文档渲染器生成 Markdown、DOCX、manifest 和可下载归档。只允许非受控工作区交付;项目受控文档必须交给 RDM。公司默认规则已发布(负责人 2026-10-16 批准),但只用于普通工作区的 working/preview 交付,评审状态会写入 manifest。",
|
|
Parameters: json.RawMessage(`{"type":"object","additionalProperties":false,"properties":{` +
|
|
`"operationId":{"type":"string"},"name":{"type":"string"},"documentId":{"type":"string"},"documentType":{"type":"string"},` +
|
|
`"language":{"type":"string"},"markdown":{"type":"string"},` +
|
|
`"mode":{"type":"string","enum":["working","preview"]},` +
|
|
`"controlled":{"type":"boolean"},"projectDocument":{"type":"boolean"}` +
|
|
`},"required":["operationId","name","documentId","markdown","controlled","projectDocument"]}`),
|
|
}, executeDocumentRenderer)
|
|
}
|
|
|
|
type documentRendererArgs struct {
|
|
OperationID string `json:"operationId"`
|
|
Name string `json:"name"`
|
|
DocumentID string `json:"documentId"`
|
|
DocumentType string `json:"documentType"`
|
|
Language string `json:"language"`
|
|
Markdown string `json:"markdown"`
|
|
Mode string `json:"mode"`
|
|
Controlled *bool `json:"controlled"`
|
|
ProjectDocument *bool `json:"projectDocument"`
|
|
}
|
|
|
|
type documentDeliveryHost interface {
|
|
ExecuteDocumentDelivery(context.Context, docgen.OperationRequest) (docgen.OperationReceipt, error)
|
|
}
|
|
|
|
func executeDocumentRenderer(rc ToolExecCtx, raw json.RawMessage) (string, error) {
|
|
var args documentRendererArgs
|
|
decoder := json.NewDecoder(bytes.NewReader(raw))
|
|
decoder.DisallowUnknownFields()
|
|
if err := decoder.Decode(&args); err != nil {
|
|
return "", fmt.Errorf("render_document: bad args: %w", err)
|
|
}
|
|
var extra any
|
|
if err := decoder.Decode(&extra); !errors.Is(err, io.EOF) {
|
|
return "", errors.New("render_document: arguments must contain one JSON object")
|
|
}
|
|
if strings.TrimSpace(args.OperationID) == "" || strings.TrimSpace(args.Name) == "" || strings.TrimSpace(args.DocumentID) == "" || strings.TrimSpace(args.Markdown) == "" {
|
|
return "", errors.New("render_document: operationId, name, documentId, and markdown are required")
|
|
}
|
|
if args.Controlled == nil || args.ProjectDocument == nil {
|
|
return "", errors.New("render_document: controlled and projectDocument must be explicit")
|
|
}
|
|
if *args.Controlled || *args.ProjectDocument {
|
|
return "", docgen.ErrRDMRequired
|
|
}
|
|
if strings.TrimSpace(rc.OwnerID()) == "" {
|
|
return "", errors.New("render_document: trusted requester identity is required")
|
|
}
|
|
mode := render.Mode(args.Mode)
|
|
if mode == "" {
|
|
mode = render.ModePreview
|
|
}
|
|
if mode != render.ModeWorking && mode != render.ModePreview {
|
|
return "", fmt.Errorf("render_document: mode %q is unavailable for an ordinary workspace document", mode)
|
|
}
|
|
documentType := strings.TrimSpace(args.DocumentType)
|
|
if documentType == "" {
|
|
documentType = "general"
|
|
}
|
|
language := strings.TrimSpace(args.Language)
|
|
if language == "" {
|
|
language = "zh-CN"
|
|
}
|
|
host, ok := rc.(documentDeliveryHost)
|
|
if !ok {
|
|
return "", errors.New("render_document: trusted delivery host is unavailable")
|
|
}
|
|
receipt, err := host.ExecuteDocumentDelivery(execParentCtx(rc), docgen.OperationRequest{
|
|
OperationID: args.OperationID, DocumentID: args.DocumentID, Title: args.Name,
|
|
DocumentType: documentType, Language: language, Markdown: []byte(args.Markdown), Mode: mode,
|
|
Controlled: *args.Controlled, ProjectDocument: *args.ProjectDocument,
|
|
})
|
|
encoded, marshalErr := json.Marshal(receipt)
|
|
if marshalErr != nil {
|
|
return "", marshalErr
|
|
}
|
|
if err != nil {
|
|
return "", fmt.Errorf("render_document: %s", encoded)
|
|
}
|
|
return string(encoded), nil
|
|
}
|