fix(brain): enforce mutual exclusivity and clarify brain_ingest schema

- Return error when both path and content are supplied simultaneously
- Improve tool description to clearly state the two valid call forms
- Add per-field descriptions so LLMs understand what each parameter requires

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Mathias Bergqvist
2026-04-22 23:03:03 +02:00
parent a6dce972d6
commit 2ae6bfe81e
2 changed files with 12 additions and 5 deletions

View File

@@ -78,6 +78,9 @@ func (s *Skill) ingest(ctx context.Context, args json.RawMessage) (json.RawMessa
if s.cfg.IngestSvcURL == "" {
return nil, fmt.Errorf("brain_ingest: INGEST_SVC_URL not configured")
}
if a.Path != "" && a.Content != "" {
return nil, fmt.Errorf("path and content+source are mutually exclusive: provide one or the other")
}
if a.Path != "" {
return s.postTo(ctx, s.cfg.IngestSvcURL+"/ingest-path", map[string]any{
"path": a.Path,

View File

@@ -57,11 +57,15 @@ func (s *Skill) Tools() []registry.ToolDef {
if s.cfg.IngestSvcURL != "" {
tools = append(tools, registry.ToolDef{
Name: "brain_ingest",
Description: "Ingest text content into the brain wiki (brain/wiki/). Calls an LLM to produce structured wiki pages. Use for substantial documents, articles, or knowledge worth structuring. Returns the list of wiki pages written.",
Description: "Ingest content into the brain wiki (brain/wiki/). Calls an LLM to produce structured wiki pages. " +
"Use for substantial documents, articles, or knowledge worth structuring. " +
"Provide EITHER (a) path — absolute path to a file or directory, " +
"OR (b) content + source — raw text and a human-readable name. " +
"Providing both is an error. Returns the list of wiki pages written.",
InputSchema: schema([]string{}, map[string]any{
"content": str,
"source": map[string]any{"type": "string", "description": "human-readable name for the content, e.g. 'article-on-raft.md'"},
"path": map[string]any{"type": "string", "description": "absolute path to a file or directory to ingest; if set, content and source are not needed"},
"content": map[string]any{"type": "string", "description": "raw text to ingest; required when path is not set"},
"source": map[string]any{"type": "string", "description": "human-readable name for the content, e.g. 'shape-up-book'; required when path is not set"},
"path": map[string]any{"type": "string", "description": "absolute path to a file or directory to ingest; mutually exclusive with content+source"},
"dry_run": map[string]any{"type": "boolean"},
}),
})