diff --git a/internal/skills/brain/handlers.go b/internal/skills/brain/handlers.go index ae53e42..a79ead9 100644 --- a/internal/skills/brain/handlers.go +++ b/internal/skills/brain/handlers.go @@ -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, diff --git a/internal/skills/brain/skill.go b/internal/skills/brain/skill.go index 6b6da1f..260dc5a 100644 --- a/internal/skills/brain/skill.go +++ b/internal/skills/brain/skill.go @@ -56,12 +56,16 @@ 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.", + Name: "brain_ingest", + 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"}, }), })