Skip to content
Closed
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
69 changes: 12 additions & 57 deletions python/packages/kagent-langgraph/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,71 +4,26 @@ This package provides LangGraph integration for KAgent with A2A (Agent-to-Agent)

## Features

- **A2A Server Integration**: Compatible with KAgent's Agent-to-Agent protocol
- **Event Streaming**: Real-time streaming of graph execution events
- **FastAPI Integration**: Ready-to-deploy web server for agent execution
- **A2A Server Integration**: Serves LangGraph workflows over A2A
- **Event Streaming**: Streams graph execution events
- **FastAPI Integration**: Builds a deployable FastAPI application

## Quick Start
## State and Task Storage

```python
from kagent.core import AsyncControllerClient, AsyncFileTokenProvider, KAgentConfig
from kagent.langgraph import KAgentApp
import os
import sqlite3
from langgraph.checkpoint.sqlite import SqliteSaver
from langgraph.graph import StateGraph
from langchain_core.messages import BaseMessage
from typing import TypedDict, Annotated, Sequence
The LangGraph checkpointer owns graph conversation state. A SQLite checkpointer stores checkpoints in a local file; persistence across pod replacement requires placing that file on durable storage or selecting another durable LangGraph checkpointer.

class State(TypedDict):
messages: Annotated[Sequence[BaseMessage], "The conversation history"]

config = KAgentConfig()
controller_client = AsyncControllerClient(
config.grpc_url,
agent_name=config.app_name,
token_provider=AsyncFileTokenProvider(),
)

# Define and compile your graph
builder = StateGraph(State)
# Add nodes and edges...
checkpointer = SqliteSaver(sqlite3.connect(
os.getenv("KAGENT_CHECKPOINT_DB", "/tmp/langgraph-checkpoints.sqlite"),
check_same_thread=False,
))
graph = builder.compile(checkpointer=checkpointer)

# Create KAgent app
app = KAgentApp(
graph=graph,
agent_card={
"name": "my-langgraph-agent",
"description": "A LangGraph agent with KAgent integration",
"version": "0.1.0",
"capabilities": {"streaming": True},
"defaultInputModes": ["text"],
"defaultOutputModes": ["text"]
},
config=config,
controller_client=controller_client,
)

# Build FastAPI application
fastapi_app = app.build()
```
`KAgentApp` uses an in-memory A2A task store inside the agent process. That task state does not survive a process restart. This package does not configure a gateway connection; a deployment may place a gateway in front of the application and have that gateway own durable task history.

## Architecture

The package mirrors the structure of `kagent-adk` but uses LangGraph instead of Google's ADK:

- **LangGraphAgentExecutor**: Executes LangGraph workflows within A2A protocol
- **KAgentApp**: FastAPI application builder with A2A integration
- **Task Management**: Automatic A2A task persistence through one shared authenticated gRPC channel
- **LangGraphAgentExecutor**: Executes LangGraph workflows over A2A
- **KAgentApp**: Builds the FastAPI A2A application
- **LangGraph checkpointer**: Stores graph conversation state when configured
- **InMemoryTaskStore**: Tracks A2A tasks for the lifetime of the process

## Configuration

Set both endpoints when running locally. A2A and MCP use `KAGENT_GATEWAY_URL`, while control-plane calls use `KAGENT_API_URL`.
`KAgentConfig` currently requires both endpoint values and the agent identity. This wrapper uses the identity and tracing configuration, but does not use these URLs for outbound control-plane or gateway calls:

```bash
export KAGENT_API_URL=http://localhost:8083
Expand All @@ -79,4 +34,4 @@ export KAGENT_NAMESPACE=default

## Deployment

Use the same deployment pattern as kagent-adk samples with Docker and Kubernetes.
This package has no documented end-to-end deployment path yet. Sample documentation identifies the validation available for each sample.
114 changes: 49 additions & 65 deletions python/packages/kagent-openai/README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,52 @@
# KAgent OpenAI Agents SDK Integration

OpenAI Agents SDK integration for KAgent with A2A (Agent-to-Agent) protocol support, session management, and optional skills integration.
OpenAI Agents SDK integration for KAgent with A2A (Agent-to-Agent) protocol support and optional skills integration.

---

## Quick Start

Set the required configuration first:

```bash
export KAGENT_API_URL=http://localhost:8083
export KAGENT_GATEWAY_URL=http://localhost:8083
export KAGENT_NAME=my-openai-agent
export KAGENT_NAMESPACE=default
export OPENAI_API_KEY=your-api-key
```

Then build the A2A application:

```python
from kagent.openai import KAgentApp
from agents.agent import Agent
from kagent.core import KAgentConfig
from kagent.openai import KAgentApp

