feat(ingestion): implement brain_ingest MCP tool

Wraps pipeline.Run with the existing LLM client. Mirrors the HTTP
/ingest and /ingest-path semantics — accepts either path or
content+source, validates mutual exclusion, surfaces an explicit error
when the LLM client is not configured (test-mode).

ctx is threaded through to pipeline.Run for cancellation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mathias Bergqvist
2026-05-01 13:02:02 +02:00
parent 809d435480
commit 8c87460bff
3 changed files with 103 additions and 0 deletions

View File

@@ -127,3 +127,46 @@ func TestBrainIngestRawDryRun(t *testing.T) {
_, err := os.Stat(filepath.Join(brainDir, "wiki", "concepts", "test-concept.md"))
assert.True(t, os.IsNotExist(err))
}
func TestBrainIngestRejectsBoth(t *testing.T) {
brainDir := t.TempDir()
srv := mcp.NewServer(brainDir, nil, nil)
resp := toolCall(t, srv, "brain_ingest", map[string]any{
"content": "x",
"source": "y",
"path": "/tmp/foo.md",
})
require.NotNil(t, resp["error"])
}
func TestBrainIngestRequiresOne(t *testing.T) {
brainDir := t.TempDir()
srv := mcp.NewServer(brainDir, nil, nil)
resp := toolCall(t, srv, "brain_ingest", map[string]any{})
require.NotNil(t, resp["error"])
}
func TestBrainIngestRejectsContentWithoutSource(t *testing.T) {
brainDir := t.TempDir()
srv := mcp.NewServer(brainDir, nil, nil)
resp := toolCall(t, srv, "brain_ingest", map[string]any{
"content": "x",
})
require.NotNil(t, resp["error"])
}
func TestBrainIngestRequiresLLMConfigured(t *testing.T) {
brainDir := t.TempDir()
srv := mcp.NewServer(brainDir, nil, nil) // nil pipelineCfg → no LLM
resp := toolCall(t, srv, "brain_ingest", map[string]any{
"content": "some content",
"source": "test",
})
require.NotNil(t, resp["error"])
errObj := resp["error"].(map[string]any)
assert.Contains(t, errObj["message"].(string), "LLM not configured")
}