codemode

package
v1.12.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 27, 2026 License: MPL-2.0 Imports: 16 Imported by: 2

README

CodeMode UTCP — Expr runtime

CodeMode UTCP lets an LLM compose multiple UTCP tools into a single executable workflow. CodeMode now uses Expr instead of Yaegi.

Why Expr

Expr is a Go-centric expression language with static checking, a bytecode VM, bounded expression execution, and a small execution surface. CodeMode exposes only the codemode API to generated expressions, so generated code cannot import packages or access arbitrary Go APIs.

How it works

  1. The orchestrator ranks candidate UTCP tools.
  2. The LLM receives an exact closed-world tool list and schemas.
  3. The LLM generates Expr source.
  4. CodeMode compiles the expression with Expr.
  5. The expression calls only the exposed UTCP helpers.
  6. The final Expr value becomes the CodeMode result.

Expr syntax

Generated code is Expr, not Go. Use sequential expressions and let bindings:

let r1 = codemode.CallTool("math.add", {"a": 5, "b": 7});
let sum = codemode.Get(r1, "result");
let r2 = codemode.CallTool("math.multiply", {"value": sum, "factor": 3});
r2

The last expression is returned. There is no __out, :=, package declaration, import, type assertion, or Go loop.

Runtime API

codemode.CallTool
codemode.CallTool("provider.tool", {"field": value})

Calls one UTCP tool. Tool errors propagate as Expr runtime errors.

codemode.CallToolStream
codemode.CallToolStream("provider.stream", {"input": "hello"})

Calls a streaming UTCP tool and returns the collected chunks as an array. This keeps streaming workflows compatible with Expr's expression-oriented execution model.

codemode.Get
codemode.Get(toolResult, "result")

Extracts a field from a map[string]any tool result and returns nil when the value is not a map or the key is absent.

Chaining

Tool output can be passed directly into the next tool:

let first = codemode.CallTool("calculator.add", {"a": 2, "b": 3});
let value = codemode.Get(first, "result");
codemode.CallTool("calculator.multiply", {"value": value, "factor": 10})

This gives CodeMode a compact sequential workflow without repeatedly returning control to the LLM.

Streaming

The orchestrator marks a generated plan as streaming when the expression contains codemode.CallToolStream(...):

{
  "tools": ["api.stream"],
  "code": "codemode.CallToolStream(\"api.stream\", {\"input\": \"hello\"})",
  "stream": true
}

Safety boundary

The Expr environment exposes only the codemode object. The runtime does not expose Go imports, filesystem APIs, arbitrary reflection, or Yaegi's standard library loader. UTCP remains the authority for actual tool dispatch.

Generated tool names are checked against the exact candidate whitelist before execution.

Timeout

CodeModeArgs.Timeout is expressed in milliseconds. The default direct-execution timeout is 30 seconds; the tool handler uses 3 seconds when no timeout is supplied. Remote tool calls receive the same cancellable context.

Expr itself does not support arbitrary infinite loops, which removes the primary reason the old Yaegi execution path needed to guard generated loops.

API

func NewCodeModeUTCP(
    client utcp.UtcpClientInterface,
    model interface {
        Generate(ctx context.Context, prompt string) (any, error)
    },
) *CodeModeUTCP

func (cm *CodeModeUTCP) CallTool(
    ctx context.Context,
    prompt string,
) (bool, any, error)

func (cm *CodeModeUTCP) Execute(
    ctx context.Context,
    args CodeModeArgs,
) (CodeModeResult, error)

Environment

  • utcp_search_tools_limit — maximum number of tools loaded into the CodeMode catalog; defaults to 50.
  • UTCP_CODEMODE_CANDIDATE_LIMIT — maximum candidate tools sent to the planner; defaults to 16.

Migration from Yaegi

The old Go-like CodeMode syntax is intentionally no longer the execution contract. Migrate generated programs to Expr using:

  • let x = ... instead of Go variable declarations
  • {} maps instead of map[string]any{}
  • ;-separated expressions instead of Go statements
  • codemode.Get(...) instead of Go type assertions for common map results
  • the final expression instead of __out
  • codemode.CallToolStream(...) returning collected chunks instead of manual Next() loops

Tests

The CodeMode test suite covers arithmetic and sequential expressions, synchronous tool calls, tool chaining, streaming, tool errors, timeout behavior, and exact tool-name extraction.

Documentation

Index

Constants

View Source
const CodeModeToolName = "codemode.run_code"

Variables

This section is empty.

Functions

This section is empty.

Types

type CacheStats added in v1.10.6

type CacheStats struct {
	SpecsHits       int64
	SpecsMisses     int64
	SelectionHits   int64
	SelectionMisses int64
	SelectionSize   int
}

CacheStats holds cache performance metrics

func (CacheStats) SelectionHitRate added in v1.10.6

func (cs CacheStats) SelectionHitRate() float64

SelectionHitRate returns the cache hit rate for tool selections

func (CacheStats) SpecsHitRate added in v1.10.6

func (cs CacheStats) SpecsHitRate() float64

