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
- func LoopsBucket(cfg *config.Config) string
- func RegisterComponents(registry *component.Registry) error
- func RegisterPayloads(registry *payloadregistry.Registry) error
- func RegisterTool(ctx context.Context, tools *agentictools.ExecutorRegistry, ...) error
- func Selected(cfg *config.Config) bool
- func ValidateConfig(cfg *config.Config) error
- type ResearchGraphExecutor
- type ResearchGraphOption
- type ResearchKVWriter
Constants ¶
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 ¶
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 ¶
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 ¶
Selected reports whether a config requests any part of graph research. A partial selection is still selected so ValidateConfig can reject it.
func ValidateConfig ¶
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:
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.
The research_intent payload wrapped in a BaseMessage envelope at key research.requested.<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 ¶
func (e *ResearchGraphExecutor) Execute(ctx context.Context, call agentic.ToolCall) (agentic.ToolResult, error)
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.requested, research.topic, research.loop_id, research.parent_loop/role, research.budget_tokens, research.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.requested.<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.