toolsrv/agent: rename ClassifyTool→CanParallelize, ClassifyTier→MemoryTier

Rename throughout: Go methods, interface types, Runtime fields, wire
protocol RPCs, tests, and ollie-remote.

- IsParallelRead / ParallelClassifier → CanParallelize
- ResultTier / ResultTierArgs / TierClassifier → MemoryTier / MemoryTierArgs / MemoryTierClassifier
- Wire: is_parallel_read → can_parallelize, result_tier → memory_tier, result_tier_args → memory_tier_args
This commit is contained in:
Ollie Agent 2026-08-08 14:29:41 +02:00
parent 6e7b6e5f96
commit 38b35f1ba5
9 changed files with 56 additions and 56 deletions

View File

@ -69,7 +69,7 @@ func BuildRuntime(cfg *AgentConfig, srv toolsrv.Runner, cwd string, env []string
var classify toolClassifier
if pc, ok := srv.(toolsrv.ParallelClassifier); ok {
classify = pc.IsParallelRead
classify = pc.CanParallelize
}
// Capture output formats from the same tool listing used to build the
@ -87,9 +87,9 @@ func BuildRuntime(cfg *AgentConfig, srv toolsrv.Runner, cwd string, env []string
}
var tierFn func(string, json.RawMessage) ResultTier
if tc, ok := srv.(toolsrv.TierClassifier); ok {
if tc, ok := srv.(toolsrv.MemoryTierClassifier); ok {
tierFn = func(name string, args json.RawMessage) ResultTier {
switch tc.ResultTierArgs(name, args) {
switch tc.MemoryTierArgs(name, args) {
case "cold":
return TierCold
case "warm":
@ -125,9 +125,9 @@ func BuildRuntime(cfg *AgentConfig, srv toolsrv.Runner, cwd string, env []string
ToolServer: srv,
Tools: allTools,
Exec: exec,
ClassifyTool: classify,
CanParallelize: classify,
OutputFormat: outputFormat,
ClassifyTier: tierFn,
MemoryTier: tierFn,
ResetsCounter: resetsCounterFn,
Preamble: preamble,
GenParams: genParams,

View File

@ -317,7 +317,7 @@ func run(rt *Runtime, ctx TurnCtx, state state) error {
return cr, true
}
emit(ctx, Event{Role: "call", Name: call.Name, Content: string(call.Arguments)})
readSafe := rt.ClassifyTool != nil && rt.ClassifyTool(call.Name)
readSafe := rt.CanParallelize != nil && rt.CanParallelize(call.Name)
if readSafe {
key := call.Name + "\x00" + string(call.Arguments)
if v, ok := resultCache.Load(key); ok {
@ -420,14 +420,14 @@ func run(rt *Runtime, ctx TurnCtx, state state) error {
emit(ctx, Event{Role: "tool", Name: call.Name, OutputFormat: toolOutputFormat(rt, call.Name)})
}
tier := TierHot
if !isErr && rt.ClassifyTier != nil {
tier = rt.ClassifyTier(call.Name, call.Arguments)
if !isErr && rt.MemoryTier != nil {
tier = rt.MemoryTier(call.Name, call.Arguments)
}
return toolResult{ToolCallID: call.ID, Name: call.Name, Content: result, ContentBlocks: resultBlocks, IsError: isErr, Tier: tier}, false
}
isParallelSafe := func(name string) bool {
return name != "" && rt.ClassifyTool != nil && rt.ClassifyTool(name)
return name != "" && rt.CanParallelize != nil && rt.CanParallelize(name)
}
for i := 0; i < len(toolCalls) && !interrupted; {

View File

@ -17,9 +17,9 @@ type Runtime struct {
Preamble string // compiled system prompt
Tools []backend.Tool
Exec toolExecutor
ClassifyTool toolClassifier
CanParallelize toolClassifier
OutputFormat func(string) string
ClassifyTier func(string, json.RawMessage) ResultTier
MemoryTier func(string, json.RawMessage) ResultTier
ResetsCounter func(string) bool // true if tool resets step counter
GenParams backend.GenerationParams
MaxSteps int

View File

@ -334,7 +334,7 @@ func handleRPC(ctx context.Context, srv *toolsrv.Server, req rpcRequest, enc *lo
ok := srv.DismissDetached(params.PID)
enc.Encode(rpcResponse{JSONRPC: "2.0", ID: req.ID, Result: ok})
case "is_parallel_read":
case "can_parallelize":
var params struct {
Name string `json:"name"`
}
@ -342,10 +342,10 @@ func handleRPC(ctx context.Context, srv *toolsrv.Server, req rpcRequest, enc *lo
enc.Encode(rpcResponse{JSONRPC: "2.0", ID: req.ID, Error: &rpcError{Code: -32602, Message: err.Error()}})
return
}
ok := srv.IsParallelRead(params.Name)
ok := srv.CanParallelize(params.Name)
enc.Encode(rpcResponse{JSONRPC: "2.0", ID: req.ID, Result: ok})
case "result_tier":
case "memory_tier":
var params struct {
Name string `json:"name"`
}
@ -353,10 +353,10 @@ func handleRPC(ctx context.Context, srv *toolsrv.Server, req rpcRequest, enc *lo
enc.Encode(rpcResponse{JSONRPC: "2.0", ID: req.ID, Error: &rpcError{Code: -32602, Message: err.Error()}})
return
}
tier := srv.ResultTier(params.Name)
tier := srv.MemoryTier(params.Name)
enc.Encode(rpcResponse{JSONRPC: "2.0", ID: req.ID, Result: tier})
case "result_tier_args":
case "memory_tier_args":
var params struct {
Name string `json:"name"`
Args json.RawMessage `json:"args"`
@ -365,7 +365,7 @@ func handleRPC(ctx context.Context, srv *toolsrv.Server, req rpcRequest, enc *lo
enc.Encode(rpcResponse{JSONRPC: "2.0", ID: req.ID, Error: &rpcError{Code: -32602, Message: err.Error()}})
return
}
tier := srv.ResultTierArgs(params.Name, params.Args)
tier := srv.MemoryTierArgs(params.Name, params.Args)
enc.Encode(rpcResponse{JSONRPC: "2.0", ID: req.ID, Result: tier})
case "tool_load":

View File

@ -151,10 +151,10 @@ func (c *Conn) DismissDetached(pid int) bool {
return ok
}
// IsParallelRead implements ParallelClassifier.
func (c *Conn) IsParallelRead(name string) bool {
// CanParallelize implements ParallelClassifier.
func (c *Conn) CanParallelize(name string) bool {
params, _ := json.Marshal(map[string]string{"name": name})
resp, err := c.call("is_parallel_read", params)
resp, err := c.call("can_parallelize", params)
if err != nil {
return false
}
@ -163,10 +163,10 @@ func (c *Conn) IsParallelRead(name string) bool {
return ok
}
// ResultTier implements TierClassifier.
func (c *Conn) ResultTier(name string) string {
// MemoryTier implements MemoryTierClassifier.
func (c *Conn) MemoryTier(name string) string {
params, _ := json.Marshal(map[string]string{"name": name})
resp, err := c.call("result_tier", params)
resp, err := c.call("memory_tier", params)
if err != nil {
return "hot"
}
@ -175,10 +175,10 @@ func (c *Conn) ResultTier(name string) string {
return tier
}
// ResultTierArgs implements TierClassifier.
func (c *Conn) ResultTierArgs(name string, args json.RawMessage) string {
// MemoryTierArgs implements MemoryTierClassifier.
func (c *Conn) MemoryTierArgs(name string, args json.RawMessage) string {
params, _ := json.Marshal(map[string]any{"name": name, "args": args})
resp, err := c.call("result_tier_args", params)
resp, err := c.call("memory_tier_args", params)
if err != nil {
return "hot"
}

View File

@ -130,29 +130,29 @@ func (ts *testServer) handleRPC(ctx context.Context, req rpcRequest) rpcResponse
ts.srv.SetAllowTools(params.Names)
return rpcResponse{JSONRPC: "2.0", ID: req.ID, Result: json.RawMessage(`true`)}
case "is_parallel_read":
case "can_parallelize":
var params struct {
Name string `json:"name"`
}
if err := json.Unmarshal(req.Params, &params); err != nil {
return rpcResponse{JSONRPC: "2.0", ID: req.ID, Error: &rpcError{Code: -32602, Message: err.Error()}}
}
ok := ts.srv.IsParallelRead(params.Name)
ok := ts.srv.CanParallelize(params.Name)
result, _ := json.Marshal(ok)
return rpcResponse{JSONRPC: "2.0", ID: req.ID, Result: result}
case "result_tier":
case "memory_tier":
var params struct {
Name string `json:"name"`
}
if err := json.Unmarshal(req.Params, &params); err != nil {
return rpcResponse{JSONRPC: "2.0", ID: req.ID, Error: &rpcError{Code: -32602, Message: err.Error()}}
}
tier := ts.srv.ResultTier(params.Name)
tier := ts.srv.MemoryTier(params.Name)
result, _ := json.Marshal(tier)
return rpcResponse{JSONRPC: "2.0", ID: req.ID, Result: result}
case "result_tier_args":
case "memory_tier_args":
var params struct {
Name string `json:"name"`
Args json.RawMessage `json:"args"`
@ -160,7 +160,7 @@ func (ts *testServer) handleRPC(ctx context.Context, req rpcRequest) rpcResponse
if err := json.Unmarshal(req.Params, &params); err != nil {
return rpcResponse{JSONRPC: "2.0", ID: req.ID, Error: &rpcError{Code: -32602, Message: err.Error()}}
}
tier := ts.srv.ResultTierArgs(params.Name, params.Args)
tier := ts.srv.MemoryTierArgs(params.Name, params.Args)
result, _ := json.Marshal(tier)
return rpcResponse{JSONRPC: "2.0", ID: req.ID, Result: result}
@ -449,13 +449,13 @@ func TestRPC_SetAllowTools(t *testing.T) {
}
}
func TestRPC_IsParallelRead(t *testing.T) {
func TestRPC_CanParallelize(t *testing.T) {
ts := newTestServer(t)
defer ts.srv.Close()
ctx := context.Background()
params, _ := json.Marshal(map[string]string{"name": "unknown_tool"})
req := rpcRequest{JSONRPC: "2.0", ID: 1, Method: "is_parallel_read", Params: params}
req := rpcRequest{JSONRPC: "2.0", ID: 1, Method: "can_parallelize", Params: params}
resp := ts.handleRPC(ctx, req)
if resp.Error != nil {
@ -472,13 +472,13 @@ func TestRPC_IsParallelRead(t *testing.T) {
}
}
func TestRPC_ResultTier(t *testing.T) {
func TestRPC_MemoryTier(t *testing.T) {
ts := newTestServer(t)
defer ts.srv.Close()
ctx := context.Background()
params, _ := json.Marshal(map[string]string{"name": "unknown_tool"})
req := rpcRequest{JSONRPC: "2.0", ID: 1, Method: "result_tier", Params: params}
req := rpcRequest{JSONRPC: "2.0", ID: 1, Method: "memory_tier", Params: params}
resp := ts.handleRPC(ctx, req)
if resp.Error != nil {
@ -495,7 +495,7 @@ func TestRPC_ResultTier(t *testing.T) {
}
}
func TestRPC_ResultTierArgs(t *testing.T) {
func TestRPC_MemoryTierArgs(t *testing.T) {
ts := newTestServer(t)
defer ts.srv.Close()
@ -504,7 +504,7 @@ func TestRPC_ResultTierArgs(t *testing.T) {
"name": "some_tool",
"args": json.RawMessage(`{"foo": "bar"}`),
})
req := rpcRequest{JSONRPC: "2.0", ID: 1, Method: "result_tier_args", Params: params}
req := rpcRequest{JSONRPC: "2.0", ID: 1, Method: "memory_tier_args", Params: params}
resp := ts.handleRPC(ctx, req)
if resp.Error != nil {
@ -701,12 +701,12 @@ func TestRPC_PipeConnection(t *testing.T) {
conn.SetCWD("/tmp/test")
// Test is_parallel_read
if conn.IsParallelRead("unknown") {
t.Error("expected IsParallelRead=false for unknown tool")
if conn.CanParallelize("unknown") {
t.Error("expected CanParallelize=false for unknown tool")
}
// Test result_tier
tier := conn.ResultTier("unknown")
tier := conn.MemoryTier("unknown")
if tier != "hot" {
t.Errorf("expected tier='hot', got %q", tier)
}

View File

@ -4,9 +4,9 @@ import (
"encoding/json"
)
// ResultTier implements TierClassifier. Looks up the tool's tier
// MemoryTier implements MemoryTierClassifier. Looks up the tool's tier
// from the registry, then from its .meta file.
func (e *Server) ResultTier(name string) string {
func (e *Server) MemoryTier(name string) string {
if e.toolRegistry != nil && e.sessionID != "" {
if info, ok := e.toolRegistry.Lookup(e.sessionID, name); ok && info.Tier != "" {
return info.Tier
@ -36,21 +36,21 @@ func (e *Server) OutputFormat(name string) string {
return ""
}
// ResultTierArgs classifies the tier using both the outer tool name and its
// MemoryTierArgs classifies the tier using both the outer tool name and its
// arguments. For shell, it returns warm. For promoted tools, it
// delegates to ResultTier.
func (e *Server) ResultTierArgs(name string, args json.RawMessage) string {
// delegates to MemoryTier.
func (e *Server) MemoryTierArgs(name string, args json.RawMessage) string {
switch name {
case "shell":
return "warm"
default:
return e.ResultTier(name)
return e.MemoryTier(name)
}
}
// IsParallelRead implements ParallelClassifier. Returns true when the
// CanParallelize implements ParallelClassifier. Returns true when the
// named tool is marked readOnly in its .meta file.
func (e *Server) IsParallelRead(name string) bool {
func (e *Server) CanParallelize(name string) bool {
if e.toolRegistry != nil && e.sessionID != "" {
if info, ok := e.toolRegistry.Lookup(e.sessionID, name); ok {
return info.ReadOnly

View File

@ -41,17 +41,17 @@ type Runner interface {
// named tool is safe to run concurrently with other read-class tools.
// Returns false for unknown tools (conservative default).
type ParallelClassifier interface {
IsParallelRead(name string) bool
CanParallelize(name string) bool
}
// TierClassifier is implemented by tool servers that can report the retention
// MemoryTierClassifier is implemented by tool servers that can report the retention
// tier of a tool's results: "hot" (verbatim), "warm" (summarized on compaction),
// or "cold" (immediately summarized). Returns "hot" for unknown tools.
type TierClassifier interface {
ResultTier(name string) string
// ResultTierArgs classifies the tier using both the outer tool name and its
type MemoryTierClassifier interface {
MemoryTier(name string) string
// MemoryTierArgs classifies the tier using both the outer tool name and its
// arguments.
ResultTierArgs(name string, args json.RawMessage) string
MemoryTierArgs(name string, args json.RawMessage) string
}
// OutputFormatClassifier reports the source-fence language for tool output.