HitRate returns the cache hit rate for tool specs

type CodeModeArgs

type CodeModeArgs struct {
	Code    string `json:"code"`
	Timeout int    `json:"timeout"`
}

type CodeModeResult

type CodeModeResult struct {
	Value  any    `json:"value"`
	Stdout string `json:"stdout"`
	Stderr string `json:"stderr"`
}

type CodeModeUTCP

type CodeModeUTCP struct {
	// contains filtered or unexported fields
}

func NewCodeModeUTCP

func NewCodeModeUTCP(client utcp.UtcpClientInterface, model interface {
	Generate(ctx context.Context, prompt string) (any, error)
}) *CodeModeUTCP

func (*CodeModeUTCP) CacheStats added in v1.10.6

func (cm *CodeModeUTCP) CacheStats() CacheStats

func (*CodeModeUTCP) CallTool added in v1.10.0

func (cm *CodeModeUTCP) CallTool(ctx context.Context, prompt string) (bool, any, error)

func (*CodeModeUTCP) Execute

func (c *CodeModeUTCP) Execute(ctx context.Context, args CodeModeArgs) (CodeModeResult, error)

func (*CodeModeUTCP) InvalidateAllCaches added in v1.10.6

func (cm *CodeModeUTCP) InvalidateAllCaches()

func (*CodeModeUTCP) InvalidateSelectionsCache added in v1.10.6

func (cm *CodeModeUTCP) InvalidateSelectionsCache()

func (*CodeModeUTCP) InvalidateToolSpecsCache added in v1.10.6

func (cm *CodeModeUTCP) InvalidateToolSpecsCache()

func (*CodeModeUTCP) StartCacheCleanup added in v1.10.6

func (cm *CodeModeUTCP) StartCacheCleanup(ctx context.Context, interval time.Duration)

func (*CodeModeUTCP) ToolSpecs added in v1.10.0

func (a *CodeModeUTCP) ToolSpecs() []tools.Tool

func (*CodeModeUTCP) Tools

func (c *CodeModeUTCP) Tools() ([]tools.Tool, error)

type ToolCache added in v1.10.6

type ToolCache struct {
	// contains filtered or unexported fields
}

ToolCache provides thread-safe caching for tool specs and selection results

func NewToolCache added in v1.10.6

func NewToolCache() *ToolCache

NewToolCache creates a new tool cache with configurable TTLs

func (*ToolCache) CleanExpired added in v1.10.6

func (tc *ToolCache) CleanExpired()

CleanExpired removes expired entries from selection cache

func (*ToolCache) GetSelectedTools added in v1.10.6

func (tc *ToolCache) GetSelectedTools(query string, availableTools string) []string

GetSelectedTools retrieves cached tool selection for a query

func (*ToolCache) GetToolSpecs added in v1.10.6

func (tc *ToolCache) GetToolSpecs() []tools.Tool

GetToolSpecs retrieves cached tool specs or returns nil if expired/missing

func (*ToolCache) GetToolSpecsAndCatalog added in v1.11.3

func (tc *ToolCache) GetToolSpecsAndCatalog() ([]tools.Tool, string)

GetToolSpecsAndCatalog returns cached tool specs and their compact prompt catalog. Both values share a TTL so callers never use a stale catalog.

func (*ToolCache) InvalidateAll added in v1.10.6

func (tc *ToolCache) InvalidateAll()

InvalidateAll clears all caches

func (*ToolCache) InvalidateSelections added in v1.10.6

func (tc *ToolCache) InvalidateSelections()

InvalidateSelections clears all tool selection cache entries

func (*ToolCache) InvalidateToolSpecs added in v1.10.6

func (tc *ToolCache) InvalidateToolSpecs()

InvalidateToolSpecs clears the tool specs cache

func (*ToolCache) SetSelectedTools added in v1.10.6

func (tc *ToolCache) SetSelectedTools(query string, availableTools string, selectedTools []string)

SetSelectedTools stores tool selection result in cache

func (*ToolCache) SetToolCatalog added in v1.11.3

func (tc *ToolCache) SetToolCatalog(catalog string)

SetToolCatalog attaches a catalog to the current cached spec snapshot.

func (*ToolCache) SetToolSpecs added in v1.10.6

func (tc *ToolCache) SetToolSpecs(specs []tools.Tool)

SetToolSpecs stores tool specs in cache

func (*ToolCache) SetToolSpecsAndCatalog added in v1.11.3

func (tc *ToolCache) SetToolSpecsAndCatalog(specs []tools.Tool, catalog string)

SetToolSpecsAndCatalog stores a spec snapshot and the catalog derived from it atomically, avoiding repeated rendering on the orchestration hot path.

func (*ToolCache) StartCleanupRoutine added in v1.10.6

func (tc *ToolCache) StartCleanupRoutine(ctx context.Context, interval time.Duration)

StartCleanupRoutine starts a background goroutine to periodically clean expired entries

func (*ToolCache) Stats added in v1.10.6

func (tc *ToolCache) Stats() CacheStats

Stats returns cache performance statistics

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL