adk-fluent · P · C · S Visual Reference

# P·C·S Visual Reference

Three composition modules for declarative agent construction in adk-fluent
P
Prompt
Frozen Descriptor
Declaratively compose what the LLM is told to do. Structure instructions into ordered sections with canonical placement.
Compiles to → instruction (str or async callable)
C
Context
Frozen Descriptor
Declaratively control what the agent can see. Filter history, inject state, summarize, budget tokens.
Compiles to → include_contents + instruction (async callable)
S
State
Callable Transform
Transform how state flows between agents. Pick, rename, merge, guard, branch on state keys.
Compiles to → FnAgent step in pipeline
Five Orthogonal Concerns
C
Context
.reads() .context()
I
Input
.accepts()
O
Output
.returns() @
S
Storage
.writes()
K
Contract
.produces() .consumes()
before LLM ← • → after LLM

## What the LLM Receives

order matters
1

#### System Instruction P

Assembled from global_instruction (root only, deprecated) → static_instruction (cached) → instruction (main). Template variables {key} resolved from state.

global_instruction → system_instruction (if root agent) static_instruction → system_instruction (cached, no substitution) instruction → system_instruction (if no static) → user content (if static IS set)
2

#### Conversation History C

Controlled by `include_contents`. "default" = full history (filtered, rearranged). "none" = current turn only (latest user input + active tool calls).

"default" → all turns, branch-filtered, reordered "none" → current turn only (NOT empty — user input remains)
3

#### Context Injection C

When .reads() or .context(C.from_state()) is set, state values are injected as a <conversation_context> block appended to the instruction.

[Your instruction text] <conversation_context> [topic]: value from state [tone]: value from state </conversation_context>
4

#### User Message ADK

For .ask("prompt"): the prompt string. For pipelines: ADK manages turn flow. Multi-agent: other agents' messages reformatted as "[agent_name] said: ..."

5

#### Tools ADK

Function declarations for all registered tools. If output_schema is set on a model that doesn't natively support both, a `set_model_response` workaround tool is added.

6

#### Output Constraint schema

If output_schema is set: response_schema + response_mime_type="application/json". LLM must respond with JSON matching the schema.

## After the LLM Responds

response captured
→
state[key] = text
→
parse to Model
→
callbacks run
Note: .writes() stores raw text in state, not a parsed Pydantic model. If output_schema is set and you use .ask(), the response is parsed to a model instance on return.

## Composition Operators

Operator
P Prompt
C Context
S State
+
Union — merge sections
Union — merge context specs
Combine — run both on original state
|
Pipe — post-process output
Pipe — chain filter
—
>>
—
—
Chain — sequential through state

## Factory Catalog

P · 17 C · 29 S · 14

#### P · Core Sections

role(text)agent persona
context(text)background info
task(text)what to do
constraint(*rules)boundaries
format(text)output shape
example(in, out)few-shot
section(name, text)custom block

#### P · Dynamic

when(pred, block)conditional
from_state(*keys)inject state
template(text)string template

#### P · Structural & LLM

reorder(*names)reorder sections
only(*names)keep only
without(*names)remove sections
compress(max, model)LLM shrink
adapt(audience)LLM rephrase
scaffolded(block)wrap content
versioned(block, tag)version tag

#### C · Primitives

none()no context
default()full history
user_only()user messages

#### C · Selection

from_state(*keys)inject state
from_agents(*names)named agents
exclude_agents(*)skip agents
window(n)last N turns
last_n_turns(n)alias window
template(str)template text

#### C · Filtering

select(author,type)metadata filter
recent(decay)decay weighting
compact(strategy)merge msgs
dedup(strategy)remove dups
truncate(max)hard limit
project(*fields)pick fields

#### C · Constraints

budget(max_tokens)token limit
priority(tier)tier ranking
fit(max, strategy)auto-fit
fresh(max_age)freshness
redact(*patterns)remove PII

#### C · LLM-Powered

summarize(scope)LLM summary
relevant(query_key)semantic pick
extract(schema)structured
distill(key)key points

#### C · Sugar

rolling(n, summarize)window + sum
from_agents_windowed()per-agent
user(strategy)user msgs
manus_cascade(budget)cascade
notes(key)read notes
write_notes(key)persist notes
validate(*checks)assertions
capture(key)snapshot

#### S · Replacement

pick(*keys)keep only these
drop(*keys)remove these
rename(**mapping)rename keys

#### S · Delta (Additive)

default(**kv)set if missing
merge(*keys, into=)combine keys
transform(key, fn)map function
compute(**factories)derive values
set(**values)force values

#### S · Control & Inspect

when(pred, transform)conditional
branch(key, **tfms)switch/case
guard(pred, msg)assertion
log(*keys, label=)debug print
identity()no-op
capture(key)snapshot state

## Complete Example

All three modules in a single pipeline

#### Fluent Builder Code

    from adk_fluent import Agent, P, C, S

    reviewer = (
        Agent("reviewer")
        .instruct(
            P.role("Senior code reviewer.")
            + P.task("Review for bugs.")
            + P.constraint("Be concise.")
        )
        .context(
            C.window(n=5)
            + C.from_state("code")
        )
        .writes("review")
    )

    pipeline = (
        Agent("parser").writes("parsed")
        >> S.pick("parsed")
        >> S.rename(parsed="code")
        >> reviewer
        >> S.pick("review")
        >> Agent("summarizer")
           .reads("review")
    )

#### What the Reviewer LLM Sees

    ── system_instruction ──
    Senior code reviewer.

    Task:
    Review for bugs.

    Constraints:
    Be concise.

    <conversation_context>
    code: [contents of state["code"]]

    [last 5 turn-pairs from history]
    </conversation_context>

    ── contents ──
    [current turn only — no full history]

    ── after response ──
    state["review"] = response_text

## Pipeline Composition

Agent
parser .writes("parsed")
»
State Transform
S.pick("parsed")
»
State Transform
S.rename(parsed="code")
»
Agent
reviewer P + C + .writes
»
State Transform
S.pick("review")
»
Agent
summarizer .reads("review")

## Build-Time Compilation Order

1

#### Contract Checks

Run IR contract validation. Verify .produces()/.consumes() annotations match.

2

#### Extract Internal Directives

Pull out _context_spec, _prompt_spec, _output_schema from builder config. Strip internal _ fields.

3

#### Compile Context Spec C first

C transforms compile first. Sets include_contents and creates the instruction provider (async callable). CWriteNotes extracted to after_agent_callback.

4

#### Compile Prompt Spec P second

P transforms compile second. Can override the instruction from step 3. Static prompts become strings; dynamic prompts become async providers.

5

#### Assemble ADK Config

Final config dict passed to LlmAgent constructor. S transforms are wrapped as FnAgent pipeline steps separately.

adk-fluent · P · C · S — Three modules, five concerns, one fluent API