# Create your OpenAI agent
agent = Agent(
name="Assistant",
instructions="You are a helpful assistant.",
tools=[my_tool], # Optional
tools=[],
)

# Create KAgent app
agent_card = {
"name": "my-openai-agent",
"description": "My OpenAI agent",
"version": "0.1.0",
"supportedInterfaces": [
{"url": "http://localhost:8080", "protocolBinding": "JSONRPC"}
],
"capabilities": {"streaming": True},
"defaultInputModes": ["text/plain"],
"defaultOutputModes": ["text/plain"],
}

app = KAgentApp(
agent=agent,
agent_card={
"name": "my-openai-agent",
"description": "My OpenAI agent",
"version": "0.1.0",
"capabilities": {"streaming": True},
"defaultInputModes": ["text"],
"defaultOutputModes": ["text"]
},
kagent_url="http://localhost:8083",
app_name="my-agent"
agent_card=agent_card,
config=KAgentConfig(),
)

# Run
fastapi_app = app.build()
# uvicorn run_me:fastapi_app
```
Expand Down Expand Up @@ -61,77 +75,48 @@ See [skills README](../../kagent-skills/README.md) for skill format and structur

---

## Session Management
## Task and Conversation State

Sessions persist conversation history in KAgent backend:

```python
from agents.agent import Agent
from agents.run import Runner
from kagent.openai._session_service import KAgentSession
import httpx

client = httpx.AsyncClient(base_url="http://localhost:8083")
session = KAgentSession(
session_id="conversation_123",
client=client,
app_name="my-agent",
)
`KAgentApp` uses an in-memory A2A task store and does not configure an OpenAI Agents SDK session. Task state held by the agent process is lost when that process restarts. This package does not configure a gateway connection; a deployment may place a gateway in front of the application and have that gateway own durable task history.

agent = Agent(name="Assistant", instructions="Be helpful")
result = await Runner.run(agent, "Hello!", session=session)
```
Applications that need durable framework-level conversation state must configure it explicitly rather than relying on a KAgent REST session service.

---

## Local Development

Test without KAgent backend using in-memory mode:
`build_local()` creates the same kind of in-memory A2A application without connecting to a KAgent backend. `KAgentConfig` still requires its configuration values:

```python
app = KAgentApp(
agent=agent,
agent_card=agent_card,
kagent_url="http://localhost:8083",
app_name="test-agent"
config=KAgentConfig(),
)

