chore(mcp): clarify inline text limit and cover artifact edge cases
This commit is contained in:
parent
cefec159ad
commit
728b7ad325
5 changed files with 33 additions and 7 deletions
|
|
@ -533,4 +533,4 @@ For example:
|
|||
Note: Nested map-style config (for example `tools.mcp.servers.<name>.*`) is configured in `config.json` rather than
|
||||
environment variables.
|
||||
|
||||
For MCP tools, `tools.mcp.max_inline_text_chars` controls how much text result is kept inline in model context. Above this threshold, PicoClaw saves the MCP text result as a local artifact in the agent workspace and gives the model a short note plus a structured `[file:...]` artifact path instead of injecting the full payload into context.
|
||||
For MCP tools, `tools.mcp.max_inline_text_chars` controls how much text result is kept inline in model context. The threshold is counted in Unicode characters (Go runes), not bytes. For example, `16384` means up to 16,384 characters inline, which may occupy more than 16 KB for multibyte text such as CJK. Above this threshold, PicoClaw saves the MCP text result as a local artifact in the agent workspace and gives the model a short note plus a structured `[file:...]` artifact path instead of injecting the full payload into context.
|
||||
|
|
|
|||
|
|
@ -943,8 +943,8 @@ type MCPServerConfig struct {
|
|||
type MCPConfig struct {
|
||||
ToolConfig ` envPrefix:"PICOCLAW_TOOLS_MCP_"`
|
||||
Discovery ToolDiscoveryConfig ` json:"discovery"`
|
||||
// Max controls how much MCP text stays inline before it is saved as an artifact.
|
||||
Max int `json:"max_inline_text_chars,omitempty" env:"PICOCLAW_TOOLS_MCP_MAX_INLINE_TEXT_CHARS"`
|
||||
// MaxInlineTextChars controls how much MCP text stays inline before it is saved as an artifact.
|
||||
MaxInlineTextChars int `json:"max_inline_text_chars,omitempty" env:"PICOCLAW_TOOLS_MCP_MAX_INLINE_TEXT_CHARS"`
|
||||
// Servers is a map of server name to server configuration
|
||||
Servers map[string]MCPServerConfig `json:"servers,omitempty"`
|
||||
}
|
||||
|
|
@ -952,8 +952,8 @@ type MCPConfig struct {
|
|||
const DefaultMCPMaxInlineTextChars = 16 * 1024
|
||||
|
||||
func (c *MCPConfig) GetMaxInlineTextChars() int {
|
||||
if c.Max > 0 {
|
||||
return c.Max
|
||||
if c.MaxInlineTextChars > 0 {
|
||||
return c.MaxInlineTextChars
|
||||
}
|
||||
return DefaultMCPMaxInlineTextChars
|
||||
}
|
||||
|
|
|
|||
|
|
@ -462,8 +462,8 @@ func DefaultConfig() *Config {
|
|||
UseBM25: true,
|
||||
UseRegex: false,
|
||||
},
|
||||
Max: DefaultMCPMaxInlineTextChars,
|
||||
Servers: map[string]MCPServerConfig{},
|
||||
MaxInlineTextChars: DefaultMCPMaxInlineTextChars,
|
||||
Servers: map[string]MCPServerConfig{},
|
||||
},
|
||||
AppendFile: ToolConfig{
|
||||
Enabled: true,
|
||||
|
|
|
|||
|
|
@ -362,6 +362,7 @@ func (t *MCPTool) persistLargeTextArtifact(text string) *ToolResult {
|
|||
if err := os.MkdirAll(dir, 0o700); err != nil {
|
||||
return t.largeTextArtifactFallback(text, err)
|
||||
}
|
||||
// TODO: Add lifecycle cleanup/retention for MCP artifact files.
|
||||
|
||||
pattern := fmt.Sprintf(
|
||||
"%s_%s_*.txt",
|
||||
|
|
|
|||
|
|
@ -783,3 +783,28 @@ func TestMCPTool_Execute_LargeTextArtifactFailureStillOmitsContext(t *testing.T)
|
|||
t.Fatalf("expected no artifact tags on persistence failure, got %+v", result.ArtifactTags)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMCPTool_Execute_WhitespaceWorkspaceDisablesArtifactPersistence(t *testing.T) {
|
||||
largeText := strings.Repeat("This is a large MCP text payload.\n", 800)
|
||||
manager := &MockMCPManager{
|
||||
callToolFunc: func(ctx context.Context, serverName, toolName string, arguments map[string]any) (*mcp.CallToolResult, error) {
|
||||
return &mcp.CallToolResult{
|
||||
Content: []mcp.Content{
|
||||
&mcp.TextContent{Text: largeText},
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
|
||||
mcpTool := NewMCPTool(manager, "test_server", &mcp.Tool{Name: "dump_payload"})
|
||||
mcpTool.SetWorkspace(" \n\t ")
|
||||
|
||||
result := mcpTool.Execute(context.Background(), nil)
|
||||
|
||||
if len(result.ArtifactTags) != 0 {
|
||||
t.Fatalf("expected no artifact tags for whitespace workspace, got %+v", result.ArtifactTags)
|
||||
}
|
||||
if !strings.Contains(result.ForLLM, "This is a large MCP text payload") {
|
||||
t.Fatalf("expected large text to remain inline when workspace is blank, got %q", result.ForLLM)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue