agno 2.0.0rc1__py3-none-any.whl → 2.0.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.
- agno/agent/agent.py +101 -140
- agno/db/mongo/mongo.py +8 -3
- agno/eval/accuracy.py +12 -5
- agno/knowledge/chunking/strategy.py +14 -14
- agno/knowledge/knowledge.py +156 -120
- agno/knowledge/reader/arxiv_reader.py +5 -5
- agno/knowledge/reader/csv_reader.py +6 -77
- agno/knowledge/reader/docx_reader.py +5 -5
- agno/knowledge/reader/firecrawl_reader.py +5 -5
- agno/knowledge/reader/json_reader.py +5 -5
- agno/knowledge/reader/markdown_reader.py +31 -9
- agno/knowledge/reader/pdf_reader.py +10 -123
- agno/knowledge/reader/reader_factory.py +65 -72
- agno/knowledge/reader/s3_reader.py +44 -114
- agno/knowledge/reader/text_reader.py +5 -5
- agno/knowledge/reader/url_reader.py +75 -31
- agno/knowledge/reader/web_search_reader.py +6 -29
- agno/knowledge/reader/website_reader.py +5 -5
- agno/knowledge/reader/wikipedia_reader.py +5 -5
- agno/knowledge/reader/youtube_reader.py +6 -6
- agno/knowledge/reranker/__init__.py +9 -0
- agno/knowledge/utils.py +10 -10
- agno/media.py +269 -268
- agno/models/aws/bedrock.py +3 -7
- agno/models/base.py +50 -54
- agno/models/google/gemini.py +11 -10
- agno/models/message.py +4 -4
- agno/models/ollama/chat.py +1 -1
- agno/models/openai/chat.py +33 -14
- agno/models/response.py +5 -5
- agno/os/app.py +40 -29
- agno/os/mcp.py +39 -59
- agno/os/router.py +547 -16
- agno/os/routers/evals/evals.py +197 -12
- agno/os/routers/knowledge/knowledge.py +428 -14
- agno/os/routers/memory/memory.py +250 -28
- agno/os/routers/metrics/metrics.py +125 -7
- agno/os/routers/session/session.py +393 -25
- agno/os/schema.py +55 -2
- agno/run/agent.py +37 -28
- agno/run/base.py +9 -19
- agno/run/team.py +110 -19
- agno/run/workflow.py +41 -28
- agno/team/team.py +808 -1080
- agno/tools/brightdata.py +3 -3
- agno/tools/cartesia.py +3 -5
- agno/tools/dalle.py +7 -4
- agno/tools/desi_vocal.py +2 -2
- agno/tools/e2b.py +6 -6
- agno/tools/eleven_labs.py +3 -3
- agno/tools/fal.py +4 -4
- agno/tools/function.py +7 -7
- agno/tools/giphy.py +2 -2
- agno/tools/lumalab.py +3 -3
- agno/tools/mcp.py +1 -2
- agno/tools/models/azure_openai.py +2 -2
- agno/tools/models/gemini.py +3 -3
- agno/tools/models/groq.py +3 -5
- agno/tools/models/nebius.py +2 -2
- agno/tools/models_labs.py +5 -5
- agno/tools/openai.py +4 -9
- agno/tools/opencv.py +3 -3
- agno/tools/replicate.py +7 -7
- agno/utils/events.py +5 -5
- agno/utils/gemini.py +1 -1
- agno/utils/log.py +52 -2
- agno/utils/mcp.py +57 -5
- agno/utils/models/aws_claude.py +1 -1
- agno/utils/models/claude.py +0 -8
- agno/utils/models/cohere.py +1 -1
- agno/utils/models/watsonx.py +1 -1
- agno/utils/openai.py +1 -1
- agno/utils/print_response/team.py +177 -73
- agno/utils/streamlit.py +27 -0
- agno/vectordb/lancedb/lance_db.py +82 -25
- agno/workflow/step.py +7 -7
- agno/workflow/types.py +13 -13
- agno/workflow/workflow.py +37 -28
- {agno-2.0.0rc1.dist-info → agno-2.0.1.dist-info}/METADATA +140 -1
- {agno-2.0.0rc1.dist-info → agno-2.0.1.dist-info}/RECORD +83 -84
- agno-2.0.1.dist-info/licenses/LICENSE +201 -0
- agno/knowledge/reader/gcs_reader.py +0 -67
- agno-2.0.0rc1.dist-info/licenses/LICENSE +0 -375
- {agno-2.0.0rc1.dist-info → agno-2.0.1.dist-info}/WHEEL +0 -0
- {agno-2.0.0rc1.dist-info → agno-2.0.1.dist-info}/top_level.txt +0 -0
agno/os/router.py
CHANGED
|
@@ -21,11 +21,17 @@ from agno.os.auth import get_authentication_dependency
|
|
|
21
21
|
from agno.os.schema import (
|
|
22
22
|
AgentResponse,
|
|
23
23
|
AgentSummaryResponse,
|
|
24
|
+
BadRequestResponse,
|
|
24
25
|
ConfigResponse,
|
|
26
|
+
HealthResponse,
|
|
25
27
|
InterfaceResponse,
|
|
28
|
+
InternalServerErrorResponse,
|
|
26
29
|
Model,
|
|
30
|
+
NotFoundResponse,
|
|
27
31
|
TeamResponse,
|
|
28
32
|
TeamSummaryResponse,
|
|
33
|
+
UnauthenticatedResponse,
|
|
34
|
+
ValidationErrorResponse,
|
|
29
35
|
WorkflowResponse,
|
|
30
36
|
WorkflowSummaryResponse,
|
|
31
37
|
)
|
|
@@ -307,13 +313,47 @@ def get_base_router(
|
|
|
307
313
|
os: "AgentOS",
|
|
308
314
|
settings: AgnoAPISettings = AgnoAPISettings(),
|
|
309
315
|
) -> APIRouter:
|
|
310
|
-
|
|
316
|
+
"""
|
|
317
|
+
Create the base FastAPI router with comprehensive OpenAPI documentation.
|
|
318
|
+
|
|
319
|
+
This router provides endpoints for:
|
|
320
|
+
- Core system operations (health, config, models)
|
|
321
|
+
- Agent management and execution
|
|
322
|
+
- Team collaboration and coordination
|
|
323
|
+
- Workflow automation and orchestration
|
|
324
|
+
- Real-time WebSocket communications
|
|
325
|
+
|
|
326
|
+
All endpoints include detailed documentation, examples, and proper error handling.
|
|
327
|
+
"""
|
|
328
|
+
router = APIRouter(
|
|
329
|
+
dependencies=[Depends(get_authentication_dependency(settings))],
|
|
330
|
+
responses={
|
|
331
|
+
400: {"description": "Bad Request", "model": BadRequestResponse},
|
|
332
|
+
401: {"description": "Unauthorized", "model": UnauthenticatedResponse},
|
|
333
|
+
404: {"description": "Not Found", "model": NotFoundResponse},
|
|
334
|
+
422: {"description": "Validation Error", "model": ValidationErrorResponse},
|
|
335
|
+
500: {"description": "Internal Server Error", "model": InternalServerErrorResponse},
|
|
336
|
+
},
|
|
337
|
+
)
|
|
311
338
|
|
|
312
339
|
# -- Main Routes ---
|
|
313
340
|
|
|
314
|
-
@router.get(
|
|
315
|
-
|
|
316
|
-
|
|
341
|
+
@router.get(
|
|
342
|
+
"/health",
|
|
343
|
+
tags=["Core"],
|
|
344
|
+
operation_id="health_check",
|
|
345
|
+
summary="Health Check",
|
|
346
|
+
description="Check the health status of the AgentOS API. Returns a simple status indicator.",
|
|
347
|
+
response_model=HealthResponse,
|
|
348
|
+
responses={
|
|
349
|
+
200: {
|
|
350
|
+
"description": "API is healthy and operational",
|
|
351
|
+
"content": {"application/json": {"example": {"status": "ok"}}},
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
)
|
|
355
|
+
async def health_check() -> HealthResponse:
|
|
356
|
+
return HealthResponse(status="ok")
|
|
317
357
|
|
|
318
358
|
@router.get(
|
|
319
359
|
"/config",
|
|
@@ -321,6 +361,79 @@ def get_base_router(
|
|
|
321
361
|
response_model_exclude_none=True,
|
|
322
362
|
tags=["Core"],
|
|
323
363
|
operation_id="get_config",
|
|
364
|
+
summary="Get OS Configuration",
|
|
365
|
+
description=(
|
|
366
|
+
"Retrieve the complete configuration of the AgentOS instance, including:\n\n"
|
|
367
|
+
"- Available models and databases\n"
|
|
368
|
+
"- Registered agents, teams, and workflows\n"
|
|
369
|
+
"- Chat, session, memory, knowledge, and evaluation configurations\n"
|
|
370
|
+
"- Available interfaces and their routes"
|
|
371
|
+
),
|
|
372
|
+
responses={
|
|
373
|
+
200: {
|
|
374
|
+
"description": "OS configuration retrieved successfully",
|
|
375
|
+
"content": {
|
|
376
|
+
"application/json": {
|
|
377
|
+
"example": {
|
|
378
|
+
"os_id": "demo",
|
|
379
|
+
"description": "Example AgentOS configuration",
|
|
380
|
+
"available_models": [],
|
|
381
|
+
"databases": ["9c884dc4-9066-448c-9074-ef49ec7eb73c"],
|
|
382
|
+
"session": {
|
|
383
|
+
"dbs": [
|
|
384
|
+
{
|
|
385
|
+
"db_id": "9c884dc4-9066-448c-9074-ef49ec7eb73c",
|
|
386
|
+
"domain_config": {"display_name": "Sessions"},
|
|
387
|
+
}
|
|
388
|
+
]
|
|
389
|
+
},
|
|
390
|
+
"metrics": {
|
|
391
|
+
"dbs": [
|
|
392
|
+
{
|
|
393
|
+
"db_id": "9c884dc4-9066-448c-9074-ef49ec7eb73c",
|
|
394
|
+
"domain_config": {"display_name": "Metrics"},
|
|
395
|
+
}
|
|
396
|
+
]
|
|
397
|
+
},
|
|
398
|
+
"memory": {
|
|
399
|
+
"dbs": [
|
|
400
|
+
{
|
|
401
|
+
"db_id": "9c884dc4-9066-448c-9074-ef49ec7eb73c",
|
|
402
|
+
"domain_config": {"display_name": "Memory"},
|
|
403
|
+
}
|
|
404
|
+
]
|
|
405
|
+
},
|
|
406
|
+
"knowledge": {
|
|
407
|
+
"dbs": [
|
|
408
|
+
{
|
|
409
|
+
"db_id": "9c884dc4-9066-448c-9074-ef49ec7eb73c",
|
|
410
|
+
"domain_config": {"display_name": "Knowledge"},
|
|
411
|
+
}
|
|
412
|
+
]
|
|
413
|
+
},
|
|
414
|
+
"evals": {
|
|
415
|
+
"dbs": [
|
|
416
|
+
{
|
|
417
|
+
"db_id": "9c884dc4-9066-448c-9074-ef49ec7eb73c",
|
|
418
|
+
"domain_config": {"display_name": "Evals"},
|
|
419
|
+
}
|
|
420
|
+
]
|
|
421
|
+
},
|
|
422
|
+
"agents": [
|
|
423
|
+
{
|
|
424
|
+
"id": "main-agent",
|
|
425
|
+
"name": "Main Agent",
|
|
426
|
+
"db_id": "9c884dc4-9066-448c-9074-ef49ec7eb73c",
|
|
427
|
+
}
|
|
428
|
+
],
|
|
429
|
+
"teams": [],
|
|
430
|
+
"workflows": [],
|
|
431
|
+
"interfaces": [],
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
},
|
|
435
|
+
}
|
|
436
|
+
},
|
|
324
437
|
)
|
|
325
438
|
async def config() -> ConfigResponse:
|
|
326
439
|
return ConfigResponse(
|
|
@@ -349,8 +462,26 @@ def get_base_router(
|
|
|
349
462
|
response_model_exclude_none=True,
|
|
350
463
|
tags=["Core"],
|
|
351
464
|
operation_id="get_models",
|
|
465
|
+
summary="Get Available Models",
|
|
466
|
+
description=(
|
|
467
|
+
"Retrieve a list of all unique models currently used by agents and teams in this OS instance. "
|
|
468
|
+
"This includes the model ID and provider information for each model."
|
|
469
|
+
),
|
|
470
|
+
responses={
|
|
471
|
+
200: {
|
|
472
|
+
"description": "List of models retrieved successfully",
|
|
473
|
+
"content": {
|
|
474
|
+
"application/json": {
|
|
475
|
+
"example": [
|
|
476
|
+
{"id": "gpt-4", "provider": "openai"},
|
|
477
|
+
{"id": "claude-3-sonnet", "provider": "anthropic"},
|
|
478
|
+
]
|
|
479
|
+
}
|
|
480
|
+
},
|
|
481
|
+
}
|
|
482
|
+
},
|
|
352
483
|
)
|
|
353
|
-
async def get_models():
|
|
484
|
+
async def get_models() -> List[Model]:
|
|
354
485
|
"""Return the list of all models used by agents and teams in the contextual OS"""
|
|
355
486
|
all_components: List[Union[Agent, Team]] = []
|
|
356
487
|
if os.agents:
|
|
@@ -371,7 +502,39 @@ def get_base_router(
|
|
|
371
502
|
# -- Agent routes ---
|
|
372
503
|
|
|
373
504
|
@router.post(
|
|
374
|
-
"/agents/{agent_id}/runs",
|
|
505
|
+
"/agents/{agent_id}/runs",
|
|
506
|
+
tags=["Agents"],
|
|
507
|
+
operation_id="create_agent_run",
|
|
508
|
+
response_model_exclude_none=True,
|
|
509
|
+
summary="Create Agent Run",
|
|
510
|
+
description=(
|
|
511
|
+
"Execute an agent with a message and optional media files. Supports both streaming and non-streaming responses.\n\n"
|
|
512
|
+
"**Features:**\n"
|
|
513
|
+
"- Text message input with optional session management\n"
|
|
514
|
+
"- Multi-media support: images (PNG, JPEG, WebP), audio (WAV, MP3), video (MP4, WebM, etc.)\n"
|
|
515
|
+
"- Document processing: PDF, CSV, DOCX, TXT, JSON\n"
|
|
516
|
+
"- Real-time streaming responses with Server-Sent Events (SSE)\n"
|
|
517
|
+
"- User and session context preservation\n\n"
|
|
518
|
+
"**Streaming Response:**\n"
|
|
519
|
+
"When `stream=true`, returns SSE events with `event` and `data` fields."
|
|
520
|
+
),
|
|
521
|
+
responses={
|
|
522
|
+
200: {
|
|
523
|
+
"description": "Agent run executed successfully",
|
|
524
|
+
"content": {
|
|
525
|
+
"text/event-stream": {
|
|
526
|
+
"examples": {
|
|
527
|
+
"event_strea": {
|
|
528
|
+
"summary": "Example event stream response",
|
|
529
|
+
"value": 'event: RunStarted\ndata: {"content": "Hello!", "run_id": "123..."}\n\n',
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
},
|
|
533
|
+
},
|
|
534
|
+
},
|
|
535
|
+
400: {"description": "Invalid request or unsupported file type", "model": BadRequestResponse},
|
|
536
|
+
404: {"description": "Agent not found", "model": NotFoundResponse},
|
|
537
|
+
},
|
|
375
538
|
)
|
|
376
539
|
async def create_agent_run(
|
|
377
540
|
agent_id: str,
|
|
@@ -481,6 +644,16 @@ def get_base_router(
|
|
|
481
644
|
tags=["Agents"],
|
|
482
645
|
operation_id="cancel_agent_run",
|
|
483
646
|
response_model_exclude_none=True,
|
|
647
|
+
summary="Cancel Agent Run",
|
|
648
|
+
description=(
|
|
649
|
+
"Cancel a currently executing agent run. This will attempt to stop the agent's execution gracefully.\n\n"
|
|
650
|
+
"**Note:** Cancellation may not be immediate for all operations."
|
|
651
|
+
),
|
|
652
|
+
responses={
|
|
653
|
+
200: {},
|
|
654
|
+
404: {"description": "Agent not found", "model": NotFoundResponse},
|
|
655
|
+
500: {"description": "Failed to cancel run", "model": InternalServerErrorResponse},
|
|
656
|
+
},
|
|
484
657
|
)
|
|
485
658
|
async def cancel_agent_run(
|
|
486
659
|
agent_id: str,
|
|
@@ -500,6 +673,27 @@ def get_base_router(
|
|
|
500
673
|
tags=["Agents"],
|
|
501
674
|
operation_id="continue_agent_run",
|
|
502
675
|
response_model_exclude_none=True,
|
|
676
|
+
summary="Continue Agent Run",
|
|
677
|
+
description=(
|
|
678
|
+
"Continue a paused or incomplete agent run with updated tool results.\n\n"
|
|
679
|
+
"**Use Cases:**\n"
|
|
680
|
+
"- Resume execution after tool approval/rejection\n"
|
|
681
|
+
"- Provide manual tool execution results\n\n"
|
|
682
|
+
"**Tools Parameter:**\n"
|
|
683
|
+
"JSON string containing array of tool execution objects with results."
|
|
684
|
+
),
|
|
685
|
+
responses={
|
|
686
|
+
200: {
|
|
687
|
+
"description": "Agent run continued successfully",
|
|
688
|
+
"content": {
|
|
689
|
+
"text/event-stream": {
|
|
690
|
+
"example": 'event: RunContent\ndata: {"created_at": 1757348314, "run_id": "123..."}\n\n'
|
|
691
|
+
},
|
|
692
|
+
},
|
|
693
|
+
},
|
|
694
|
+
400: {"description": "Invalid JSON in tools field or invalid tool structure", "model": BadRequestResponse},
|
|
695
|
+
404: {"description": "Agent not found", "model": NotFoundResponse},
|
|
696
|
+
},
|
|
503
697
|
)
|
|
504
698
|
async def continue_agent_run(
|
|
505
699
|
agent_id: str,
|
|
@@ -564,8 +758,39 @@ def get_base_router(
|
|
|
564
758
|
response_model_exclude_none=True,
|
|
565
759
|
tags=["Agents"],
|
|
566
760
|
operation_id="get_agents",
|
|
761
|
+
summary="List All Agents",
|
|
762
|
+
description=(
|
|
763
|
+
"Retrieve a comprehensive list of all agents configured in this OS instance.\n\n"
|
|
764
|
+
"**Returns:**\n"
|
|
765
|
+
"- Agent metadata (ID, name, description)\n"
|
|
766
|
+
"- Model configuration and capabilities\n"
|
|
767
|
+
"- Available tools and their configurations\n"
|
|
768
|
+
"- Session, knowledge, memory, and reasoning settings\n"
|
|
769
|
+
"- Only meaningful (non-default) configurations are included"
|
|
770
|
+
),
|
|
771
|
+
responses={
|
|
772
|
+
200: {
|
|
773
|
+
"description": "List of agents retrieved successfully",
|
|
774
|
+
"content": {
|
|
775
|
+
"application/json": {
|
|
776
|
+
"example": [
|
|
777
|
+
{
|
|
778
|
+
"id": "main-agent",
|
|
779
|
+
"name": "Main Agent",
|
|
780
|
+
"db_id": "c6bf0644-feb8-4930-a305-380dae5ad6aa",
|
|
781
|
+
"model": {"name": "OpenAIChat", "model": "gpt-4o", "provider": "OpenAI"},
|
|
782
|
+
"tools": None,
|
|
783
|
+
"sessions": {"session_table": "agno_sessions"},
|
|
784
|
+
"knowledge": {"knowledge_table": "main_knowledge"},
|
|
785
|
+
"system_message": {"markdown": True, "add_datetime_to_context": True},
|
|
786
|
+
}
|
|
787
|
+
]
|
|
788
|
+
}
|
|
789
|
+
},
|
|
790
|
+
}
|
|
791
|
+
},
|
|
567
792
|
)
|
|
568
|
-
async def get_agents():
|
|
793
|
+
async def get_agents() -> List[AgentResponse]:
|
|
569
794
|
"""Return the list of all Agents present in the contextual OS"""
|
|
570
795
|
if os.agents is None:
|
|
571
796
|
return []
|
|
@@ -582,8 +807,39 @@ def get_base_router(
|
|
|
582
807
|
response_model_exclude_none=True,
|
|
583
808
|
tags=["Agents"],
|
|
584
809
|
operation_id="get_agent",
|
|
810
|
+
summary="Get Agent Details",
|
|
811
|
+
description=(
|
|
812
|
+
"Retrieve detailed configuration and capabilities of a specific agent.\n\n"
|
|
813
|
+
"**Returns comprehensive agent information including:**\n"
|
|
814
|
+
"- Model configuration and provider details\n"
|
|
815
|
+
"- Complete tool inventory and configurations\n"
|
|
816
|
+
"- Session management settings\n"
|
|
817
|
+
"- Knowledge base and memory configurations\n"
|
|
818
|
+
"- Reasoning capabilities and settings\n"
|
|
819
|
+
"- System prompts and response formatting options"
|
|
820
|
+
),
|
|
821
|
+
responses={
|
|
822
|
+
200: {
|
|
823
|
+
"description": "Agent details retrieved successfully",
|
|
824
|
+
"content": {
|
|
825
|
+
"application/json": {
|
|
826
|
+
"example": {
|
|
827
|
+
"id": "main-agent",
|
|
828
|
+
"name": "Main Agent",
|
|
829
|
+
"db_id": "9e064c70-6821-4840-a333-ce6230908a70",
|
|
830
|
+
"model": {"name": "OpenAIChat", "model": "gpt-4o", "provider": "OpenAI"},
|
|
831
|
+
"tools": None,
|
|
832
|
+
"sessions": {"session_table": "agno_sessions"},
|
|
833
|
+
"knowledge": {"knowledge_table": "main_knowledge"},
|
|
834
|
+
"system_message": {"markdown": True, "add_datetime_to_context": True},
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
},
|
|
838
|
+
},
|
|
839
|
+
404: {"description": "Agent not found", "model": NotFoundResponse},
|
|
840
|
+
},
|
|
585
841
|
)
|
|
586
|
-
async def get_agent(agent_id: str):
|
|
842
|
+
async def get_agent(agent_id: str) -> AgentResponse:
|
|
587
843
|
agent = get_agent_by_id(agent_id, os.agents)
|
|
588
844
|
if agent is None:
|
|
589
845
|
raise HTTPException(status_code=404, detail="Agent not found")
|
|
@@ -593,7 +849,34 @@ def get_base_router(
|
|
|
593
849
|
# -- Team routes ---
|
|
594
850
|
|
|
595
851
|
@router.post(
|
|
596
|
-
"/teams/{team_id}/runs",
|
|
852
|
+
"/teams/{team_id}/runs",
|
|
853
|
+
tags=["Teams"],
|
|
854
|
+
operation_id="create_team_run",
|
|
855
|
+
response_model_exclude_none=True,
|
|
856
|
+
summary="Create Team Run",
|
|
857
|
+
description=(
|
|
858
|
+
"Execute a team collaboration with multiple agents working together on a task.\n\n"
|
|
859
|
+
"**Features:**\n"
|
|
860
|
+
"- Text message input with optional session management\n"
|
|
861
|
+
"- Multi-media support: images (PNG, JPEG, WebP), audio (WAV, MP3), video (MP4, WebM, etc.)\n"
|
|
862
|
+
"- Document processing: PDF, CSV, DOCX, TXT, JSON\n"
|
|
863
|
+
"- Real-time streaming responses with Server-Sent Events (SSE)\n"
|
|
864
|
+
"- User and session context preservation\n\n"
|
|
865
|
+
"**Streaming Response:**\n"
|
|
866
|
+
"When `stream=true`, returns SSE events with `event` and `data` fields."
|
|
867
|
+
),
|
|
868
|
+
responses={
|
|
869
|
+
200: {
|
|
870
|
+
"description": "Team run executed successfully",
|
|
871
|
+
"content": {
|
|
872
|
+
"text/event-stream": {
|
|
873
|
+
"example": 'event: RunStarted\ndata: {"content": "Hello!", "run_id": "123..."}\n\n'
|
|
874
|
+
},
|
|
875
|
+
},
|
|
876
|
+
},
|
|
877
|
+
400: {"description": "Invalid request or unsupported file type", "model": BadRequestResponse},
|
|
878
|
+
404: {"description": "Team not found", "model": NotFoundResponse},
|
|
879
|
+
},
|
|
597
880
|
)
|
|
598
881
|
async def create_team_run(
|
|
599
882
|
team_id: str,
|
|
@@ -700,6 +983,16 @@ def get_base_router(
|
|
|
700
983
|
tags=["Teams"],
|
|
701
984
|
operation_id="cancel_team_run",
|
|
702
985
|
response_model_exclude_none=True,
|
|
986
|
+
summary="Cancel Team Run",
|
|
987
|
+
description=(
|
|
988
|
+
"Cancel a currently executing team run. This will attempt to stop the team's execution gracefully.\n\n"
|
|
989
|
+
"**Note:** Cancellation may not be immediate for all operations."
|
|
990
|
+
),
|
|
991
|
+
responses={
|
|
992
|
+
200: {},
|
|
993
|
+
404: {"description": "Team not found", "model": NotFoundResponse},
|
|
994
|
+
500: {"description": "Failed to cancel team run", "model": InternalServerErrorResponse},
|
|
995
|
+
},
|
|
703
996
|
)
|
|
704
997
|
async def cancel_team_run(
|
|
705
998
|
team_id: str,
|
|
@@ -720,8 +1013,82 @@ def get_base_router(
|
|
|
720
1013
|
response_model_exclude_none=True,
|
|
721
1014
|
tags=["Teams"],
|
|
722
1015
|
operation_id="get_teams",
|
|
1016
|
+
summary="List All Teams",
|
|
1017
|
+
description=(
|
|
1018
|
+
"Retrieve a comprehensive list of all teams configured in this OS instance.\n\n"
|
|
1019
|
+
"**Returns team information including:**\n"
|
|
1020
|
+
"- Team metadata (ID, name, description, execution mode)\n"
|
|
1021
|
+
"- Model configuration for team coordination\n"
|
|
1022
|
+
"- Team member roster with roles and capabilities\n"
|
|
1023
|
+
"- Knowledge sharing and memory configurations"
|
|
1024
|
+
),
|
|
1025
|
+
responses={
|
|
1026
|
+
200: {
|
|
1027
|
+
"description": "List of teams retrieved successfully",
|
|
1028
|
+
"content": {
|
|
1029
|
+
"application/json": {
|
|
1030
|
+
"example": [
|
|
1031
|
+
{
|
|
1032
|
+
"team_id": "basic-team",
|
|
1033
|
+
"name": "Basic Team",
|
|
1034
|
+
"mode": "coordinate",
|
|
1035
|
+
"model": {"name": "OpenAIChat", "model": "gpt-4o", "provider": "OpenAI"},
|
|
1036
|
+
"tools": [
|
|
1037
|
+
{
|
|
1038
|
+
"name": "transfer_task_to_member",
|
|
1039
|
+
"description": "Use this function to transfer a task to the selected team member.\nYou must provide a clear and concise description of the task the member should achieve AND the expected output.",
|
|
1040
|
+
"parameters": {
|
|
1041
|
+
"type": "object",
|
|
1042
|
+
"properties": {
|
|
1043
|
+
"member_id": {
|
|
1044
|
+
"type": "string",
|
|
1045
|
+
"description": "(str) The ID of the member to transfer the task to. Use only the ID of the member, not the ID of the team followed by the ID of the member.",
|
|
1046
|
+
},
|
|
1047
|
+
"task_description": {
|
|
1048
|
+
"type": "string",
|
|
1049
|
+
"description": "(str) A clear and concise description of the task the member should achieve.",
|
|
1050
|
+
},
|
|
1051
|
+
"expected_output": {
|
|
1052
|
+
"type": "string",
|
|
1053
|
+
"description": "(str) The expected output from the member (optional).",
|
|
1054
|
+
},
|
|
1055
|
+
},
|
|
1056
|
+
"additionalProperties": False,
|
|
1057
|
+
"required": ["member_id", "task_description"],
|
|
1058
|
+
},
|
|
1059
|
+
}
|
|
1060
|
+
],
|
|
1061
|
+
"members": [
|
|
1062
|
+
{
|
|
1063
|
+
"agent_id": "basic-agent",
|
|
1064
|
+
"name": "Basic Agent",
|
|
1065
|
+
"model": {"name": "OpenAIChat", "model": "gpt-4o", "provider": "OpenAI gpt-4o"},
|
|
1066
|
+
"memory": {
|
|
1067
|
+
"app_name": "Memory",
|
|
1068
|
+
"app_url": None,
|
|
1069
|
+
"model": {"name": "OpenAIChat", "model": "gpt-4o", "provider": "OpenAI"},
|
|
1070
|
+
},
|
|
1071
|
+
"session_table": "agno_sessions",
|
|
1072
|
+
"memory_table": "agno_memories",
|
|
1073
|
+
}
|
|
1074
|
+
],
|
|
1075
|
+
"enable_agentic_context": False,
|
|
1076
|
+
"memory": {
|
|
1077
|
+
"app_name": "agno_memories",
|
|
1078
|
+
"app_url": "/memory/1",
|
|
1079
|
+
"model": {"name": "OpenAIChat", "model": "gpt-4o", "provider": "OpenAI"},
|
|
1080
|
+
},
|
|
1081
|
+
"async_mode": False,
|
|
1082
|
+
"session_table": "agno_sessions",
|
|
1083
|
+
"memory_table": "agno_memories",
|
|
1084
|
+
}
|
|
1085
|
+
]
|
|
1086
|
+
}
|
|
1087
|
+
},
|
|
1088
|
+
}
|
|
1089
|
+
},
|
|
723
1090
|
)
|
|
724
|
-
async def get_teams():
|
|
1091
|
+
async def get_teams() -> List[TeamResponse]:
|
|
725
1092
|
"""Return the list of all Teams present in the contextual OS"""
|
|
726
1093
|
if os.teams is None:
|
|
727
1094
|
return []
|
|
@@ -738,8 +1105,85 @@ def get_base_router(
|
|
|
738
1105
|
response_model_exclude_none=True,
|
|
739
1106
|
tags=["Teams"],
|
|
740
1107
|
operation_id="get_team",
|
|
1108
|
+
summary="Get Team Details",
|
|
1109
|
+
description=("Retrieve detailed configuration and member information for a specific team."),
|
|
1110
|
+
responses={
|
|
1111
|
+
200: {
|
|
1112
|
+
"description": "Team details retrieved successfully",
|
|
1113
|
+
"content": {
|
|
1114
|
+
"application/json": {
|
|
1115
|
+
"example": {
|
|
1116
|
+
"team_id": "basic-team",
|
|
1117
|
+
"name": "Basic Team",
|
|
1118
|
+
"description": None,
|
|
1119
|
+
"mode": "coordinate",
|
|
1120
|
+
"model": {"name": "OpenAIChat", "model": "gpt-4o", "provider": "OpenAI"},
|
|
1121
|
+
"tools": [
|
|
1122
|
+
{
|
|
1123
|
+
"name": "transfer_task_to_member",
|
|
1124
|
+
"description": "Use this function to transfer a task to the selected team member.\nYou must provide a clear and concise description of the task the member should achieve AND the expected output.",
|
|
1125
|
+
"parameters": {
|
|
1126
|
+
"type": "object",
|
|
1127
|
+
"properties": {
|
|
1128
|
+
"member_id": {
|
|
1129
|
+
"type": "string",
|
|
1130
|
+
"description": "(str) The ID of the member to transfer the task to. Use only the ID of the member, not the ID of the team followed by the ID of the member.",
|
|
1131
|
+
},
|
|
1132
|
+
"task_description": {
|
|
1133
|
+
"type": "string",
|
|
1134
|
+
"description": "(str) A clear and concise description of the task the member should achieve.",
|
|
1135
|
+
},
|
|
1136
|
+
"expected_output": {
|
|
1137
|
+
"type": "string",
|
|
1138
|
+
"description": "(str) The expected output from the member (optional).",
|
|
1139
|
+
},
|
|
1140
|
+
},
|
|
1141
|
+
"additionalProperties": False,
|
|
1142
|
+
"required": ["member_id", "task_description"],
|
|
1143
|
+
},
|
|
1144
|
+
}
|
|
1145
|
+
],
|
|
1146
|
+
"instructions": None,
|
|
1147
|
+
"members": [
|
|
1148
|
+
{
|
|
1149
|
+
"agent_id": "basic-agent",
|
|
1150
|
+
"name": "Basic Agent",
|
|
1151
|
+
"description": None,
|
|
1152
|
+
"instructions": None,
|
|
1153
|
+
"model": {"name": "OpenAIChat", "model": "gpt-4o", "provider": "OpenAI gpt-4o"},
|
|
1154
|
+
"tools": None,
|
|
1155
|
+
"memory": {
|
|
1156
|
+
"app_name": "Memory",
|
|
1157
|
+
"app_url": None,
|
|
1158
|
+
"model": {"name": "OpenAIChat", "model": "gpt-4o", "provider": "OpenAI"},
|
|
1159
|
+
},
|
|
1160
|
+
"knowledge": None,
|
|
1161
|
+
"session_table": "agno_sessions",
|
|
1162
|
+
"memory_table": "agno_memories",
|
|
1163
|
+
"knowledge_table": None,
|
|
1164
|
+
}
|
|
1165
|
+
],
|
|
1166
|
+
"expected_output": None,
|
|
1167
|
+
"dependencies": None,
|
|
1168
|
+
"enable_agentic_context": False,
|
|
1169
|
+
"memory": {
|
|
1170
|
+
"app_name": "Memory",
|
|
1171
|
+
"app_url": None,
|
|
1172
|
+
"model": {"name": "OpenAIChat", "model": "gpt-4o", "provider": "OpenAI"},
|
|
1173
|
+
},
|
|
1174
|
+
"knowledge": None,
|
|
1175
|
+
"async_mode": False,
|
|
1176
|
+
"session_table": "agno_sessions",
|
|
1177
|
+
"memory_table": "agno_memories",
|
|
1178
|
+
"knowledge_table": None,
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
},
|
|
1182
|
+
},
|
|
1183
|
+
404: {"description": "Team not found", "model": NotFoundResponse},
|
|
1184
|
+
},
|
|
741
1185
|
)
|
|
742
|
-
async def get_team(team_id: str):
|
|
1186
|
+
async def get_team(team_id: str) -> TeamResponse:
|
|
743
1187
|
team = get_team_by_id(team_id, os.teams)
|
|
744
1188
|
if team is None:
|
|
745
1189
|
raise HTTPException(status_code=404, detail="Team not found")
|
|
@@ -748,7 +1192,10 @@ def get_base_router(
|
|
|
748
1192
|
|
|
749
1193
|
# -- Workflow routes ---
|
|
750
1194
|
|
|
751
|
-
@router.websocket(
|
|
1195
|
+
@router.websocket(
|
|
1196
|
+
"/workflows/ws",
|
|
1197
|
+
name="workflow_websocket",
|
|
1198
|
+
)
|
|
752
1199
|
async def workflow_websocket_endpoint(websocket: WebSocket):
|
|
753
1200
|
"""WebSocket endpoint for receiving real-time workflow events"""
|
|
754
1201
|
await websocket_manager.connect(websocket)
|
|
@@ -776,12 +1223,38 @@ def get_base_router(
|
|
|
776
1223
|
|
|
777
1224
|
@router.get(
|
|
778
1225
|
"/workflows",
|
|
779
|
-
response_model=List[
|
|
1226
|
+
response_model=List[WorkflowSummaryResponse],
|
|
780
1227
|
response_model_exclude_none=True,
|
|
781
1228
|
tags=["Workflows"],
|
|
782
1229
|
operation_id="get_workflows",
|
|
1230
|
+
summary="List All Workflows",
|
|
1231
|
+
description=(
|
|
1232
|
+
"Retrieve a comprehensive list of all workflows configured in this OS instance.\n\n"
|
|
1233
|
+
"**Return Information:**\n"
|
|
1234
|
+
"- Workflow metadata (ID, name, description)\n"
|
|
1235
|
+
"- Input schema requirements\n"
|
|
1236
|
+
"- Step sequence and execution flow\n"
|
|
1237
|
+
"- Associated agents and teams"
|
|
1238
|
+
),
|
|
1239
|
+
responses={
|
|
1240
|
+
200: {
|
|
1241
|
+
"description": "List of workflows retrieved successfully",
|
|
1242
|
+
"content": {
|
|
1243
|
+
"application/json": {
|
|
1244
|
+
"example": [
|
|
1245
|
+
{
|
|
1246
|
+
"id": "content-creation-workflow",
|
|
1247
|
+
"name": "Content Creation Workflow",
|
|
1248
|
+
"description": "Automated content creation from blog posts to social media",
|
|
1249
|
+
"db_id": "123",
|
|
1250
|
+
}
|
|
1251
|
+
]
|
|
1252
|
+
}
|
|
1253
|
+
},
|
|
1254
|
+
}
|
|
1255
|
+
},
|
|
783
1256
|
)
|
|
784
|
-
async def get_workflows():
|
|
1257
|
+
async def get_workflows() -> List[WorkflowSummaryResponse]:
|
|
785
1258
|
if os.workflows is None:
|
|
786
1259
|
return []
|
|
787
1260
|
|
|
@@ -793,8 +1266,26 @@ def get_base_router(
|
|
|
793
1266
|
response_model_exclude_none=True,
|
|
794
1267
|
tags=["Workflows"],
|
|
795
1268
|
operation_id="get_workflow",
|
|
1269
|
+
summary="Get Workflow Details",
|
|
1270
|
+
description=("Retrieve detailed configuration and step information for a specific workflow."),
|
|
1271
|
+
responses={
|
|
1272
|
+
200: {
|
|
1273
|
+
"description": "Workflow details retrieved successfully",
|
|
1274
|
+
"content": {
|
|
1275
|
+
"application/json": {
|
|
1276
|
+
"example": {
|
|
1277
|
+
"id": "content-creation-workflow",
|
|
1278
|
+
"name": "Content Creation Workflow",
|
|
1279
|
+
"description": "Automated content creation from blog posts to social media",
|
|
1280
|
+
"db_id": "123",
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
},
|
|
1284
|
+
},
|
|
1285
|
+
404: {"description": "Workflow not found", "model": NotFoundResponse},
|
|
1286
|
+
},
|
|
796
1287
|
)
|
|
797
|
-
async def get_workflow(workflow_id: str):
|
|
1288
|
+
async def get_workflow(workflow_id: str) -> WorkflowResponse:
|
|
798
1289
|
workflow = get_workflow_by_id(workflow_id, os.workflows)
|
|
799
1290
|
if workflow is None:
|
|
800
1291
|
raise HTTPException(status_code=404, detail="Workflow not found")
|
|
@@ -806,6 +1297,34 @@ def get_base_router(
|
|
|
806
1297
|
tags=["Workflows"],
|
|
807
1298
|
operation_id="create_workflow_run",
|
|
808
1299
|
response_model_exclude_none=True,
|
|
1300
|
+
summary="Execute Workflow",
|
|
1301
|
+
description=(
|
|
1302
|
+
"Execute a workflow with the provided input data. Workflows can run in streaming or batch mode.\n\n"
|
|
1303
|
+
"**Execution Modes:**\n"
|
|
1304
|
+
"- **Streaming (`stream=true`)**: Real-time step-by-step execution updates via SSE\n"
|
|
1305
|
+
"- **Non-Streaming (`stream=false`)**: Complete workflow execution with final result\n\n"
|
|
1306
|
+
"**Workflow Execution Process:**\n"
|
|
1307
|
+
"1. Input validation against workflow schema\n"
|
|
1308
|
+
"2. Sequential or parallel step execution based on workflow design\n"
|
|
1309
|
+
"3. Data flow between steps with transformation\n"
|
|
1310
|
+
"4. Error handling and automatic retries where configured\n"
|
|
1311
|
+
"5. Final result compilation and response\n\n"
|
|
1312
|
+
"**Session Management:**\n"
|
|
1313
|
+
"Workflows support session continuity for stateful execution across multiple runs."
|
|
1314
|
+
),
|
|
1315
|
+
responses={
|
|
1316
|
+
200: {
|
|
1317
|
+
"description": "Workflow executed successfully",
|
|
1318
|
+
"content": {
|
|
1319
|
+
"text/event-stream": {
|
|
1320
|
+
"example": 'event: RunStarted\ndata: {"content": "Hello!", "run_id": "123..."}\n\n'
|
|
1321
|
+
},
|
|
1322
|
+
},
|
|
1323
|
+
},
|
|
1324
|
+
400: {"description": "Invalid input data or workflow configuration", "model": BadRequestResponse},
|
|
1325
|
+
404: {"description": "Workflow not found", "model": NotFoundResponse},
|
|
1326
|
+
500: {"description": "Workflow execution error", "model": InternalServerErrorResponse},
|
|
1327
|
+
},
|
|
809
1328
|
)
|
|
810
1329
|
async def create_workflow_run(
|
|
811
1330
|
workflow_id: str,
|
|
@@ -853,7 +1372,19 @@ def get_base_router(
|
|
|
853
1372
|
raise HTTPException(status_code=500, detail=f"Error running workflow: {str(e)}")
|
|
854
1373
|
|
|
855
1374
|
@router.post(
|
|
856
|
-
"/workflows/{workflow_id}/runs/{run_id}/cancel",
|
|
1375
|
+
"/workflows/{workflow_id}/runs/{run_id}/cancel",
|
|
1376
|
+
tags=["Workflows"],
|
|
1377
|
+
operation_id="cancel_workflow_run",
|
|
1378
|
+
summary="Cancel Workflow Run",
|
|
1379
|
+
description=(
|
|
1380
|
+
"Cancel a currently executing workflow run, stopping all active steps and cleanup.\n"
|
|
1381
|
+
"**Note:** Complex workflows with multiple parallel steps may take time to fully cancel."
|
|
1382
|
+
),
|
|
1383
|
+
responses={
|
|
1384
|
+
200: {},
|
|
1385
|
+
404: {"description": "Workflow or run not found", "model": NotFoundResponse},
|
|
1386
|
+
500: {"description": "Failed to cancel workflow run", "model": InternalServerErrorResponse},
|
|
1387
|
+
},
|
|
857
1388
|
)
|
|
858
1389
|
async def cancel_workflow_run(workflow_id: str, run_id: str):
|
|
859
1390
|
workflow = get_workflow_by_id(workflow_id, os.workflows)
|