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

@ -694,4 +694,4 @@ Consumers subscribe to the `"event"` topic on the bus. The 9P server's session m
<unix-nanoseconds>-<6-hex-chars>
```
Lexicographically sortable by creation time. Unique even within the same nanosecond due to the random suffix.
Lexicographically sortable by creation time. Unique even within the same nanosecond due to the random suffix.

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.