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.
@@ -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,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ march-agent = march_agent.cli:main
@@ -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