Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go/api/v1alpha2/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions go/config/crd/bases/kagent.dev_agents.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6060,6 +6060,46 @@ spec:
minItems: 1
type: array
type: object
context:
properties:
cache:
properties:
cacheIntervals:
type: integer
enabled:
type: boolean
minTokens:
type: integer
ttlSeconds:
type: integer
required:
- enabled
type: object
compression:
properties:
compactionInterval:
type: integer
enabled:
type: boolean
overlapSize:
type: integer
summarizer:
properties:
model:
description: Model to use for summarization (required
if type is llm)
type: string
type:
default: llm
enum:
- llm
- text
type: string
type: object
required:
- enabled
type: object
type: object
deployment:
properties:
affinity:
Expand Down
40 changes: 40 additions & 0 deletions helm/kagent-crds/templates/kagent.dev_agents.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6060,6 +6060,46 @@ spec:
minItems: 1
type: array
type: object
context:
properties:
cache:
properties:
cacheIntervals:
type: integer
enabled:
type: boolean
minTokens:
type: integer
ttlSeconds:
type: integer
required:
- enabled
type: object
compression:
properties:
compactionInterval:
type: integer
enabled:
type: boolean
overlapSize:
type: integer
summarizer:
properties:
model:
description: Model to use for summarization (required
if type is llm)
type: string
type:
default: llm
enum:
- llm
- text
type: string
type: object
required:
- enabled
type: object
type: object
deployment:
properties:
affinity:
Expand Down
10 changes: 9 additions & 1 deletion python/packages/kagent-adk/src/kagent/adk/_a2a.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def __init__(
app_name: str,
lifespan: Optional[Callable[[Any], Any]] = None,
plugins: List[BasePlugin] = None,
context_configs: Optional[Dict[str, Any]] = None,
stream: bool = False,
):
self.root_agent = root_agent
Expand All @@ -63,6 +64,7 @@ def __init__(
self.agent_card = agent_card
self._lifespan = lifespan
self.plugins = plugins if plugins is not None else []
self.context_configs = context_configs or {"compaction": None, "cache": None}
self.stream = stream

def build(self, local=False) -> FastAPI:
Expand All @@ -77,7 +79,13 @@ def build(self, local=False) -> FastAPI:
)
session_service = KAgentSessionService(http_client)

adk_app = App(name=self.app_name, root_agent=self.root_agent, plugins=self.plugins)
adk_app = App(
name=self.app_name,
root_agent=self.root_agent,
plugins=self.plugins,
events_compaction_config=self.context_configs.get("compaction"),
context_cache_config=self.context_configs.get("cache")
)

def create_runner() -> Runner:
return Runner(
Expand Down
59 changes: 59 additions & 0 deletions python/packages/kagent-adk/src/kagent/adk/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
from agentsts.adk import ADKTokenPropagationPlugin
from google.adk.agents import Agent
from google.adk.agents.base_agent import BaseAgent
from google.adk.apps.app import App, EventsCompactionConfig
from google.adk.apps.llm_event_summarizer import LlmEventSummarizer
from google.adk.agents.context_cache_config import ContextCacheConfig as AdkCacheConfig
from google.adk.agents.llm_agent import ToolUnion
from google.adk.agents.remote_a2a_agent import AGENT_CARD_WELL_KNOWN_PATH, DEFAULT_TIMEOUT, RemoteA2aAgent
from google.adk.code_executors.base_code_executor import BaseCodeExecutor
Expand Down Expand Up @@ -95,6 +98,60 @@ class Gemini(BaseLLM):
type: Literal["gemini"]


class ContextSummarizerSettings(BaseModel):
model: Optional[str] = None
type: Literal["llm", "text"] = "llm"

class ContextCompressionSettings(BaseModel):
enabled: bool
compaction_interval: Optional[int] = Field(None, alias="compactionInterval")
overlap_size: Optional[int] = Field(None, alias="overlapSize")
summarizer: Optional[ContextSummarizerSettings] = None

class ContextCacheSettings(BaseModel):
enabled: bool
min_tokens: Optional[int] = Field(None, alias="minTokens")
ttl_seconds: Optional[int] = Field(None, alias="ttlSeconds")
cache_intervals: Optional[int] = Field(None, alias="cacheIntervals")

class ContextConfig(BaseModel):
cache: Optional[ContextCacheSettings] = None
compression: Optional[ContextCompressionSettings] = None


def build_adk_context_configs(ctx: Optional[ContextConfig], default_llm: Any) -> Dict[str, Any]:
configs = {
"events_compaction_config": None,
"context_cache_config": None
}

if not ctx:
return configs

if ctx.compression and ctx.compression.enabled:
summarizer = None
if ctx.compression.summarizer and ctx.compression.summarizer.type == "llm":
# Use the provided model for summarization, or fall back to the main agent model
summerizer_model_name = ctx.compression.summarizer.model
summarizer_llm = GeminiLLM(model=summerizer_model_name) if summerizer_model_name else default_llm
summarizer = LlmEventSummarizer(llm=summarizer_llm)

configs["events_compaction_config"] = EventsCompactionConfig(
compaction_interval=ctx.compression.compaction_interval or 3,
overlap_size=ctx.compression.overlap_size or 1,
summarizer=summarizer,
)

if ctx.cache and ctx.cache.enabled:
configs["context_cache_config"] = AdkCacheConfig(
min_tokens=ctx.cache.min_tokens or 2048,
ttl_seconds=ctx.cache.ttl_seconds or 3600,
cache_intervals=ctx.cache.cache_intervals or 5,
)

return configs


class AgentConfig(BaseModel):
model: Union[OpenAI, Anthropic, GeminiVertexAI, GeminiAnthropic, Ollama, AzureOpenAI, Gemini] = Field(
discriminator="type"
Expand All @@ -105,6 +162,8 @@ class AgentConfig(BaseModel):
sse_tools: list[SseMcpServerConfig] | None = None # SSE MCP tools
remote_agents: list[RemoteAgentConfig] | None = None # remote agents
execute_code: bool | None = None
context: Optional[ContextConfig] = None

# This stream option refers to LLM response streaming, not A2A streaming
stream: bool | None = None

Expand Down