Core API¶
The core module contains the main classes for building and running agents.
Zap¶
The main orchestrator class that manages agents and Temporal connections.
zap_ai.Zap
dataclass
¶
Bases: Generic[TContext]
Main orchestrator for the Zap AI agent platform.
Zap manages a collection of agents and provides methods to execute tasks against them. It supports a generic context type that can be passed to agents with dynamic prompts. It handles: - Agent configuration validation at build time - Temporal client connection management - Task execution via Temporal workflows - Task status queries
Example
from zap_ai import Zap, ZapAgent
# Simple usage with static prompts
agents = [
ZapAgent(name="MainAgent", prompt="You are helpful..."),
ZapAgent(name="HelperAgent", prompt="You assist with..."),
]
zap = Zap(agents=agents)
await zap.start()
task = await zap.execute_task(
agent_name="MainAgent",
task="Help me with something",
)
# With typed context and dynamic prompts
from dataclasses import dataclass
@dataclass
class MyContext:
user_name: str
company: str
agent = ZapAgent[MyContext](
name="Helper",
prompt=lambda ctx: f"You assist {ctx.user_name} from {ctx.company}.",
)
zap: Zap[MyContext] = Zap(agents=[agent])
await zap.start()
task = await zap.execute_task(
agent_name="Helper",
task="Help me with something",
context=MyContext(user_name="Alice", company="Acme"),
)
Attributes:
| Name | Type | Description |
|---|---|---|
agents |
list[ZapAgent[TContext]]
|
List of ZapAgent configurations. Validated at instantiation. |
temporal_client |
Client | None
|
Optional pre-configured Temporal client. If None, a default connection to localhost:7233 is created in start(). |
task_queue |
str
|
Temporal task queue name for agent workflows. Default is "zap-agents". |
Source code in src/zap_ai/core/zap.py
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 | |
start()
async
¶
Initialize Temporal connection and MCP clients.
Must be called before execute_task() or get_task(). This method: 1. Connects to Temporal (if client not provided) 2. Initializes the tool registry 3. Pre-connects all MCP clients and discovers tools
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If start() has already been called. |
ConnectionError
|
If Temporal connection fails. |
Example
zap = Zap(agents=[...])
await zap.start() # Must call before using
Source code in src/zap_ai/core/zap.py
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | |
stop()
async
¶
Gracefully shut down Zap.
Disconnects MCP clients and closes Temporal connection. Does not cancel running tasks.
Source code in src/zap_ai/core/zap.py
825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 | |
execute_task(agent_name=None, task=None, task_content=None, follow_up_on_task=None, context=None, approval_rules=None)
async
¶
Execute a new task or follow up on an existing one.
For new tasks, starts a Temporal workflow for the specified agent. For follow-ups, sends a signal to the existing workflow.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent_name
|
str | None
|
Name of the agent to execute the task. Required for new tasks, ignored for follow-ups (uses original agent). |
None
|
task
|
str | None
|
The task description/prompt to send to the agent (text only). Either task or task_content is required. |
None
|
task_content
|
MessageContent | None
|
Multimodal task content (text + images). If provided,
takes precedence over |
None
|
follow_up_on_task
|
str | None
|
If provided, sends the task as a follow-up message to an existing task instead of starting a new one. |
None
|
context
|
TContext | None
|
Optional context to pass to agents with dynamic prompts
and MCP tools. For dynamic prompts, this is used to resolve
the prompt at runtime. For MCP tools, this is passed via the
|
None
|
approval_rules
|
'ApprovalRules | None'
|
Optional rules for human-in-the-loop approval. When provided, tool calls matching the patterns will pause for human approval before execution. |
None
|
Returns:
| Type | Description |
|---|---|
Task
|
Task object with initial state. Use get_task() to poll for updates. |
Raises:
| Type | Description |
|---|---|
ZapNotStartedError
|
If start() hasn't been called. |
AgentNotFoundError
|
If agent_name doesn't exist (new tasks only). |
TaskNotFoundError
|
If follow_up_on_task doesn't exist. |
VisionNotSupportedError
|
If task contains images but model doesn't support vision. |
ValueError
|
If required arguments are missing. |
Example (new task):
task = await zap.execute_task(
agent_name="MyAgent",
task="Analyze this data and summarize findings",
)
Example (with images - multimodal):
from zap_ai import TextContent, ImageContent
task = await zap.execute_task(
agent_name="VisionAgent",
task_content=[
TextContent(text="What's in this image?"),
ImageContent.from_url("https://example.com/photo.jpg"),
],
)
Example (with context):
task = await zap.execute_task(
agent_name="Helper",
task="Help me with something",
context=MyContext(user_name="Alice", company="Acme"),
)
Example (with approval rules):
from zap_ai import ApprovalRules
task = await zap.execute_task(
agent_name="FinancialAgent",
task="Transfer $50,000 to vendor",
approval_rules=ApprovalRules(patterns=["transfer_*", "delete_*"]),
)
# Later, check for pending approvals
pending = await task.get_pending_approvals()
await task.approve(pending[0].id)
Example (follow-up):
task = await zap.execute_task(
follow_up_on_task=task.id,
task="Now export the summary to PDF",
)
Source code in src/zap_ai/core/zap.py
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 | |
stream_task(agent_name=None, task=None, task_content=None, context=None, approval_rules=None, *, poll_interval=0.1, include_thinking=True, include_tool_events=True)
async
¶
Execute a task and stream events as an async generator.
This method starts a task and yields streaming events as they occur, allowing real-time progress monitoring. Events are polled from the workflow via Temporal queries at the specified interval.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent_name
|
str | None
|
Name of the agent to execute the task. |
None
|
task
|
str | None
|
The task description/prompt (text only). |
None
|
task_content
|
MessageContent | None
|
Multimodal task content (text + images). |
None
|
context
|
TContext | None
|
Optional context for agents with dynamic prompts. |
None
|
approval_rules
|
'ApprovalRules | None'
|
Optional rules for human-in-the-loop approval. |
None
|
poll_interval
|
float
|
How often to poll for new events (seconds). Default 0.1. |
0.1
|
include_thinking
|
bool
|
Whether to yield ThinkingEvent. Default True. |
True
|
include_tool_events
|
bool
|
Whether to yield ToolCallEvent and ToolResultEvent. Default True. |
True
|
Yields:
| Type | Description |
|---|---|
'AsyncIterator[Event]'
|
Event objects in order: ThinkingEvent, ToolCallEvent, ToolResultEvent, |
'AsyncIterator[Event]'
|
and finally CompletedEvent or ErrorEvent. |
Raises:
| Type | Description |
|---|---|
ZapNotStartedError
|
If start() hasn't been called. |
AgentNotFoundError
|
If agent_name doesn't exist. |
VisionNotSupportedError
|
If task contains images but model doesn't support vision. |
ValueError
|
If required arguments are missing. |
Example
async for event in zap.stream_task(
agent_name="MainAgent",
task="What's the weather in Paris?"
):
match event:
case ThinkingEvent(iteration=n):
print(f"Thinking (iteration {n})...")
case ToolCallEvent(phrase=phrase):
print(phrase) # "Getting weather for Paris..."
case ToolResultEvent(name=name, success=success):
print(f"Tool {name}: {'OK' if success else 'FAILED'}")
case CompletedEvent(result=result):
print(f"Done: {result}")
case ErrorEvent(error=error):
print(f"Error: {error}")
Source code in src/zap_ai/core/zap.py
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 | |
get_task(task_id)
async
¶
Get the current state of a task.
Queries the Temporal workflow for current status, result, conversation history, and sub-task information.
The returned Task object includes:
- Full conversation history via task.history
- Sub-task IDs via task.sub_tasks
- Ability to fetch sub-task Task objects via await task.get_sub_tasks()
- Convenience methods: get_text_content(), get_tool_calls(),
get_turn(), get_turns(), turn_count()
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
task_id
|
str
|
The task ID returned from execute_task(). |
required |
Returns:
| Type | Description |
|---|---|
Task
|
Task object with current state and conversation access. |
Raises:
| Type | Description |
|---|---|
ZapNotStartedError
|
If start() hasn't been called. |
TaskNotFoundError
|
If no task with that ID exists. |
Example
task = await zap.get_task(task_id)
print(f"Status: {task.status}")
if task.is_complete():
print(f"Result: {task.result}")
# Access conversation
print(task.get_text_content())
for tool_call in task.get_tool_calls():
print(f"Called: {tool_call.name}")
# Access sub-tasks
sub_tasks = await task.get_sub_tasks()
for sub in sub_tasks:
print(f"Sub-task: {sub.id}")
Source code in src/zap_ai/core/zap.py
728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 | |
get_agent(name)
¶
Get an agent by name.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
The agent name to look up. |
required |
Returns:
| Type | Description |
|---|---|
ZapAgent[TContext]
|
The ZapAgent with the given name. |
Raises:
| Type | Description |
|---|---|
AgentNotFoundError
|
If no agent with that name exists. |
Source code in src/zap_ai/core/zap.py
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | |
get_agent_tools(agent_name)
async
¶
Get list of tool names available to an agent.
Useful for validating approval patterns before execution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
agent_name
|
str
|
Name of the agent. |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
List of tool names available to the agent. |
Raises:
| Type | Description |
|---|---|
ZapNotStartedError
|
If start() hasn't been called. |
AgentNotFoundError
|
If agent doesn't exist. |
Example
tools = await zap.get_agent_tools("financial_agent")
# ['transfer_funds', 'check_balance', 'delete_transaction']
# Validate approval patterns
rules = ApprovalRules(patterns=["transfer_*"])
print(rules.preview_matches(tools))
# {'transfer_*': ['transfer_funds']}
Source code in src/zap_ai/core/zap.py
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | |
ZapAgent¶
Configuration for an AI agent.
zap_ai.ZapAgent
¶
Bases: BaseModel, Generic[TContext]
Configuration for an AI agent within the Zap platform.
ZapAgent defines all the properties needed to run an agent, including its system prompt (static or dynamic), LLM model, available tools (via MCP clients), and which other agents it can delegate to.
The prompt can be either: - A static string: "You are a helpful assistant." - A callable that receives context: lambda ctx: f"You assist {ctx['user_name']}."
Example
from zap_ai import ZapAgent
from fastmcp import Client
# Static prompt
agent = ZapAgent(
name="ResearchAgent",
prompt="You are a research assistant...",
model="gpt-4o",
mcp_clients=[Client("./tools.py")],
sub_agents=["WriterAgent"],
)
# Dynamic prompt with context
agent = ZapAgent[MyContext](
name="PersonalAgent",
prompt=lambda ctx: f"You are {ctx.user_name}'s assistant.",
)
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Unique identifier for the agent. Used as workflow ID prefix. Cannot contain spaces or special characters that would be invalid in a Temporal workflow ID. |
prompt |
str | Callable[[Any], str]
|
System prompt that defines the agent's behavior and personality. Can be a string or a callable that takes context and returns a string. This is sent as the first message in every conversation. |
model |
str
|
LiteLLM model identifier (e.g., "gpt-4o", "claude-3-opus-20240229", "anthropic/claude-3-sonnet"). See LiteLLM docs for full list. |
mcp_clients |
list[Any]
|
List of FastMCP Client instances that provide tools to this agent. Clients are connected during Zap.start(). |
sub_agents |
list[str]
|
List of agent names that this agent can delegate to. A special "message_agent" tool is automatically added when this list is non-empty. Referenced agents must exist in the Zap instance. |
discovery_prompt |
str | None
|
Description shown to parent agents when they can delegate to this agent. Used in the message_agent tool description. If None, agent won't appear in transfer tool options. |
max_iterations |
int
|
Maximum number of agentic loop iterations before forcing completion. Prevents infinite loops. Each iteration is one LLM call + optional tool execution. |
temperature |
float
|
Sampling temperature for LLM responses (0.0-2.0). Lower values (e.g., 0.2) make output more focused and deterministic. Higher values (e.g., 0.8) make output more random and creative. Defaults to 0.7. |
max_tokens |
int | None
|
Maximum number of tokens to generate in the response. If None (default), uses the model's default limit. |
Source code in src/zap_ai/core/agent.py
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | |
is_dynamic_prompt()
¶
Check if this agent uses a dynamic (callable) prompt.
Source code in src/zap_ai/core/agent.py
183 184 185 | |
resolve_prompt(context)
¶
Resolve the prompt with the given context.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
context
|
TContext
|
The context to pass to a dynamic prompt. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The resolved system prompt string. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If prompt resolution fails. |
Source code in src/zap_ai/core/agent.py
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | |
Task¶
Represents a task execution.
zap_ai.Task
dataclass
¶
Represents a task execution within the Zap platform.
A Task is created when you call zap.execute_task() and tracks the
full lifecycle of that execution. Use zap.get_task(task_id) to
retrieve updated task state.
Example
task = await zap.execute_task(agent_name="MyAgent", task="Do something")
print(f"Task ID: {task.id}")
# Poll for completion
while not task.status.is_terminal():
await asyncio.sleep(1)
task = await zap.get_task(task.id)
if task.status == TaskStatus.COMPLETED:
print(f"Result: {task.result}")
else:
print(f"Failed: {task.error}")
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
Unique identifier for this task. Format: "{agent_name}-{uuid}". Used as the Temporal workflow ID. |
agent_name |
str
|
Name of the agent executing this task. |
status |
TaskStatus
|
Current execution status. See TaskStatus for details. |
result |
str | None
|
Final result string if completed, None otherwise. |
history |
list[dict[str, Any]]
|
List of conversation messages in LiteLLM format. Each message is a dict with "role" and "content" keys. May include tool calls and tool results. |
sub_tasks |
list[str]
|
List of child task IDs spawned for sub-agent delegation. |
error |
str | None
|
Error message if failed, None otherwise. |
created_at |
datetime
|
Timestamp when task was created. |
updated_at |
datetime
|
Timestamp of last status update. |
Source code in src/zap_ai/core/task.py
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | |
is_complete()
¶
Return True if task has reached a terminal state.
Source code in src/zap_ai/core/task.py
131 132 133 | |
is_successful()
¶
Return True if task completed successfully.
Source code in src/zap_ai/core/task.py
135 136 137 | |
get_last_message()
¶
Return the most recent message in history, or None if empty.
Source code in src/zap_ai/core/task.py
139 140 141 142 143 | |
get_assistant_messages()
¶
Return all assistant messages from history.
Source code in src/zap_ai/core/task.py
145 146 147 | |
get_tool_calls_count()
¶
Return total number of tool calls made during this task.
Source code in src/zap_ai/core/task.py
149 150 151 152 153 154 155 | |
get_text_content()
¶
Extract all text content from conversation history.
Returns concatenated text from user and assistant messages, excluding tool calls and tool results.
Returns:
| Type | Description |
|---|---|
str
|
Combined text content as a single string, with messages |
str
|
separated by double newlines. |
Source code in src/zap_ai/core/task.py
157 158 159 160 161 162 163 164 165 166 167 168 169 170 | |
get_tool_calls()
¶
Get all tool calls with their results.
Returns:
| Type | Description |
|---|---|
list['ToolCallInfo']
|
List of ToolCallInfo objects containing tool name, arguments, |
list['ToolCallInfo']
|
and results (if available). |
Source code in src/zap_ai/core/task.py
172 173 174 175 176 177 178 179 180 181 182 | |
get_turns()
¶
Get all conversation turns.
A turn is defined as a user message (or system prompt for turn 0), followed by all assistant responses and tool interactions until the next user message.
Returns:
| Type | Description |
|---|---|
list['ConversationTurn']
|
List of ConversationTurn objects, one per turn. |
Source code in src/zap_ai/core/task.py
184 185 186 187 188 189 190 191 192 193 194 195 196 197 | |
get_turn(turn_num)
¶
Get messages for a specific conversation turn.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
turn_num
|
int
|
Turn number (0-indexed). Turn 0 may contain system prompt. |
required |
Returns:
| Type | Description |
|---|---|
'ConversationTurn | None'
|
ConversationTurn with the turn's messages, or None if turn doesn't exist. |
Source code in src/zap_ai/core/task.py
199 200 201 202 203 204 205 206 207 208 209 210 211 | |
turn_count()
¶
Return the number of conversation turns.
Source code in src/zap_ai/core/task.py
213 214 215 216 217 | |
get_sub_tasks()
async
¶
Fetch full Task objects for all sub-tasks.
This method requires the Task to have been created via zap.get_task(),
which injects the necessary callback for fetching sub-task data.
Returns:
| Type | Description |
|---|---|
list['Task']
|
List of Task objects for each sub-task spawned by this task. |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If Task was not created via Zap.get_task(). |
Example
task = await zap.get_task(task_id)
sub_tasks = await task.get_sub_tasks()
for sub in sub_tasks:
print(f"Sub-task {sub.id}: {sub.status}")
Source code in src/zap_ai/core/task.py
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | |
get_pending_approvals()
async
¶
Get all pending approval requests for this task.
This method requires the Task to have been created via zap.get_task(),
which injects the necessary callback for fetching approval data.
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
List of dicts with approval request data: |
list[dict[str, Any]]
|
|
list[dict[str, Any]]
|
|
list[dict[str, Any]]
|
|
list[dict[str, Any]]
|
|
list[dict[str, Any]]
|
|
list[dict[str, Any]]
|
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If Task was not created via Zap.get_task(). |
Example
task = await zap.get_task(task_id)
pending = await task.get_pending_approvals()
for req in pending:
print(f"Tool: {req['tool_name']}, Args: {req['tool_args']}")
await task.approve(req['id'])
Source code in src/zap_ai/core/task.py
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | |
approve(approval_id)
async
¶
Approve a pending tool execution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
approval_id
|
str
|
ID of the approval request to approve. |
required |
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If Task was not created via Zap.get_task(). |
Example
task = await zap.get_task(task_id)
pending = await task.get_pending_approvals()
await task.approve(pending[0]['id'])
Source code in src/zap_ai/core/task.py
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 | |
reject(approval_id, reason=None)
async
¶
Reject a pending tool execution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
approval_id
|
str
|
ID of the approval request to reject. |
required |
reason
|
str | None
|
Optional reason for rejection. |
None
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If Task was not created via Zap.get_task(). |
Example
task = await zap.get_task(task_id)
pending = await task.get_pending_approvals()
await task.reject(pending[0]['id'], reason="Amount exceeds limit")
Source code in src/zap_ai/core/task.py
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | |
TaskStatus¶
Enum for task execution states.
zap_ai.TaskStatus
¶
Bases: str, Enum
Status of a task execution.
The lifecycle of a task typically follows: PENDING -> THINKING -> (AWAITING_TOOL <-> THINKING)* -> COMPLETED
With approval rules enabled, the lifecycle may include: THINKING -> AWAITING_APPROVAL -> (approved) -> AWAITING_TOOL
At any point, a task can transition to FAILED if an unrecoverable error occurs.
Attributes:
| Name | Type | Description |
|---|---|---|
PENDING |
Task has been created but workflow hasn't started yet. |
|
THINKING |
Agent is thinking (LLM inference in progress). |
|
AWAITING_TOOL |
Waiting for one or more tool executions to complete. Includes sub-agent delegation via message_agent tool. |
|
AWAITING_APPROVAL |
Tool call requires human approval before execution. Use Task.get_pending_approvals() to see pending requests, and Task.approve() or Task.reject() to respond. |
|
COMPLETED |
Task finished successfully. Result is available. |
|
FAILED |
Task failed with an error. Error details available in Task.error field. |
Source code in src/zap_ai/core/task.py
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | |
is_terminal()
¶
Return True if this is a terminal (final) status.
Source code in src/zap_ai/core/task.py
50 51 52 | |
is_active()
¶
Return True if the task is actively being processed.
Source code in src/zap_ai/core/task.py
54 55 56 | |