march-agent 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- march_agent/__init__.py +52 -0
- march_agent/agent.py +341 -0
- march_agent/agent_state_client.py +149 -0
- march_agent/app.py +416 -0
- march_agent/artifact.py +58 -0
- march_agent/checkpoint_client.py +169 -0
- march_agent/checkpointer.py +16 -0
- march_agent/cli.py +139 -0
- march_agent/conversation.py +103 -0
- march_agent/conversation_client.py +86 -0
- march_agent/conversation_message.py +48 -0
- march_agent/exceptions.py +36 -0
- march_agent/extensions/__init__.py +1 -0
- march_agent/extensions/langgraph.py +526 -0
- march_agent/extensions/pydantic_ai.py +180 -0
- march_agent/gateway_client.py +506 -0
- march_agent/gateway_pb2.py +73 -0
- march_agent/gateway_pb2_grpc.py +101 -0
- march_agent/heartbeat.py +84 -0
- march_agent/memory.py +73 -0
- march_agent/memory_client.py +155 -0
- march_agent/message.py +80 -0
- march_agent/streamer.py +220 -0
- march_agent-0.1.1.dist-info/METADATA +503 -0
- march_agent-0.1.1.dist-info/RECORD +29 -0
- march_agent-0.1.1.dist-info/WHEEL +5 -0
- march_agent-0.1.1.dist-info/entry_points.txt +2 -0
- march_agent-0.1.1.dist-info/licenses/LICENSE +21 -0
- march_agent-0.1.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: march-agent
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Python SDK for March AI Agent framework - handles agent registration, message consumption, and streaming responses
|
|
5
|
+
Author-email: March AI <support@march.ai>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/march-us/march-agent
|
|
8
|
+
Project-URL: Repository, https://github.com/march-us/march-agent
|
|
9
|
+
Project-URL: Documentation, https://github.com/march-us/march-agent#readme
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: grpcio>=1.70.0
|
|
22
|
+
Requires-Dist: grpcio-tools>=1.70.0
|
|
23
|
+
Requires-Dist: protobuf>=5.29.0
|
|
24
|
+
Requires-Dist: requests>=2.31.0
|
|
25
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
29
|
+
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest-mock>=3.11.0; extra == "dev"
|
|
31
|
+
Requires-Dist: respx>=0.20.0; extra == "dev"
|
|
32
|
+
Provides-Extra: langgraph
|
|
33
|
+
Requires-Dist: langgraph>=1.0.0; extra == "langgraph"
|
|
34
|
+
Requires-Dist: langchain-core>=0.3.0; extra == "langgraph"
|
|
35
|
+
Provides-Extra: pydantic
|
|
36
|
+
Requires-Dist: pydantic-ai>=1.0.0; extra == "pydantic"
|
|
37
|
+
Dynamic: license-file
|
|
38
|
+
|
|
39
|
+
# March Agent SDK
|
|
40
|
+
|
|
41
|
+
Python SDK for building AI agents in the March AI platform. Provides agent registration, message handling via Kafka (through Agent Gateway), streaming responses, and integrations with LangGraph and Pydantic AI.
|
|
42
|
+
|
|
43
|
+
## Overview
|
|
44
|
+
|
|
45
|
+
The March Agent SDK (`march-agent`) enables developers to build AI agents that integrate with the March AI Management platform. Agents register themselves, receive messages through Kafka topics, and stream responses back to users.
|
|
46
|
+
|
|
47
|
+
### Key Features
|
|
48
|
+
|
|
49
|
+
- **Agent Registration**: Automatic registration with AI Inventory
|
|
50
|
+
- **Message Handling**: Decorator-based handlers with sender filtering
|
|
51
|
+
- **Response Streaming**: Chunked responses via Kafka/Centrifugo
|
|
52
|
+
- **Conversation History**: Access to message history via Conversation Store
|
|
53
|
+
- **LangGraph Integration**: HTTP-based checkpoint saver for LangGraph graphs
|
|
54
|
+
- **Pydantic AI Integration**: Persistent message history for Pydantic AI agents
|
|
55
|
+
- **Error Handling**: Automatic error responses to users on handler failures
|
|
56
|
+
|
|
57
|
+
## Architecture
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
61
|
+
│ Your Agent Application │
|
|
62
|
+
├─────────────────────────────────────────────────────────────────────────────┤
|
|
63
|
+
│ │
|
|
64
|
+
│ MarchAgentApp │
|
|
65
|
+
│ ├── register_me() → Agent │
|
|
66
|
+
│ │ ├── @on_message decorator │
|
|
67
|
+
│ │ └── streamer() → Streamer │
|
|
68
|
+
│ └── run() → Start consume loop │
|
|
69
|
+
│ │
|
|
70
|
+
│ Extensions: │
|
|
71
|
+
│ ├── HTTPCheckpointSaver (LangGraph) │
|
|
72
|
+
│ └── PydanticAIMessageStore (Pydantic AI) │
|
|
73
|
+
│ │
|
|
74
|
+
└──────────────────────────────────┬──────────────────────────────────────────┘
|
|
75
|
+
│ gRPC (Kafka) + HTTP (APIs)
|
|
76
|
+
▼
|
|
77
|
+
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
78
|
+
│ Agent Gateway │
|
|
79
|
+
├─────────────────────────────────────────────────────────────────────────────┤
|
|
80
|
+
│ gRPC: AgentStream (bidirectional) HTTP: /s/{service}/* proxy │
|
|
81
|
+
│ - Auth - /s/ai-inventory/* │
|
|
82
|
+
│ - Subscribe/Unsubscribe - /s/conversation-store/* │
|
|
83
|
+
│ - Produce/Consume messages │
|
|
84
|
+
└─────────────────┬───────────────────────────────────┬───────────────────────┘
|
|
85
|
+
│ │
|
|
86
|
+
▼ ▼
|
|
87
|
+
┌──────────────┐ ┌────────────────────┐
|
|
88
|
+
│ Kafka │ │ AI Inventory / │
|
|
89
|
+
│ {agent}.inbox │ │ Conversation Store │
|
|
90
|
+
└──────────────┘ └────────────────────┘
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Message Flow
|
|
94
|
+
|
|
95
|
+
```mermaid
|
|
96
|
+
sequenceDiagram
|
|
97
|
+
participant User
|
|
98
|
+
participant Provider
|
|
99
|
+
participant Router
|
|
100
|
+
participant Gateway as Agent Gateway
|
|
101
|
+
participant Agent as Your Agent
|
|
102
|
+
participant ConvStore as Conversation Store
|
|
103
|
+
|
|
104
|
+
User->>Provider: Send message
|
|
105
|
+
Provider->>Router: Kafka: router.inbox
|
|
106
|
+
Router->>Gateway: Kafka: {agent}.inbox
|
|
107
|
+
Gateway->>Agent: gRPC stream: message
|
|
108
|
+
|
|
109
|
+
Agent->>ConvStore: Get conversation history
|
|
110
|
+
ConvStore-->>Agent: Message history
|
|
111
|
+
|
|
112
|
+
loop Streaming Response
|
|
113
|
+
Agent->>Gateway: gRPC stream: content chunk
|
|
114
|
+
Gateway->>Router: Kafka: router.inbox
|
|
115
|
+
Router->>Provider: Kafka: user.inbox
|
|
116
|
+
Provider->>User: WebSocket: chunk
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
Agent->>Gateway: gRPC stream: done=true
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Installation
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# Basic installation
|
|
126
|
+
pip install march-agent
|
|
127
|
+
|
|
128
|
+
# With LangGraph support
|
|
129
|
+
pip install march-agent[langgraph]
|
|
130
|
+
|
|
131
|
+
# With Pydantic AI support
|
|
132
|
+
pip install march-agent[pydantic]
|
|
133
|
+
|
|
134
|
+
# Development installation
|
|
135
|
+
pip install -e ".[dev]"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Quick Start
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
from march_agent import MarchAgentApp
|
|
142
|
+
|
|
143
|
+
# Initialize the app
|
|
144
|
+
app = MarchAgentApp(
|
|
145
|
+
gateway_url="agent-gateway:8080",
|
|
146
|
+
api_key="your-api-key"
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
# Register an agent
|
|
150
|
+
agent = app.register_me(
|
|
151
|
+
name="my-assistant",
|
|
152
|
+
about="A helpful AI assistant",
|
|
153
|
+
document="Answers general questions and provides helpful information.",
|
|
154
|
+
representation_name="My Assistant"
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
# Handle messages
|
|
158
|
+
@agent.on_message
|
|
159
|
+
async def handle_message(message, sender):
|
|
160
|
+
# Access conversation history
|
|
161
|
+
history = message.conversation.get_history(limit=10)
|
|
162
|
+
|
|
163
|
+
# Stream response
|
|
164
|
+
async with agent.streamer(message) as s:
|
|
165
|
+
s.stream("Hello! ")
|
|
166
|
+
s.stream("How can I help you today?")
|
|
167
|
+
|
|
168
|
+
# Run the agent
|
|
169
|
+
app.run()
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Configuration
|
|
173
|
+
|
|
174
|
+
### Environment Variables
|
|
175
|
+
|
|
176
|
+
| Variable | Description | Default |
|
|
177
|
+
|----------|-------------|---------|
|
|
178
|
+
| `GATEWAY_URL` | Agent Gateway endpoint | Required |
|
|
179
|
+
| `GATEWAY_API_KEY` | API key for authentication | Required |
|
|
180
|
+
|
|
181
|
+
### MarchAgentApp Options
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
app = MarchAgentApp(
|
|
185
|
+
gateway_url="agent-gateway:8080", # Gateway endpoint
|
|
186
|
+
api_key="key", # Authentication key
|
|
187
|
+
heartbeat_interval=60, # Heartbeat frequency (seconds)
|
|
188
|
+
max_concurrent_tasks=100, # Max concurrent message handlers
|
|
189
|
+
error_message_template="...", # Error message sent to users
|
|
190
|
+
)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## API Reference
|
|
194
|
+
|
|
195
|
+
### MarchAgentApp
|
|
196
|
+
|
|
197
|
+
Main application class for initializing and running agents.
|
|
198
|
+
|
|
199
|
+
```python
|
|
200
|
+
app = MarchAgentApp(gateway_url, api_key)
|
|
201
|
+
|
|
202
|
+
# Register an agent
|
|
203
|
+
agent = app.register_me(
|
|
204
|
+
name="agent-name", # Unique identifier (used for routing)
|
|
205
|
+
about="Short description", # Brief description for agent selection
|
|
206
|
+
document="Full docs...", # Detailed documentation
|
|
207
|
+
representation_name="Name", # Display name (optional)
|
|
208
|
+
metadata={"key": "value"}, # Additional metadata (optional)
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
# Start consuming messages
|
|
212
|
+
app.run() # Blocks until shutdown
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Agent
|
|
216
|
+
|
|
217
|
+
Handles message registration and response streaming.
|
|
218
|
+
|
|
219
|
+
```python
|
|
220
|
+
# Register message handler (all senders)
|
|
221
|
+
@agent.on_message
|
|
222
|
+
async def handle(message, sender):
|
|
223
|
+
pass
|
|
224
|
+
|
|
225
|
+
# Filter by sender
|
|
226
|
+
@agent.on_message(senders=["user"])
|
|
227
|
+
async def handle_user(message, sender):
|
|
228
|
+
pass
|
|
229
|
+
|
|
230
|
+
# Exclude sender
|
|
231
|
+
@agent.on_message(senders=["~other-agent"])
|
|
232
|
+
async def handle_not_other(message, sender):
|
|
233
|
+
pass
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Message
|
|
237
|
+
|
|
238
|
+
Represents an incoming message with conversation context.
|
|
239
|
+
|
|
240
|
+
```python
|
|
241
|
+
@agent.on_message
|
|
242
|
+
async def handle(message, sender):
|
|
243
|
+
message.id # Message ID
|
|
244
|
+
message.conversation_id # Conversation ID
|
|
245
|
+
message.content # Message content
|
|
246
|
+
message.created_at # Timestamp
|
|
247
|
+
|
|
248
|
+
# Access conversation history
|
|
249
|
+
message.conversation.get_history(limit=10)
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Streamer
|
|
253
|
+
|
|
254
|
+
Streams response chunks back to the user (or another agent).
|
|
255
|
+
|
|
256
|
+
```python
|
|
257
|
+
@agent.on_message
|
|
258
|
+
async def handle(message, sender):
|
|
259
|
+
# Basic streaming
|
|
260
|
+
async with agent.streamer(message) as s:
|
|
261
|
+
s.stream("Chunk 1...")
|
|
262
|
+
s.stream("Chunk 2...")
|
|
263
|
+
|
|
264
|
+
# Streaming with options
|
|
265
|
+
async with agent.streamer(
|
|
266
|
+
message,
|
|
267
|
+
send_to="user", # or another agent name
|
|
268
|
+
awaiting=True, # Set awaiting_route to this agent
|
|
269
|
+
) as s:
|
|
270
|
+
# Non-persisted content (not saved to DB)
|
|
271
|
+
s.stream("Thinking...", persist=False, event_type="thinking")
|
|
272
|
+
|
|
273
|
+
# Persisted content
|
|
274
|
+
s.stream("Here's my response...")
|
|
275
|
+
|
|
276
|
+
# Set response schema for forms
|
|
277
|
+
s.set_response_schema({
|
|
278
|
+
"type": "object",
|
|
279
|
+
"properties": {
|
|
280
|
+
"name": {"type": "string"}
|
|
281
|
+
}
|
|
282
|
+
})
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## Extensions
|
|
286
|
+
|
|
287
|
+
### LangGraph Integration
|
|
288
|
+
|
|
289
|
+
Use `HTTPCheckpointSaver` to persist LangGraph state via the Conversation Store checkpoint API.
|
|
290
|
+
|
|
291
|
+
```python
|
|
292
|
+
from march_agent import MarchAgentApp
|
|
293
|
+
from march_agent.extensions.langgraph import HTTPCheckpointSaver
|
|
294
|
+
from langgraph.graph import StateGraph
|
|
295
|
+
|
|
296
|
+
app = MarchAgentApp(gateway_url="...", api_key="...")
|
|
297
|
+
checkpointer = HTTPCheckpointSaver(app=app)
|
|
298
|
+
|
|
299
|
+
# Define your LangGraph
|
|
300
|
+
graph = StateGraph(MyState)
|
|
301
|
+
# ... add nodes and edges ...
|
|
302
|
+
compiled = graph.compile(checkpointer=checkpointer)
|
|
303
|
+
|
|
304
|
+
agent = app.register_me(name="langgraph-agent", ...)
|
|
305
|
+
|
|
306
|
+
@agent.on_message
|
|
307
|
+
async def handle(message, sender):
|
|
308
|
+
config = {"configurable": {"thread_id": message.conversation_id}}
|
|
309
|
+
|
|
310
|
+
async with agent.streamer(message) as s:
|
|
311
|
+
# Graph state persists across messages via checkpointer
|
|
312
|
+
result = await compiled.ainvoke(
|
|
313
|
+
{"messages": [message.content]},
|
|
314
|
+
config
|
|
315
|
+
)
|
|
316
|
+
s.stream(result["messages"][-1])
|
|
317
|
+
|
|
318
|
+
app.run()
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Pydantic AI Integration
|
|
322
|
+
|
|
323
|
+
Use `PydanticAIMessageStore` to persist Pydantic AI message history.
|
|
324
|
+
|
|
325
|
+
```python
|
|
326
|
+
from march_agent import MarchAgentApp
|
|
327
|
+
from march_agent.extensions.pydantic_ai import PydanticAIMessageStore
|
|
328
|
+
from pydantic_ai import Agent as PydanticAgent
|
|
329
|
+
|
|
330
|
+
app = MarchAgentApp(gateway_url="...", api_key="...")
|
|
331
|
+
store = PydanticAIMessageStore(app=app)
|
|
332
|
+
|
|
333
|
+
my_llm = PydanticAgent('openai:gpt-4o', system_prompt="You are helpful.")
|
|
334
|
+
|
|
335
|
+
agent = app.register_me(name="pydantic-agent", ...)
|
|
336
|
+
|
|
337
|
+
@agent.on_message
|
|
338
|
+
async def handle(message, sender):
|
|
339
|
+
# Load previous messages
|
|
340
|
+
history = await store.load(message.conversation_id)
|
|
341
|
+
|
|
342
|
+
async with agent.streamer(message) as s:
|
|
343
|
+
async with my_llm.run_stream(
|
|
344
|
+
message.content,
|
|
345
|
+
message_history=history
|
|
346
|
+
) as result:
|
|
347
|
+
async for chunk in result.stream_text():
|
|
348
|
+
s.stream(chunk)
|
|
349
|
+
|
|
350
|
+
# Save updated history
|
|
351
|
+
await store.save(message.conversation_id, result.all_messages())
|
|
352
|
+
|
|
353
|
+
app.run()
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## Advanced Usage
|
|
357
|
+
|
|
358
|
+
### Inter-Agent Communication
|
|
359
|
+
|
|
360
|
+
Agents can send messages to other agents using the `send_to` parameter.
|
|
361
|
+
|
|
362
|
+
```python
|
|
363
|
+
@agent.on_message(senders=["user"])
|
|
364
|
+
async def handle_user(message, sender):
|
|
365
|
+
# Forward to specialist agent
|
|
366
|
+
async with agent.streamer(message, send_to="specialist-agent") as s:
|
|
367
|
+
s.stream("Forwarding your question to the specialist...")
|
|
368
|
+
|
|
369
|
+
@agent.on_message(senders=["specialist-agent"])
|
|
370
|
+
async def handle_specialist(message, sender):
|
|
371
|
+
# Respond to user with specialist's answer
|
|
372
|
+
async with agent.streamer(message, send_to="user") as s:
|
|
373
|
+
s.stream(f"The specialist says: {message.content}")
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### Dynamic Forms with Response Schema
|
|
377
|
+
|
|
378
|
+
Request structured input from users using JSON Schema forms.
|
|
379
|
+
|
|
380
|
+
```python
|
|
381
|
+
@agent.on_message
|
|
382
|
+
async def handle(message, sender):
|
|
383
|
+
async with agent.streamer(message, awaiting=True) as s:
|
|
384
|
+
s.stream("Please fill out this form:")
|
|
385
|
+
s.set_response_schema({
|
|
386
|
+
"type": "object",
|
|
387
|
+
"title": "Contact Information",
|
|
388
|
+
"properties": {
|
|
389
|
+
"name": {"type": "string", "title": "Full Name"},
|
|
390
|
+
"email": {"type": "string", "format": "email"},
|
|
391
|
+
"message": {"type": "string", "title": "Message"}
|
|
392
|
+
},
|
|
393
|
+
"required": ["name", "email"]
|
|
394
|
+
})
|
|
395
|
+
|
|
396
|
+
# When user submits form, message.content will be JSON
|
|
397
|
+
@agent.on_message
|
|
398
|
+
async def handle_form(message, sender):
|
|
399
|
+
import json
|
|
400
|
+
data = json.loads(message.content)
|
|
401
|
+
name = data.get("name")
|
|
402
|
+
# Process form data...
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
### Error Handling
|
|
406
|
+
|
|
407
|
+
Customize error handling behavior:
|
|
408
|
+
|
|
409
|
+
```python
|
|
410
|
+
app = MarchAgentApp(
|
|
411
|
+
gateway_url="...",
|
|
412
|
+
api_key="...",
|
|
413
|
+
error_message_template="Sorry, something went wrong. Please try again."
|
|
414
|
+
)
|
|
415
|
+
|
|
416
|
+
agent = app.register_me(...)
|
|
417
|
+
|
|
418
|
+
# Disable automatic error responses
|
|
419
|
+
agent.send_error_responses = False
|
|
420
|
+
|
|
421
|
+
@agent.on_message
|
|
422
|
+
async def handle(message, sender):
|
|
423
|
+
try:
|
|
424
|
+
# Your logic
|
|
425
|
+
pass
|
|
426
|
+
except Exception as e:
|
|
427
|
+
# Custom error handling
|
|
428
|
+
async with agent.streamer(message) as s:
|
|
429
|
+
s.stream(f"I encountered an issue: {str(e)}")
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
## Project Structure
|
|
433
|
+
|
|
434
|
+
```
|
|
435
|
+
ai-framework/
|
|
436
|
+
├── src/
|
|
437
|
+
│ └── march_agent/
|
|
438
|
+
│ ├── __init__.py # Package exports
|
|
439
|
+
│ ├── app.py # MarchAgentApp
|
|
440
|
+
│ ├── agent.py # Agent class
|
|
441
|
+
│ ├── message.py # Message class
|
|
442
|
+
│ ├── streamer.py # Streamer class
|
|
443
|
+
│ ├── conversation.py # Conversation helper
|
|
444
|
+
│ ├── conversation_client.py # HTTP client for Conversation Store
|
|
445
|
+
│ ├── checkpoint_client.py # HTTP client for checkpoints
|
|
446
|
+
│ ├── agent_state_client.py # HTTP client for agent state
|
|
447
|
+
│ ├── gateway_client.py # gRPC client for Agent Gateway
|
|
448
|
+
│ ├── gateway_pb2.py # Generated protobuf
|
|
449
|
+
│ ├── gateway_pb2_grpc.py # Generated gRPC stubs
|
|
450
|
+
│ ├── heartbeat.py # Heartbeat manager
|
|
451
|
+
│ ├── exceptions.py # Custom exceptions
|
|
452
|
+
│ └── extensions/
|
|
453
|
+
│ ├── __init__.py
|
|
454
|
+
│ ├── langgraph.py # LangGraph HTTPCheckpointSaver
|
|
455
|
+
│ └── pydantic_ai.py # Pydantic AI MessageStore
|
|
456
|
+
├── tests/
|
|
457
|
+
├── pyproject.toml
|
|
458
|
+
└── README.md
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
## Development
|
|
462
|
+
|
|
463
|
+
### Running Tests
|
|
464
|
+
|
|
465
|
+
```bash
|
|
466
|
+
# Install dev dependencies
|
|
467
|
+
pip install -e ".[dev]"
|
|
468
|
+
|
|
469
|
+
# Run tests with coverage
|
|
470
|
+
pytest
|
|
471
|
+
|
|
472
|
+
# Run specific test file
|
|
473
|
+
pytest tests/test_agent.py -v
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
### Regenerating Protobuf
|
|
477
|
+
|
|
478
|
+
If the gateway.proto file changes:
|
|
479
|
+
|
|
480
|
+
```bash
|
|
481
|
+
python -m grpc_tools.protoc \
|
|
482
|
+
-I../../agent-gateway/proto \
|
|
483
|
+
--python_out=src/march_agent \
|
|
484
|
+
--grpc_python_out=src/march_agent \
|
|
485
|
+
../../agent-gateway/proto/gateway.proto
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
## Dependencies
|
|
489
|
+
|
|
490
|
+
| Package | Purpose |
|
|
491
|
+
|---------|---------|
|
|
492
|
+
| grpcio | gRPC communication with Agent Gateway |
|
|
493
|
+
| grpcio-tools | Protobuf compilation |
|
|
494
|
+
| protobuf | Message serialization |
|
|
495
|
+
| requests | Sync HTTP for registration |
|
|
496
|
+
| aiohttp | Async HTTP for runtime operations |
|
|
497
|
+
|
|
498
|
+
### Optional Dependencies
|
|
499
|
+
|
|
500
|
+
| Package | Install Command | Purpose |
|
|
501
|
+
|---------|-----------------|---------|
|
|
502
|
+
| langgraph | `pip install march-agent[langgraph]` | LangGraph checkpoint integration |
|
|
503
|
+
| pydantic-ai | `pip install march-agent[pydantic]` | Pydantic AI message history |
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
march_agent/__init__.py,sha256=S9SV9LFo9gOaoiRbeDdvhJI9bKg9AIDei-RFDRRzZBI,1191
|
|
2
|
+
march_agent/agent.py,sha256=pvFGoBO8-2mwDWq4LpHB_aTXO6F8DG6YwOd1khj-O2I,12532
|
|
3
|
+
march_agent/agent_state_client.py,sha256=pEwF6f1RHS_nwth6LXb1ytFZiZ4nOgha4aZZ5qcBSrk,4948
|
|
4
|
+
march_agent/app.py,sha256=HW2gWB2ktbHPaoO-P-uzhS2Ud9jp4U40fYZUrfOKXco,15976
|
|
5
|
+
march_agent/artifact.py,sha256=JTdSoU3pVwSZ9Gkr4M7ylisG5CY3j_eUXGGJmt4Q7YA,1782
|
|
6
|
+
march_agent/checkpoint_client.py,sha256=-3LAEDVnn6ZgAtuVgT7i3GQtUD2NFFjTXC2IyA7lwUY,6056
|
|
7
|
+
march_agent/checkpointer.py,sha256=hm9WdEZ5eIz8uBQklyEnNL1Krf3z-uNScPw1V5aK0-E,526
|
|
8
|
+
march_agent/cli.py,sha256=c5XVFxWiw1sMVBeEFRFv73HPu-ZKXvhV8skvFVVCCUg,3846
|
|
9
|
+
march_agent/conversation.py,sha256=wvsXWatCPVYJ_M10iGCOtenTWqAE1gUfxgIpku0drB8,3470
|
|
10
|
+
march_agent/conversation_client.py,sha256=Af2iJHDBtmUAQBq2ipK8V94DIWuFLQimiW-HlUgAueY,3184
|
|
11
|
+
march_agent/conversation_message.py,sha256=-GOb8KOwRt3tk0dRKEyxaWrwwzLV2ghS3O8Ja35XSvo,1688
|
|
12
|
+
march_agent/exceptions.py,sha256=_mPQkzG2yK5xKWaIngwi1sMA2x-UMcGpr2H_QDZ4Wew,763
|
|
13
|
+
march_agent/gateway_client.py,sha256=SvI4B_S9y3QfEKO0aZjAICR27YPqupzoRt68gvLIKlQ,16183
|
|
14
|
+
march_agent/gateway_pb2.py,sha256=FA7fHMmVvxL_Bent7Dw96E0Any0BdzWwUOLfUvZn8Do,6140
|
|
15
|
+
march_agent/gateway_pb2_grpc.py,sha256=TAK5vwwl008KxWKam0-76L4IQ3gsaC0zFA1oqR44-4I,3475
|
|
16
|
+
march_agent/heartbeat.py,sha256=nv5IFzDVBUnAYFQnP0V515NxdttM6U3Ik3mOFOJnjKo,2767
|
|
17
|
+
march_agent/memory.py,sha256=EJf1ja5f30htgJZss5AGZ4CgHaz22BO6e84MJj1OptA,2291
|
|
18
|
+
march_agent/memory_client.py,sha256=VWyllXDNxAfSNxMsgj34dVwy1V1zZDcW9UdRfMkmpNc,5141
|
|
19
|
+
march_agent/message.py,sha256=U4yR2dY0sC5iuU9MxNrl9lSIrJZgrPyiK3TPIK6vEoQ,2366
|
|
20
|
+
march_agent/streamer.py,sha256=4r0pIRxyfe7fSLskhq3a3zRPUgOV6kXso4Cxja-0Ho8,7882
|
|
21
|
+
march_agent/extensions/__init__.py,sha256=VjEvH-1gCnkTzIbxwrwoJmwZQniWVc482-D3d7gzI2I,37
|
|
22
|
+
march_agent/extensions/langgraph.py,sha256=S0qc-G9QF3joDKhaUqqUdkW5D2VuGrxuKPeDceneIyc,19252
|
|
23
|
+
march_agent/extensions/pydantic_ai.py,sha256=j0jJJ0LFqZcrp3afLUiwZgTiKC2ZqAJV2tDuziajk7c,5807
|
|
24
|
+
march_agent-0.1.1.dist-info/licenses/LICENSE,sha256=tmASeS19bzdNhxLRrKEgISA7BrGdXkiPdSmHktpxptM,1065
|
|
25
|
+
march_agent-0.1.1.dist-info/METADATA,sha256=iP_EU0REn6eyo4i-PY3XW0UibcxqMd124mVApRPDhF8,17274
|
|
26
|
+
march_agent-0.1.1.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
|
|
27
|
+
march_agent-0.1.1.dist-info/entry_points.txt,sha256=3nVN4mJbhPi4oZBj5GDfL9ptKkVeQjitVFkIMJ9Txd0,53
|
|
28
|
+
march_agent-0.1.1.dist-info/top_level.txt,sha256=sFnINVMd3896bCUXL4AkmE9wsT4wL_ekt4RKprZiyXM,12
|
|
29
|
+
march_agent-0.1.1.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 March AI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
march_agent
|