Agent Context
This guide explains what context reaches business agent code when KsADK invokes ADK, LangGraph, LangChain, or DeepAgents projects.
Recommended Pattern
Do not make business code parse raw UI events or internal session records. Use a framework hook or runner payload boundary:
| Framework | Recommended integration |
|---|---|
| LangGraph | define ksadk_prepare_state(payload, session_context) |
| LangChain | define ksadk_prepare_input(payload, session_context) |
| ADK | consume ADK message/session primitives produced by the runner |
| DeepAgents | configure the model/tools and consume normalized input |
For LangGraph and LangChain, the hook must be visible from the configured entry_point module.
Standard Payload Fields
The runner payload can include:
| Field | Meaning |
|---|---|
input | current user input text or resume payload |
history | projected conversation history |
input_content | current input as Responses-style content blocks |
input_messages | current input as Responses-style messages/items |
input_parts | legacy/internal normalized parts |
attachments | effective attachment context, possibly restored from session |
attachment_results | effective extracted text/OCR/document results |
current_attachments | attachments from the current user turn only |
current_attachment_results | extraction results from the current user turn only |
has_current_files | whether this user turn included files/images |
model | per-request model override |
model_metadata | model capability metadata where available |
instructions | request-level system/developer instruction |
invocation_id | per-invocation identifier, useful for trace correlation and resume |
Session context can include:
| Field | Meaning |
|---|---|
history | current conversation history |
platform_context | agent ID, user ID, account ID, session ID, and related runtime identity |
kb_context | knowledge-base retrieval context |
memory_context | long-term memory context |
is_resume | whether the request is resuming an interrupted run |
New in 0.6.7
platform_context.account_id defaults to an empty string. Skill / Workspace / Sandbox / Memory isolate per account boundary: data is visible within the same account and isolated across accounts.
LangGraph Hook
def ksadk_prepare_state(payload: dict, session_context: dict) -> dict:
if session_context.get("is_resume"):
return payload.get("input")
return {
"query": payload["input"],
"history": session_context.get("history", []),
"attachments": payload.get("attachments", []),
"attachment_results": payload.get("attachment_results", []),
"current_attachments": payload.get("current_attachments", []),
"current_attachment_results": payload.get("current_attachment_results", []),
"has_current_files": payload.get("has_current_files", False),
"input_content": payload.get("input_content", []),
"input_messages": payload.get("input_messages", []),
"platform_context": session_context.get("platform_context"),
"kb_context": session_context.get("kb_context"),
"memory_context": session_context.get("memory_context"),
"model_metadata": payload.get("model_metadata", {}),
}When is_resume is true, return the resume payload directly. Do not wrap it as a new graph state unless your graph explicitly expects that.
LangChain Hook
def ksadk_prepare_input(payload: dict, session_context: dict) -> dict:
return {
"question": payload["input"],
"history": session_context.get("history", []),
"attachment_texts": [
item.get("text", "")
for item in payload.get("attachment_results", [])
if isinstance(item, dict) and item.get("text")
],
"input_content": payload.get("input_content", []),
"input_messages": payload.get("input_messages", []),
"model_metadata": payload.get("model_metadata", {}),
}Your chain decides how to map this dictionary into prompts, tools, retrievers, or model-native multimodal inputs.
Current Turn Versus Session Context
Use current-turn fields when the answer should depend on files the user just uploaded:
if payload.get("has_current_files"):
results = payload.get("current_attachment_results", [])Use effective context fields when the user is following up on an earlier file in the same session:
results = payload.get("attachment_results", [])This distinction matters for workflows such as "summarize this PDF" followed by "expand the second risk".
Model Metadata
model_metadata can describe input modalities and capabilities. A common check:
supports_image = bool(
((model_metadata or {}).get("capabilities") or {}).get("multimodal_input_image")
)If a model does not support native image input, prefer extracted OCR/document text from attachment_results.
Core Fields
KsADK collapses runtime context into a single PlatformInvocationContext that both
the runner and business code read from. The core fields are:
| Field | Meaning |
|---|---|
agent_id | agent identifier |
user_id | user identifier |
account_id | account identifier, defaults to an empty string; isolates Skill / Workspace / Sandbox / Memory per account boundary |
session_id | current session |
invocation_id | per-invocation identifier, useful for trace correlation and resume |
model | per-request model |
attachments | current-turn files or images |
memory_context | optional long-term memory context |
kb_context | optional knowledge-base context |
HTTP Entrypoints and account_id Propagation
The following three public HTTP entrypoints propagate the account identifier from
the request into PlatformInvocationContext:
| Endpoint | Request field | Written to |
|---|---|---|
POST /v1/responses | account_id | PlatformInvocationContext.account_id |
POST /v1/chat/completions | account_id | PlatformInvocationContext.account_id |
POST /v1/RunAgent (RunAgentAction) | AccountId | PlatformInvocationContext.account_id |
Once the account identifier is in the context, Skill / Workspace / Sandbox / Memory read it per account boundary uniformly, without business code needing to forward it.
Runtime Context Helper
Business tools or shared helpers that need the active invocation context should use the runtime context helpers rather than parsing private event-store internals or gateway headers.
New in 0.6.5
New safe-read entrypoints that never raise when no context is active:
get_current_invocation_context_or_default(): returns a fully emptyPlatformInvocationContextwhen no context is active (agent_id/user_id/account_id/session_idare empty strings, list fields are empty), so it is safe to call from tools or background tasks.get_current_user_id(default=''): returns the currentuser_id, ordefaultwhen no context is active.get_current_account_id(default=''): returns the currentaccount_id, ordefaultwhen no context is active.
from ksadk.runtime_context import (
get_current_invocation_context_or_default,
get_current_user_id,
get_current_account_id,
get_current_invocation_context,
)
# Safe read, will not raise in offline / background tasks
ctx = get_current_invocation_context_or_default()
print(ctx.agent_id)
print(ctx.account_id)
# Single identifiers, fall back to default when no context
user_id = get_current_user_id() # default ''
account_id = get_current_account_id() # default ''Account boundary
Skill / Workspace / Sandbox / Memory read per account_id boundary. In tool code prefer get_current_account_id() over parsing the request yourself, so the isolation semantics match the hosted runtime.
Use this for cross-cutting helpers. Business graph state should still prefer explicit hook inputs because they are easier to test.
What Not To Do
Avoid:
- reading private event-store internals from business code.
- assuming
attachmentsmeans "files uploaded in this turn". - treating
inlineDataandfileDataas official OpenAI fields. - mixing hosted gateway headers into local examples.
- storing secrets in graph state, logs, traces, or public fixtures.