appx

package
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Oct 14, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package appx declares the agent-capability seam every reasoner and phase of a carried program depends on: sec's first, which it was written for. The original Python code received the SDK `Agent` (or the `AgentRouter` proxying to it) and called `.harness(...)`, `.ai(...)`, `.note(...)` and `.call(...)` on it; the Go code receives an App.

Inside codeaf there is no control plane and no external coding-agent CLI, so the seam no longer names any SDK agent type. The harness options and result are declared here, carrying only the fields the program actually sets and reads, and the codeaf side supplies the implementation: Harness runs codeaf's own agent loop, AI goes through codeaf's model API, and Call is answered in process by the reasoner registry (internal/secaf/audit).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AIJSON

func AIJSON(pick func(prompt string) (json.RawMessage, error)) func(context.Context, string, ...ai.Option) (*ai.Response, error)

AIJSON builds an AIFn that answers every invocation with a response whose text content is the JSON produced by pick(prompt).

func HarnessJSON

func HarnessJSON(pick func(prompt string, opts HarnessOptions) (json.RawMessage, error)) func(context.Context, string, map[string]any, any, HarnessOptions) (*HarnessResult, error)

HarnessJSON builds a HarnessFn that answers every invocation by unmarshaling the JSON produced by pick(prompt) into dest and returning a successful Result whose Parsed is dest — exactly what the SDK runner does on a schema-valid run. pick returning an error yields a Result with IsError set and that message (the SDK's failure shape), NOT a transport error.

Types

type AICall

type AICall struct {
	Prompt string
	Opts   []ai.Option
}

AICall is one recorded AI invocation (the option list is opaque; tests that need the system prompt/schema should apply the options to an ai.Request).

type AIer

type AIer interface {
	AI(ctx context.Context, prompt string, opts ...ai.Option) (*ai.Response, error)
}

AIer is the `app.ai(...)` seam. The option list and the response keep the SDK `ai` package's shapes, which codeaf already speaks everywhere it talks to a model.

type App

type App interface {
	Harnesser
	AIer
	Noter
	Caller
}

App is the union the reasoners, phases and orchestrator are written against.

type CallCall

type CallCall struct {
	Target string
	Input  map[string]any
}

CallCall is one recorded Call invocation.

type Caller

type Caller interface {
	Call(ctx context.Context, target string, input map[string]any) (map[string]any, error)
}

Caller is the `app.call(f"{NODE_ID}.x", **kwargs)` seam — the reasoner invocation that used to travel through the control plane as a tracked child execution. It returns the target reasoner's result map, already decoded the way a JSON hop decodes it, and an error on any failure.

type Fake

type Fake struct {

	// HarnessFn answers Harness. To mimic a successful structured run, marshal
	// the canned value into dest and return &HarnessResult{Parsed: dest}.
	// Use HarnessJSON for the common case.
	HarnessFn func(ctx context.Context, prompt string, schema map[string]any, dest any, opts HarnessOptions) (*HarnessResult, error)
	// AIFn answers AI. Use AIJSON for the common "return this JSON" case.
	AIFn func(ctx context.Context, prompt string, opts ...ai.Option) (*ai.Response, error)
	// CallFn answers Call.
	CallFn func(ctx context.Context, target string, input map[string]any) (map[string]any, error)

	// Recorded invocations, in call order.
	Harnesses []HarnessCall
	AIs       []AICall
	Notes     []NoteCall
	Calls     []CallCall
	// contains filtered or unexported fields
}

Fake is a scripted, recording App for tests. Every seam is a plain function field; unset seams fail loudly (Harness/AI/Call return an error, Note is recorded). Fake also tracks the maximum number of concurrently in-flight Harness and Call invocations so phase tests can assert the semaphore bounds the Python code enforces (asyncio.Semaphore(n)).

Fake is safe for concurrent use; all recorded slices are guarded by mu.

func (*Fake) AI

func (f *Fake) AI(ctx context.Context, prompt string, opts ...ai.Option) (*ai.Response, error)

AI implements AIer.

func (*Fake) Call

func (f *Fake) Call(ctx context.Context, target string, input map[string]any) (map[string]any, error)

Call implements Caller.

func (*Fake) CallTargets

func (f *Fake) CallTargets() []string

CallTargets returns the recorded Call targets in order.

func (*Fake) Harness

func (f *Fake) Harness(ctx context.Context, prompt string, schema map[string]any, dest any, opts HarnessOptions) (*HarnessResult, error)

Harness implements Harnesser.

func (*Fake) MaxConcurrentCalls

func (f *Fake) MaxConcurrentCalls() int

MaxConcurrentCalls returns the peak number of simultaneously in-flight Call invocations observed so far.

func (*Fake) MaxConcurrentHarness

func (f *Fake) MaxConcurrentHarness() int

MaxConcurrentHarness returns the peak number of simultaneously in-flight Harness invocations observed so far.

func (*Fake) Note

func (f *Fake) Note(ctx context.Context, message string, tags ...string)

Note implements Noter.

func (*Fake) NoteMessages

func (f *Fake) NoteMessages() []string

NoteMessages returns the recorded Note messages in order.

type HarnessCall

type HarnessCall struct {
	Prompt string
	Schema map[string]any
	Opts   HarnessOptions
}

HarnessCall is one recorded Harness invocation.

type HarnessOptions

type HarnessOptions struct {
	Cwd        string
	ProjectDir string
	// Label is the agent the run is for, in the words its errors already use
	// ("Hunt location scanner", "DataFlowTracer"). It changes nothing about
	// the run; codeaf names the session by it on the program's page.
	Label string
}

HarnessOptions is what one harness run is told about where it works.

Cwd is the directory the agent runs in — for most agents a scratch directory the agent writes its structured output into — and ProjectDir is the repository the run reads, which the agent reads. Those two are the only options any agent in the program sets: the model, turn budget and provider were process-wide configuration of the external CLI this seam used to drive, and are now whatever the codeaf implementation of Harness decides.

type HarnessResult

type HarnessResult struct {
	Result       string
	Parsed       any
	IsError      bool
	ErrorMessage string
	NumTurns     int
	DurationMS   int64
	CostUSD      *float64
}

HarnessResult is the outcome of one harness run, mirroring the fields a program reads off it.

A run that HAPPENED and failed is reported with IsError and ErrorMessage and a nil Go error; a Go error from Harness means the run could not be made at all. The callers treat the two differently (harnessx.Extract, the gate retry loop), so an implementation must keep that split.

Parsed is the dest pointer the caller handed to Harness once it holds a schema-valid object, and nil when the run produced nothing that validated; the callers then fall back to parsing Result, the agent's raw final text.

CostUSD is a pointer because "no cost reported" is not "free": the cost trackers skip a nil and add a reported zero, so an implementation that cannot price a run leaves it nil rather than writing 0.

type Harnesser

type Harnesser interface {
	Harness(ctx context.Context, prompt string, schema map[string]any, dest any, opts HarnessOptions) (*HarnessResult, error)
}

Harnesser is the `app.harness(...)` seam.

schema is the JSON schema of the object the run must produce (nil for a free-text run), and dest is a pointer the implementation decodes that object into before returning it as HarnessResult.Parsed.

type NoteCall

type NoteCall struct {
	Message string
	Tags    []string
}

NoteCall is one recorded Note invocation.

type Noter

type Noter interface {
	Note(ctx context.Context, message string, tags ...string)
}

Noter is the `app.note(msg, tags=[...])` seam: a progress line for whoever is watching the program, never something the algorithm reads back.

Jump to

Keyboard shortcuts

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