graphresearch

package
v1.0.0-beta.155 Latest Latest
Warning

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

Go to latest
Published: Jul 20, 2026 License: MIT Imports: 28 Imported by: 0

Documentation

Overview

Package graphresearch composes the graph-first research capability defined by ADR-045. It is intentionally separate from the core composition roots: selecting it adds all five stages, research payloads, and the research_graph tool as one coherent capability.

Index

Constants

View Source
const ResearchGraphToolName = "research_graph"

ResearchGraphToolName is the name parents use to invoke the ADR-045 graph-search rule chain. PR 1 of the Phase 1 plan (docs/operations/22-adr045-phase1-plan.md) lands the registry + tool seam; PRs 2-6 land the five components + seven rules.

Variables

This section is empty.

Functions

func LoopsBucket

func LoopsBucket(cfg *config.Config) string

LoopsBucket returns the agentic-tools loop bucket selected for the capability. ValidateConfig proves that agentic-loop and all five stages use this same value before registration reaches the NATS store.

func RegisterComponents

func RegisterComponents(registry *component.Registry) error

RegisterComponents registers all five bounded graph-research stages.

func RegisterPayloads

func RegisterPayloads(registry *payloadregistry.Registry) error

RegisterPayloads registers the complete research message family.

func RegisterTool

func RegisterTool(ctx context.Context, tools *agentictools.ExecutorRegistry, natsClient *natsclient.Client, platform component.PlatformMeta, logger *slog.Logger, bucketName string) error

RegisterTool opens (or creates) the AGENT_LOOPS bucket and wires the research_graph tool. Bucket config matches agentic-loop/component.go initializeKVBuckets (History=10, TTL=24h) so whichever side reaches the bucket-create call first wins the idempotent Create-or-Get without config drift.

Unlike optional core tools, a selected graph-research capability fails boot when its store or result-reading path is unavailable. Advertising only part of the asynchronous chain would strand parent loops.

The tool needs the AGENT_LOOPS handle — both for the research-pipeline LoopEntity write and for the research.requested.<loopID> trigger key R0 watches. Callers must run ValidateConfig before invoking this function.

func Selected

func Selected(cfg *config.Config) bool

Selected reports whether a config requests any part of graph research. A partial selection is still selected so ValidateConfig can reject it.

func ValidateConfig

func ValidateConfig(cfg *config.Config) error

ValidateConfig rejects partially configured graph research before any tool catalog can be served. An entirely absent capability is valid.

Types

type ResearchGraphExecutor

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

ResearchGraphExecutor implements the research_graph tool. It kicks off the ADR-045 chain by writing two KV records to AGENT_LOOPS:

  1. A LoopEntity at key <loopID> with role=research_pipeline so downstream tools (read_loop_result, flow_monitor) can find the operation by its loop ID.

  2. The research_intent payload wrapped in a BaseMessage envelope at key research.request.received.<loopID> — the R0 trigger key.

The tool returns StopLoop=true so the parent's current iteration terminates; the continuation rule (R6 — landed in PR 6) resumes the parent on a subsequent iteration with the search_result payload.

func NewResearchGraphExecutor

func NewResearchGraphExecutor(kv ResearchKVWriter, platform component.PlatformMeta, opts ...ResearchGraphOption) *ResearchGraphExecutor

NewResearchGraphExecutor constructs the executor. kv must be non-nil — without it the tool can't seed the chain. Logger defaults to slog.Default(); clock and ID generator default to time.Now / uuid-based.

func (*ResearchGraphExecutor) Execute

Execute routes the tool call. Any other tool name is a routing bug.

func (*ResearchGraphExecutor) ListTools

func (e *ResearchGraphExecutor) ListTools() []agentic.ToolDefinition

ListTools returns the research_graph tool definition. The schema is strict-mode-compliant (ADR-035): topic is required; hints, budget_tokens, and max_iterations are optional. additionalProperties is closed so providers honouring function.strict reject ad-hoc fields a model might invent.

func (*ResearchGraphExecutor) SetLogger

func (e *ResearchGraphExecutor) SetLogger(logger *slog.Logger)

SetLogger replaces the default logger. nil-safe — a nil argument preserves whatever logger the executor already has.

type ResearchGraphOption

type ResearchGraphOption func(*ResearchGraphExecutor)

ResearchGraphOption configures a ResearchGraphExecutor at construction time.

func WithResearchGraphClock

func WithResearchGraphClock(now func() time.Time) ResearchGraphOption

WithResearchGraphClock overrides the time source the executor stamps onto the LoopEntity. nil-safe — passing nil preserves the existing clock. Used by tests for deterministic timestamps.

func WithResearchGraphIDGenerator

func WithResearchGraphIDGenerator(gen func() string) ResearchGraphOption

WithResearchGraphIDGenerator overrides the loop-ID generator. nil-safe; tests use it for deterministic IDs.

func WithResearchGraphTriplePublisher

func WithResearchGraphTriplePublisher(pub llmwrap.TriplePublisher) ResearchGraphOption

WithResearchGraphTriplePublisher injects the TriplePublisher used to stamp kickoff triples (loop.role, research.request.received, research.request.topic, research.loop.id, research.parent.loop/role, research.request.budget_tokens, research.request.max_iterations) on the research-pipeline loop entity. R0 of the ADR-045 rule chain fires on these. Nil-safe: leaves the publisher unset, in which case Execute logs warn and continues — useful for tests that don't exercise the rule wiring. Production wires this via llmwrap.NewNATSTriplePublisher(client) at registration.

type ResearchKVWriter

type ResearchKVWriter interface {
	CreateLoopEntity(ctx context.Context, loopID string, value []byte) error
	PutResearchTrigger(ctx context.Context, loopID string, value []byte) error
}

ResearchKVWriter is the narrow KV surface this executor consumes. Production satisfies it with a natsclient.KVStore scoped to the AGENT_LOOPS bucket; tests substitute an in-memory recorder so they don't need a real NATS connection.

Two methods so the tool can write both halves of its KV footprint:

  • CreateLoopEntity puts a research-pipeline LoopEntity at key <loopID>. Use Create semantics (returns ErrKVKeyExists if the loop_id collides) so an accidental duplicate doesn't silently overwrite the previous loop's state.

  • PutResearchTrigger writes the research_intent payload at key research.request.received.<loopID>. R0 watches this key pattern (see ADR-045 §Rule chain) and fires the chain on write. Last-write- wins is fine here because the loop_id is freshly minted and unique per call.

Jump to

Keyboard shortcuts

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