fastapi_app = app.build_local() # In-memory, no persistence
```

---

## Deployment

Standard Docker deployment:

```dockerfile
FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY agent.py .
CMD ["uvicorn", "agent:fastapi_app", "--host", "0.0.0.0", "--port", "8000"]
fastapi_app = app.build_local()
```

Set `KAGENT_API_URL` and `KAGENT_GATEWAY_URL` to connect to kagent.

---

## Architecture

| Component | Purpose |
| ----------------------- | -------------------------------------------- |
| **KAgentApp** | FastAPI application builder with A2A support |
| **KAgentSession** | Session persistence via KAgent REST API |
| **OpenAIAgentExecutor** | Executes agents with event streaming |
| Component | Purpose |
| --- | --- |
| **KAgentApp** | FastAPI application builder with A2A support |
| **OpenAIAgentExecutor** | Executes agents with event streaming |
| **InMemoryTaskStore** | Tracks A2A tasks for the lifetime of the process |

---

## Environment Variables

- `KAGENT_API_URL` - KAgent control-plane API URL
- `KAGENT_GATEWAY_URL` - KAgent A2A and MCP gateway URL
- `KAGENT_API_URL` - Required by `KAgentConfig`; not used for outbound control-plane calls by this wrapper
- `KAGENT_GATEWAY_URL` - Required by `KAgentConfig`; not used for outbound gateway calls by this wrapper
- `KAGENT_NAME` - Agent name
- `KAGENT_NAMESPACE` - Agent namespace
- `OPENAI_API_KEY` - OpenAI API key
- `OPENAI_API_BASE` - Optional OpenAI-compatible API base URL
- `LOG_LEVEL` - Logging level (default: INFO)

---
Expand All @@ -141,15 +126,14 @@ Set `KAGENT_API_URL` and `KAGENT_GATEWAY_URL` to connect to kagent.
See `samples/openai/` for complete examples:

- `basic_agent/` - Simple agent with custom tools
- More examples coming soon

---

## See Also

- [OpenAI Agents SDK Docs](https://github.com/openai/agents)
- [OpenAI Agents SDK Docs](https://github.com/openai/openai-agents-python)
- [KAgent Skills](../../kagent-skills/README.md)
- [A2A Protocol](https://docs.kagent.ai/a2a)
- [A2A Protocol](https://a2a-protocol.org/)

---

Expand Down
88 changes: 19 additions & 69 deletions python/samples/langgraph/currency/README.md
Original file line number Diff line number Diff line change
@@ -1,88 +1,37 @@
# Currency LangGraph Agent

This is a currency LangGraph agent that demonstrates KAgent integration with session persistence via REST API.
This sample serves a currency-conversion LangGraph agent over A2A. LangGraph conversation state is checkpointed to a local SQLite file.

## Features

- Currency conversion agent using OpenAI
- LangGraph state management with KAgent checkpointer
- A2A protocol compatibility
- Session persistence via KAgent REST API
- Currency conversion using OpenAI and the Frankfurter API
- LangGraph state checkpointing with `SqliteSaver`
- A2A protocol support
- Streaming responses

## Quick Start
## Deployment

1. Build the agent image:

Run the basic-langchain-sample target from the top-level Python directory.

```bash
make basic-langchain-sample
```

2. Push to local registry (if using one):

```bash
docker push localhost:5001/langgraph-currency:latest
```

3. Create a secret with the OpenAI API key:

```bash
kubectl create secret generic kagent-openai -n kagent \
--from-literal=OPENAI_API_KEY=$OPENAI_API_KEY \
--dry-run=client -o yaml | kubectl apply -f -
```

4. Run the image through a BYO `Harness` and matching `AgentTemplate`; see the
API v2 examples and E2E fixtures for the current resource shape.

## Local Development

1. Install dependencies:

```bash
uv sync
```

2. Set environment variables:

```bash
export OPENAI_API_KEY=your_api_key_here
export KAGENT_API_URL=http://localhost:8083
export KAGENT_GATEWAY_URL=http://localhost:8083
```

3. Run the agent server:

```bash
uv run currency
```

4. Test the agent:

```bash
uv run currency test
```
The repository validates the packaged module import, ASGI application construction, and `GET /health` response. It does not validate the `main()` process lifecycle, port binding, container startup, OpenAI-backed execution, A2A requests, or checkpoint reuse after restart. This sample therefore has no documented end-to-end runtime command yet.

## Architecture

This agent demonstrates:

- **StateGraph**: Simple conversation flow with one node
- **SqliteSaver**: Stores conversation state in a local SQLite file
- **A2A Integration**: Compatible with KAgent's agent-to-agent protocol
- **Streaming**: Real-time response streaming via A2A events
- **StateGraph**: A ReAct conversation graph with a currency tool
- **SqliteSaver**: Stores LangGraph conversation state in a local SQLite file
- **A2A Integration**: Serves the graph through KAgent's A2A application wrapper
- **Streaming**: Emits graph execution updates as A2A events

The agent stores conversation history in `KAGENT_CHECKPOINT_DB` (default: `/tmp/currency-checkpoints.sqlite`). Mount a persistent volume and point the variable there for persistence across pod replacement.
The agent stores LangGraph checkpoints in `KAGENT_CHECKPOINT_DB` (default: `/tmp/currency-checkpoints.sqlite`). Mount a persistent volume and point the variable there to retain checkpoints across pod replacement. A2A task tracking inside the agent process remains in memory.

## Configuration

The agent can be configured via environment variables:

- `OPENAI_API_KEY`: Required for OpenAI API access
- `KAGENT_API_URL`: Required. KAgent control-plane API URL; locally, `http://localhost:8083`
- `KAGENT_GATEWAY_URL`: Required. KAgent A2A and MCP gateway URL; locally, `http://localhost:8083`
- `KAGENT_API_URL`: Required by `KAgentConfig`; not used for outbound control-plane calls by this wrapper
- `KAGENT_GATEWAY_URL`: Required by `KAgentConfig`; not used for outbound gateway calls by this wrapper
- `KAGENT_NAME`: Required agent name
- `KAGENT_NAMESPACE`: Required agent namespace
- `KAGENT_CHECKPOINT_DB`: SQLite checkpoint path (default: `/tmp/currency-checkpoints.sqlite`)
- `PORT`: Server port (default: 8080)
- `HOST`: Server host (default: 0.0.0.0)

Expand All @@ -107,5 +56,6 @@ High-level options for tracing this sample:
- If you create custom tools, decorate them with the LangSmith SDK's `@traceable` decorator; this sample shows it for the exchange-rate tool.

References:
- LangSmith SDK: `https://github.com/langchain-ai/langsmith-sdk`
- Trace with OpenTelemetry: `https://docs.langchain.com/langsmith/trace-with-opentelemetry`

- LangSmith SDK: https://github.com/langchain-ai/langsmith-sdk
- Trace with OpenTelemetry: https://docs.langchain.com/langsmith/trace-with-opentelemetry
Loading