instruction_processor.go
Overview
This file implements dynamic processing and injection of instructions for large language model (LLM) agents by replacing placeholders in instruction templates with runtime session state values or artifact contents. It supports both agent-specific and global instructions, enabling context-aware prompt construction for LLM requests.
The core functionality revolves around parsing instruction templates for placeholders enclosed in curly braces (e.g., {user_name}, {app:current_task}, {artifact.report}), validating these placeholders, retrieving corresponding values from session state or artifact storage, and injecting these values into the instructions before appending them to the LLM request.
This mechanism enables AI agents to deliver personalized, dynamic, and contextually relevant instructions to the LLM, adapting to the current invocation context and session state.
The file is part of the broader Instruction Template Processing (80563) and Session State Injection (80597) domains, and tightly integrates with LLM Integration and Agents (80562), Session Management (80559), and Artifact Management (80557).
Key Components
Constants
appPrefix, userPrefix, tempPrefix: Define recognized prefixes for session state variable namespaces (e.g.,
app:,user:,temp:). These are used to validate variable names.
Function: instructionsRequestProcessor
func instructionsRequestProcessor(ctx agent.InvocationContext, req *model.LLMRequest) error
Purpose:
Main entry point to process and append instructions to an LLM request during agent invocation.
Parameters:
ctx— The current agent invocation context providing access to session, artifacts, and agent hierarchy.req— The LLM request object to which instructions are appended.
Returns:
Error if instruction processing or appending fails; otherwise nil.
Behavior:
Converts the current agent and root agent in the invocation context to internal LLM agent types.
Calls
appendGlobalInstructionsto inject global instructions from the root agent intoreq.Calls
appendInstructionsto inject the current agent’s instructions intoreq.Returns any errors encountered.
Usage Example:
Typically invoked as part of the agent lifecycle before making an LLM call, ensuring instructions are up-to-date with session state.
Functions: appendInstructions and appendGlobalInstructions
func appendInstructions(ctx agent.InvocationContext, req *model.LLMRequest, agentState *State) error
func appendGlobalInstructions(ctx agent.InvocationContext, req *model.LLMRequest, agentState *State) error
Purpose:
Inject processed instructions into the LLM request, either agent-specific or global.
Parameters:
ctx— Invocation context.req— LLM request to append instructions.agentState— Internal agent state containing instruction templates or provider functions.
Returns:
Error on failure to evaluate or inject instructions.
Behavior:
If an instruction provider function is present, it is invoked to generate instructions dynamically.
Otherwise, the static instruction string is processed via
InjectSessionStateto replace placeholders.The resulting instructions are appended to the LLM request using
utils.AppendInstructions.
Implementation Detail:
Uses a read-only context wrapper (
icontext.NewReadonlyContext) for safety when calling instruction providers.
Function: InjectSessionState
func InjectSessionState(ctx agent.InvocationContext, template string) (string, error)
Purpose:
Core logic to parse an instruction template and replace placeholders with actual session state or artifact data.
Parameters:
ctx— Invocation context providing access to session and artifact services.template— Instruction template string containing placeholders.
Returns:
Processed instruction string with placeholders replaced, or error if any required value is missing or retrieval fails.
Behavior:
Uses a regular expression (
{+[^{}]*}+) to find all placeholders in the template.Iterates over each placeholder:
Extracts the variable name.
Calls
replaceMatchto resolve the placeholder to its corresponding value.
Reconstructs the template string with all placeholders replaced.
Returns the fully injected instruction string.
Usage Example:
injected, err := InjectSessionState(ctx, "Hello {user_name}, see {artifact.report}")
if err != nil {
// handle error
}
// injected now contains the instruction with placeholders replaced
Function: replaceMatch
func replaceMatch(ctx agent.InvocationContext, match string) (string, error)
Purpose:
Resolves a single placeholder match by fetching its corresponding value from session state or artifact storage.
Parameters:
ctx— Invocation context.match— The placeholder string including braces, e.g.,{user_name},{artifact.file_name},{temp:key?}.
Returns:
Replacement string or error if resolution fails.
Implementation Details:
Trims braces and whitespace to get variable name.
Detects optional placeholders if variable name ends with
?; missing optional values return empty string instead of error.If variable name starts with
artifact., callsctx.Artifacts().Loadto retrieve artifact content.Validates variable name using
isValidStateName:Must be a valid identifier or prefixed by known namespaces (
app:,user:,temp:).
Retrieves session state variable via
ctx.Session().State().Get.Returns string representation of the value or empty string if value is nil.
Error Handling:
Returns errors if artifact service is uninitialized or artifact loading fails (unless optional).
Returns errors if session variable fetch fails (unless optional).
If variable name is invalid, returns the original placeholder string unchanged.
Helper Functions: isIdentifier and isValidStateName
func isIdentifier(s string) bool
func isValidStateName(varName string) bool
Purpose:
Validate if strings conform to acceptable Go-like identifier rules and namespace prefix conventions.
isIdentifier checks if a string starts with a letter or underscore and contains only letters, digits, or underscores.
isValidStateName additionally allows a single colon-separated prefix if it matches one of recognized prefixes (app:, user:, temp:), and validates the suffix as an identifier.
Important Implementation Details and Algorithms
Placeholder Parsing: Uses regex to find all bracketed placeholders in a single pass to efficiently process instruction templates.
Replacement Logic: The
replaceMatchmethod handles two categories: artifact references and session state variables, including optional placeholders denoted with?.Optional Placeholders: This design choice allows templates to gracefully handle missing data by substituting empty strings instead of failing.
Integration with Invocation Context: The artifact and session services are accessed through the provided
InvocationContext, abstracting the underlying storage or retrieval mechanisms.Error Propagation: Errors during injection halt processing and propagate upwards, ensuring LLM requests are not sent with incomplete or inconsistent instructions.
Namespace Prefixes: Session variables can be scoped using prefixes (
app:,user:,temp:), allowing separation of state domains.Instruction Providers: Supports both static instructions and dynamic instruction generation via callback functions, enabling flexible agent configuration.
Interaction with Other System Components
LLM Agent (
llminternal.State): Holds the agent’s instruction templates or provider functions. This file uses the internalStateto fetch instructions and global instructions.Agent Invocation Context (
agent.InvocationContext): Provides access to the current session state (ctx.Session().State()) and artifact service (ctx.Artifacts()).Artifact Service (
80557- Artifact Management): Used to load artifact contents that are injected into instructions.Session State Service (
80559- Session Management): Provides key-value state data for injection.Instruction Utility (
utils.AppendInstructions): Helper to append processed instructions to the LLM request object.Parent Agent Map (
parentmap): Used to locate the root agent for global instruction processing.Agent Lifecycle: The
instructionsRequestProcessorfunction is called during agent invocation to enrich LLM requests with fully injected instructions.
Structure Diagram
classDiagram
class InstructionProcessor {
+instructionsRequestProcessor(ctx, req) error
+appendInstructions(ctx, req, agentState) error
+appendGlobalInstructions(ctx, req, agentState) error
+InjectSessionState(ctx, template) (string, error)
-replaceMatch(ctx, match) (string, error)
-isIdentifier(s) bool
-isValidStateName(varName) bool
}
InstructionProcessor ..> agent.InvocationContext
InstructionProcessor ..> model.LLMRequest
InstructionProcessor ..> State
InstructionProcessor ..> ArtifactService
InstructionProcessor ..> SessionState
Workflow Diagram: Instruction Injection Process
flowchart TD
Start[Start: Instruction Template]
Parse[Parse Template for Placeholders]
ForEach[For Each Placeholder]
IsArtifact{Is Placeholder an Artifact?}
LoadArtifact[Load Artifact Content]
GetState[Get Session State Value]
IsOptional{Is Placeholder Optional?}
Replace[Replace Placeholder with Value]
Error{Error?}
SkipOrFail[Skip or Fail Based on Optional Flag]
End[Return Processed Instruction String]
Start --> Parse --> ForEach
ForEach --> IsArtifact
IsArtifact -->|Yes| LoadArtifact
IsArtifact -->|No| GetState
LoadArtifact --> Error
GetState --> Error
Error -->|Yes| SkipOrFail
Error -->|No| Replace
SkipOrFail --> ForEach
Replace --> ForEach
ForEach -->|No More Placeholders| End
This flowchart illustrates how the file processes an instruction template by iterating over placeholders, resolving each either from artifact content or session state, handling optional placeholders gracefully, and reconstructing the final instruction string.
Usage Pattern Summary
During Agent Invocation:
instructionsRequestProcessoris called with the current agent context and LLM request.It retrieves the root agent and current agent states.
Calls
appendGlobalInstructionsto inject global instructions.Calls
appendInstructionsto inject agent-specific instructions.Each append function calls
InjectSessionStateto replace placeholders.The final instructions are appended to the LLM request.
At Template Injection Level:
InjectSessionStatescans the instruction template for placeholders.Each placeholder is resolved by
replaceMatchfrom session state or artifact service.Results are concatenated to produce the fully injected instruction string.
This file is a critical component for dynamic prompt generation, ensuring that instructions sent to LLMs are contextually accurate and up-to-date with session and artifact data, enhancing the intelligence and responsiveness of AI agents.