Choose SubAgent narration
Choose provider reasoning
Provider-exposed reasoning is private by default. Opt in only when every caller may receive prompt-derived details and provisional internal narration:Choose tool activity
Tool execution remains enabled even when its public progress is hidden. Use a suppressed tool-activity policy when callers should receive only agent lifecycle updates and the canonical answer or structured result:True value publishes neutral tool_call and tool_result
events. False removes both event types from JSON,
SSE, WebSocket, local, and playground output. A2A already keeps tool arguments
and results private.
Choose decision results
Results fromcontext.decisions.evaluate(...) are private by default. Keep
OutputPolicy(decision_results=False) to hide Jev or another decision provider’s
judgments while still using them for routing, tools, and LLM input.
To expose them separately from the final answer:
lifecycle/output.py
decision_result item to public output.
Its value contains decision/provider versions, typed answers, the policy
outcome, duration, and a safe error category when evaluation falls back.
Request state, question instructions, and raw provider payloads are excluded.
Private graph-to-model inputs are not presented as user turns when restoring
conversation history in ADK or LangGraph.
SSE and WebSocket use response.decision_result; streaming A2A tasks use
metadata.harnest.type: decision_result. Playground displays an expandable
Decision panel. Streamed results appear when the backend next yields an event.
This controls decision events, not arbitrary data copied into a final response
or tool result. Keep decision fields out of your final output schema if they
should remain internal. It does not redact LLM text, remove internal graph
state/checkpoints, or retroactively delete previously disclosed results.
Opted-in decision events are retained in durable completion output when
checkpoint storage is configured. Standalone Decisions.evaluate(...) calls
outside the context facade do not emit public events.
See the Jev example
for a decision followed by an LLM reply.
Choose agent metadata
Harnest emits one centralizedagent_metadata event for metadata reported by
ADK or LangGraph. The default AgentMetadataMode.NORMALIZED mode exposes the
portable fields that are present: model, provider, finish reason, and exact
input, output, and total token counts. Counts are never estimated.
Use AgentMetadataMode.SUPPRESS when callers must not receive any
model/provider metadata:
agent_metadata events and the aggregate usage
derived from them. Suppressed metadata is not added to durable completion
snapshots.
Use raw mode when an authorized caller needs the native framework payload:
raw. ADK uses its native
LlmResponse metadata field names. LangGraph namespaces stream_metadata,
response_metadata, usage_metadata, and additional_kwargs so fields do not
collide. The primary message content and Harnest-owned event state are not
copied. Native metadata can still contain provider-defined content-like values,
including reasoning annotations in additional_kwargs.
When Harnest owns checkpoint storage, it durably retains the normalized
completion snapshot so another replica can return the same per-call metadata,
aggregate usage, caller metadata, and structured result. Raw metadata remains
ephemeral by default, even when it is exposed live. Persist it only with the
separate opt-in:
What remains visible
All arguments are keyword-only. Binary controls require
True or False, and
agent_metadata requires AgentMetadataMode; string policy values are not
accepted. When moving an older project to this contract, run
harnest upgrade AGENT_DIR --apply to rewrite released string and positional
forms.