ainative-python 2.0.0__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.
- ainative/__init__.py +46 -0
- ainative/agent_coordination.py +249 -0
- ainative/agent_identity_system.py +1566 -0
- ainative/agent_learning.py +239 -0
- ainative/agent_orchestration.py +202 -0
- ainative/agent_state.py +231 -0
- ainative/agent_swarm/__init__.py +510 -0
- ainative/auth.py +113 -0
- ainative/cli.py +698 -0
- ainative/cli_utils/__init__.py +13 -0
- ainative/cli_utils/diff.py +292 -0
- ainative/cli_utils/formatters.py +227 -0
- ainative/client.py +272 -0
- ainative/commands/__init__.py +28 -0
- ainative/commands/agents.py +238 -0
- ainative/commands/coordination.py +108 -0
- ainative/commands/inspect.py +483 -0
- ainative/commands/learning.py +119 -0
- ainative/commands/local.py +544 -0
- ainative/commands/state.py +144 -0
- ainative/commands/swarm.py +184 -0
- ainative/commands/sync.py +157 -0
- ainative/commands/tasks.py +191 -0
- ainative/exceptions.py +87 -0
- ainative/zerodb/__init__.py +89 -0
- ainative/zerodb/analytics.py +232 -0
- ainative/zerodb/memory.py +260 -0
- ainative/zerodb/projects.py +224 -0
- ainative/zerodb/tables.py +362 -0
- ainative/zerodb/vectors.py +231 -0
- ainative_python-2.0.0.dist-info/METADATA +550 -0
- ainative_python-2.0.0.dist-info/RECORD +35 -0
- ainative_python-2.0.0.dist-info/WHEEL +5 -0
- ainative_python-2.0.0.dist-info/entry_points.txt +2 -0
- ainative_python-2.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Swarm Management CLI Commands
|
|
3
|
+
|
|
4
|
+
Commands for managing agent swarms (list, create, delete, scale, analytics).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import click
|
|
8
|
+
import json
|
|
9
|
+
from typing import Optional
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
from rich.table import Table
|
|
12
|
+
from rich.panel import Panel
|
|
13
|
+
|
|
14
|
+
from ..client import AINativeClient
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
console = Console()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_client() -> AINativeClient:
|
|
21
|
+
"""Get authenticated client."""
|
|
22
|
+
import os
|
|
23
|
+
from ..auth import AuthConfig
|
|
24
|
+
|
|
25
|
+
api_key = os.getenv("AINATIVE_API_KEY")
|
|
26
|
+
if not api_key:
|
|
27
|
+
raise click.ClickException("AINATIVE_API_KEY environment variable not set")
|
|
28
|
+
|
|
29
|
+
return AINativeClient(
|
|
30
|
+
auth_config=AuthConfig(api_key=api_key),
|
|
31
|
+
base_url=os.getenv("AINATIVE_BASE_URL"),
|
|
32
|
+
organization_id=os.getenv("AINATIVE_ORG_ID")
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@click.group(name="swarm")
|
|
37
|
+
def swarm_group():
|
|
38
|
+
"""Manage agent swarms."""
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@swarm_group.command(name="list")
|
|
43
|
+
@click.option("--project-id", help="Filter by project ID")
|
|
44
|
+
@click.option("--status", help="Filter by status")
|
|
45
|
+
@click.option("--format", type=click.Choice(["table", "json"]), default="table",
|
|
46
|
+
help="Output format")
|
|
47
|
+
def list_swarms(project_id: Optional[str], status: Optional[str], format: str):
|
|
48
|
+
"""List all swarms."""
|
|
49
|
+
try:
|
|
50
|
+
client = get_client()
|
|
51
|
+
result = client.agent_swarm.list_swarms(
|
|
52
|
+
project_id=project_id,
|
|
53
|
+
status=status
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
swarms = result.get("swarms", [])
|
|
57
|
+
|
|
58
|
+
if format == "json":
|
|
59
|
+
click.echo(json.dumps(swarms, indent=2))
|
|
60
|
+
else:
|
|
61
|
+
table = Table(title="Agent Swarms")
|
|
62
|
+
table.add_column("ID", style="cyan")
|
|
63
|
+
table.add_column("Name", style="bold")
|
|
64
|
+
table.add_column("Status", style="green")
|
|
65
|
+
table.add_column("Agents", justify="right")
|
|
66
|
+
table.add_column("Project", style="dim")
|
|
67
|
+
|
|
68
|
+
for swarm in swarms:
|
|
69
|
+
table.add_row(
|
|
70
|
+
swarm.get("id", ""),
|
|
71
|
+
swarm.get("name", ""),
|
|
72
|
+
swarm.get("status", ""),
|
|
73
|
+
str(swarm.get("agent_count", 0)),
|
|
74
|
+
swarm.get("project_id", "")
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
console.print(table)
|
|
78
|
+
console.print(f"\nTotal: {len(swarms)} swarms")
|
|
79
|
+
|
|
80
|
+
except Exception as e:
|
|
81
|
+
click.echo(f"Error: {str(e)}", err=True)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@swarm_group.command(name="create")
|
|
85
|
+
@click.argument("name")
|
|
86
|
+
@click.option("--project-id", required=True, help="Project ID")
|
|
87
|
+
@click.option("--objective", required=True, help="Swarm objective")
|
|
88
|
+
@click.option("--agents", help="Comma-separated agent types")
|
|
89
|
+
def create_swarm(name: str, project_id: str, objective: str, agents: Optional[str]):
|
|
90
|
+
"""Create a new swarm."""
|
|
91
|
+
try:
|
|
92
|
+
client = get_client()
|
|
93
|
+
|
|
94
|
+
agent_list = []
|
|
95
|
+
if agents:
|
|
96
|
+
for agent_type in agents.split(","):
|
|
97
|
+
agent_list.append({"type": agent_type.strip()})
|
|
98
|
+
|
|
99
|
+
result = client.agent_swarm.start_swarm(
|
|
100
|
+
project_id=project_id,
|
|
101
|
+
agents=agent_list,
|
|
102
|
+
objective=objective,
|
|
103
|
+
config={"name": name}
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
console.print(Panel(
|
|
107
|
+
f"[green]✓[/green] Swarm created: {result.get('swarm_id')}",
|
|
108
|
+
title="Success"
|
|
109
|
+
))
|
|
110
|
+
console.print(json.dumps(result, indent=2))
|
|
111
|
+
|
|
112
|
+
except Exception as e:
|
|
113
|
+
click.echo(f"Error: {str(e)}", err=True)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@swarm_group.command(name="delete")
|
|
117
|
+
@click.argument("swarm_id")
|
|
118
|
+
@click.option("--force", is_flag=True, help="Force deletion without cleanup")
|
|
119
|
+
def delete_swarm(swarm_id: str, force: bool):
|
|
120
|
+
"""Delete a swarm."""
|
|
121
|
+
try:
|
|
122
|
+
if not force:
|
|
123
|
+
click.confirm(f"Delete swarm {swarm_id}?", abort=True)
|
|
124
|
+
|
|
125
|
+
client = get_client()
|
|
126
|
+
result = client.agent_swarm.delete_swarm(swarm_id, force=force)
|
|
127
|
+
|
|
128
|
+
console.print(Panel(
|
|
129
|
+
f"[green]✓[/green] Swarm deleted: {swarm_id}",
|
|
130
|
+
title="Success"
|
|
131
|
+
))
|
|
132
|
+
|
|
133
|
+
except Exception as e:
|
|
134
|
+
click.echo(f"Error: {str(e)}", err=True)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
@swarm_group.command(name="scale")
|
|
138
|
+
@click.argument("swarm_id")
|
|
139
|
+
@click.option("--agents", required=True, help="Agent counts (e.g., researcher=5,coder=3)")
|
|
140
|
+
def scale_swarm(swarm_id: str, agents: str):
|
|
141
|
+
"""Scale swarm agent counts."""
|
|
142
|
+
try:
|
|
143
|
+
agent_counts = {}
|
|
144
|
+
for pair in agents.split(","):
|
|
145
|
+
agent_type, count = pair.split("=")
|
|
146
|
+
agent_counts[agent_type.strip()] = int(count)
|
|
147
|
+
|
|
148
|
+
client = get_client()
|
|
149
|
+
result = client.agent_swarm.scale_swarm(swarm_id, agent_counts)
|
|
150
|
+
|
|
151
|
+
console.print(Panel(
|
|
152
|
+
f"[green]✓[/green] Swarm scaled successfully",
|
|
153
|
+
title="Success"
|
|
154
|
+
))
|
|
155
|
+
console.print(json.dumps(result, indent=2))
|
|
156
|
+
|
|
157
|
+
except Exception as e:
|
|
158
|
+
click.echo(f"Error: {str(e)}", err=True)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
@swarm_group.command(name="analytics")
|
|
162
|
+
@click.argument("swarm_id")
|
|
163
|
+
@click.option("--time-range", default="7d", help="Time range (1d, 7d, 30d, all)")
|
|
164
|
+
@click.option("--metrics", help="Comma-separated metric types")
|
|
165
|
+
def get_analytics(swarm_id: str, time_range: str, metrics: Optional[str]):
|
|
166
|
+
"""Get swarm analytics."""
|
|
167
|
+
try:
|
|
168
|
+
client = get_client()
|
|
169
|
+
|
|
170
|
+
metric_list = metrics.split(",") if metrics else None
|
|
171
|
+
result = client.agent_swarm.get_analytics(
|
|
172
|
+
swarm_id,
|
|
173
|
+
metric_types=metric_list,
|
|
174
|
+
time_range=time_range
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
console.print(Panel(
|
|
178
|
+
f"Analytics for swarm: {swarm_id}",
|
|
179
|
+
title="Swarm Analytics"
|
|
180
|
+
))
|
|
181
|
+
console.print(json.dumps(result, indent=2))
|
|
182
|
+
|
|
183
|
+
except Exception as e:
|
|
184
|
+
click.echo(f"Error: {str(e)}", err=True)
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Sync CLI Commands
|
|
3
|
+
|
|
4
|
+
Commands for synchronizing local and cloud database environments.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import click
|
|
8
|
+
import json
|
|
9
|
+
from typing import Optional
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
|
|
12
|
+
from ..client import AINativeClient
|
|
13
|
+
from ..cli_utils.diff import DatabaseDiff
|
|
14
|
+
from ..cli_utils.formatters import DiffFormatter
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
console = Console()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_client(base_url: Optional[str] = None) -> AINativeClient:
|
|
21
|
+
"""Get authenticated client with optional base URL override."""
|
|
22
|
+
import os
|
|
23
|
+
from ..auth import AuthConfig
|
|
24
|
+
|
|
25
|
+
api_key = os.getenv("AINATIVE_API_KEY")
|
|
26
|
+
if not api_key:
|
|
27
|
+
raise click.ClickException("AINATIVE_API_KEY environment variable not set")
|
|
28
|
+
|
|
29
|
+
return AINativeClient(
|
|
30
|
+
auth_config=AuthConfig(api_key=api_key),
|
|
31
|
+
base_url=base_url,
|
|
32
|
+
organization_id=os.getenv("AINATIVE_ORG_ID")
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@click.group(name="sync")
|
|
37
|
+
def sync_group():
|
|
38
|
+
"""Database synchronization commands."""
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@sync_group.command(name="plan")
|
|
43
|
+
@click.option(
|
|
44
|
+
"--local-url",
|
|
45
|
+
default="http://localhost:8000",
|
|
46
|
+
help="Local API URL (default: http://localhost:8000)"
|
|
47
|
+
)
|
|
48
|
+
@click.option(
|
|
49
|
+
"--cloud-url",
|
|
50
|
+
default="https://api.ainative.studio",
|
|
51
|
+
help="Cloud API URL (default: https://api.ainative.studio)"
|
|
52
|
+
)
|
|
53
|
+
@click.option(
|
|
54
|
+
"--schema",
|
|
55
|
+
is_flag=True,
|
|
56
|
+
help="Show schema diff only"
|
|
57
|
+
)
|
|
58
|
+
@click.option(
|
|
59
|
+
"--data",
|
|
60
|
+
is_flag=True,
|
|
61
|
+
help="Show data diff only"
|
|
62
|
+
)
|
|
63
|
+
@click.option(
|
|
64
|
+
"--vectors",
|
|
65
|
+
is_flag=True,
|
|
66
|
+
help="Show vectors diff only"
|
|
67
|
+
)
|
|
68
|
+
@click.option(
|
|
69
|
+
"--json",
|
|
70
|
+
"json_output",
|
|
71
|
+
is_flag=True,
|
|
72
|
+
help="Output as JSON"
|
|
73
|
+
)
|
|
74
|
+
def sync_plan(
|
|
75
|
+
local_url: str,
|
|
76
|
+
cloud_url: str,
|
|
77
|
+
schema: bool,
|
|
78
|
+
data: bool,
|
|
79
|
+
vectors: bool,
|
|
80
|
+
json_output: bool
|
|
81
|
+
):
|
|
82
|
+
"""
|
|
83
|
+
Show diff between local and cloud environments.
|
|
84
|
+
|
|
85
|
+
Compares database schema, data, and vectors between local development
|
|
86
|
+
environment and cloud production. Use flags to filter specific types.
|
|
87
|
+
|
|
88
|
+
Examples:
|
|
89
|
+
ainative sync plan
|
|
90
|
+
ainative sync plan --schema
|
|
91
|
+
ainative sync plan --data --vectors
|
|
92
|
+
ainative sync plan --json
|
|
93
|
+
"""
|
|
94
|
+
try:
|
|
95
|
+
# If no specific flags set, show all
|
|
96
|
+
show_all = not (schema or data or vectors)
|
|
97
|
+
|
|
98
|
+
console.print("\n[bold cyan]🔍 Sync Plan (Local → Cloud)[/bold cyan]\n")
|
|
99
|
+
|
|
100
|
+
# Fetch data from local and cloud
|
|
101
|
+
console.print("[dim]Fetching local database state...[/dim]")
|
|
102
|
+
local_client = get_client(local_url)
|
|
103
|
+
|
|
104
|
+
console.print("[dim]Fetching cloud database state...[/dim]")
|
|
105
|
+
cloud_client = get_client(cloud_url)
|
|
106
|
+
|
|
107
|
+
# Compute diffs
|
|
108
|
+
differ = DatabaseDiff(local_client, cloud_client)
|
|
109
|
+
|
|
110
|
+
# Get schema diff
|
|
111
|
+
schema_diff = None
|
|
112
|
+
if show_all or schema:
|
|
113
|
+
schema_diff = differ.compute_schema_diff()
|
|
114
|
+
|
|
115
|
+
# Get data diff
|
|
116
|
+
data_diff = None
|
|
117
|
+
if show_all or data:
|
|
118
|
+
data_diff = differ.compute_data_diff()
|
|
119
|
+
|
|
120
|
+
# Get vectors diff
|
|
121
|
+
vectors_diff = None
|
|
122
|
+
if show_all or vectors:
|
|
123
|
+
vectors_diff = differ.compute_vectors_diff()
|
|
124
|
+
|
|
125
|
+
# Format and display output
|
|
126
|
+
formatter = DiffFormatter()
|
|
127
|
+
|
|
128
|
+
if json_output:
|
|
129
|
+
# JSON output
|
|
130
|
+
output = {
|
|
131
|
+
"schema": schema_diff,
|
|
132
|
+
"data": data_diff,
|
|
133
|
+
"vectors": vectors_diff
|
|
134
|
+
}
|
|
135
|
+
click.echo(json.dumps(output, indent=2))
|
|
136
|
+
else:
|
|
137
|
+
# Rich formatted output
|
|
138
|
+
if schema_diff:
|
|
139
|
+
formatter.format_schema_diff(schema_diff)
|
|
140
|
+
|
|
141
|
+
if data_diff:
|
|
142
|
+
formatter.format_data_diff(data_diff)
|
|
143
|
+
|
|
144
|
+
if vectors_diff:
|
|
145
|
+
formatter.format_vectors_diff(vectors_diff)
|
|
146
|
+
|
|
147
|
+
# Show summary
|
|
148
|
+
console.print("\n[dim]Use `ainative sync apply` to execute.[/dim]")
|
|
149
|
+
|
|
150
|
+
except click.ClickException:
|
|
151
|
+
raise
|
|
152
|
+
except Exception as e:
|
|
153
|
+
console.print(f"[red]Error:[/red] {str(e)}")
|
|
154
|
+
if "--verbose" in click.get_current_context().args:
|
|
155
|
+
import traceback
|
|
156
|
+
console.print(traceback.format_exc())
|
|
157
|
+
raise click.Abort()
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Task Execution CLI Commands
|
|
3
|
+
|
|
4
|
+
Commands for task management (create, execute, status, list, sequence).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import click
|
|
8
|
+
import json
|
|
9
|
+
from typing import Optional
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
from rich.table import Table
|
|
12
|
+
from rich.panel import Panel
|
|
13
|
+
from rich import print as rprint
|
|
14
|
+
|
|
15
|
+
from ..client import AINativeClient
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
console = Console()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_client() -> AINativeClient:
|
|
22
|
+
"""Get authenticated client."""
|
|
23
|
+
import os
|
|
24
|
+
from ..auth import AuthConfig
|
|
25
|
+
|
|
26
|
+
api_key = os.getenv("AINATIVE_API_KEY")
|
|
27
|
+
if not api_key:
|
|
28
|
+
raise click.ClickException("AINATIVE_API_KEY environment variable not set")
|
|
29
|
+
|
|
30
|
+
return AINativeClient(
|
|
31
|
+
auth_config=AuthConfig(api_key=api_key),
|
|
32
|
+
base_url=os.getenv("AINATIVE_BASE_URL"),
|
|
33
|
+
organization_id=os.getenv("AINATIVE_ORG_ID")
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@click.group(name="task")
|
|
38
|
+
def task_group():
|
|
39
|
+
"""Manage agent tasks."""
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@task_group.command(name="create")
|
|
44
|
+
@click.option("--agent-id", required=True, help="Agent instance ID")
|
|
45
|
+
@click.option("--type", "task_type", required=True, help="Task type")
|
|
46
|
+
@click.option("--description", required=True, help="Task description")
|
|
47
|
+
@click.option("--priority", default="medium", help="Task priority (low, medium, high, critical)")
|
|
48
|
+
@click.option("--context", help="Task context as JSON string")
|
|
49
|
+
def create_task(agent_id: str, task_type: str, description: str, priority: str, context: Optional[str]):
|
|
50
|
+
"""Create a new task."""
|
|
51
|
+
try:
|
|
52
|
+
client = get_client()
|
|
53
|
+
|
|
54
|
+
context_data = {}
|
|
55
|
+
if context:
|
|
56
|
+
context_data = json.loads(context)
|
|
57
|
+
|
|
58
|
+
result = client.agent_orchestration.create_task(
|
|
59
|
+
agent_id=agent_id,
|
|
60
|
+
task_type=task_type,
|
|
61
|
+
description=description,
|
|
62
|
+
context=context_data,
|
|
63
|
+
priority=priority
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
console.print(Panel(
|
|
67
|
+
f"[green]✓[/green] Task created: {result.get('task_id')}",
|
|
68
|
+
title="Success"
|
|
69
|
+
))
|
|
70
|
+
console.print(json.dumps(result, indent=2))
|
|
71
|
+
|
|
72
|
+
except Exception as e:
|
|
73
|
+
click.echo(f"Error: {str(e)}", err=True)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
@task_group.command(name="execute")
|
|
77
|
+
@click.argument("task_id")
|
|
78
|
+
@click.option("--agent-id", help="Optional specific agent to use")
|
|
79
|
+
def execute_task(task_id: str, agent_id: Optional[str]):
|
|
80
|
+
"""Execute a task."""
|
|
81
|
+
try:
|
|
82
|
+
client = get_client()
|
|
83
|
+
result = client.agent_orchestration.execute_task(task_id, agent_id=agent_id)
|
|
84
|
+
|
|
85
|
+
console.print(Panel(
|
|
86
|
+
f"[green]✓[/green] Task execution started",
|
|
87
|
+
title="Success"
|
|
88
|
+
))
|
|
89
|
+
console.print(json.dumps(result, indent=2))
|
|
90
|
+
|
|
91
|
+
except Exception as e:
|
|
92
|
+
click.echo(f"Error: {str(e)}", err=True)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@task_group.command(name="status")
|
|
96
|
+
@click.argument("task_id")
|
|
97
|
+
def get_status(task_id: str):
|
|
98
|
+
"""Get task status."""
|
|
99
|
+
try:
|
|
100
|
+
client = get_client()
|
|
101
|
+
result = client.agent_orchestration.get_task_status(task_id)
|
|
102
|
+
|
|
103
|
+
status = result.get("status", "unknown")
|
|
104
|
+
status_color = {
|
|
105
|
+
"pending": "yellow",
|
|
106
|
+
"running": "blue",
|
|
107
|
+
"completed": "green",
|
|
108
|
+
"failed": "red"
|
|
109
|
+
}.get(status, "white")
|
|
110
|
+
|
|
111
|
+
console.print(Panel(
|
|
112
|
+
f"Status: [{status_color}]{status}[/{status_color}]\n\n" +
|
|
113
|
+
json.dumps(result, indent=2),
|
|
114
|
+
title=f"Task {task_id}"
|
|
115
|
+
))
|
|
116
|
+
|
|
117
|
+
except Exception as e:
|
|
118
|
+
click.echo(f"Error: {str(e)}", err=True)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@task_group.command(name="list")
|
|
122
|
+
@click.option("--agent-id", help="Filter by agent ID")
|
|
123
|
+
@click.option("--status", help="Filter by status")
|
|
124
|
+
@click.option("--type", "task_type", help="Filter by task type")
|
|
125
|
+
@click.option("--format", type=click.Choice(["table", "json"]), default="table",
|
|
126
|
+
help="Output format")
|
|
127
|
+
def list_tasks(agent_id: Optional[str], status: Optional[str], task_type: Optional[str], format: str):
|
|
128
|
+
"""List tasks."""
|
|
129
|
+
try:
|
|
130
|
+
client = get_client()
|
|
131
|
+
result = client.agent_orchestration.list_tasks(
|
|
132
|
+
agent_id=agent_id,
|
|
133
|
+
status=status,
|
|
134
|
+
task_type=task_type
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
tasks = result.get("tasks", [])
|
|
138
|
+
|
|
139
|
+
if format == "json":
|
|
140
|
+
click.echo(json.dumps(tasks, indent=2))
|
|
141
|
+
else:
|
|
142
|
+
table = Table(title="Tasks")
|
|
143
|
+
table.add_column("ID", style="cyan")
|
|
144
|
+
table.add_column("Type", style="bold")
|
|
145
|
+
table.add_column("Status", style="green")
|
|
146
|
+
table.add_column("Priority", justify="right")
|
|
147
|
+
table.add_column("Agent", style="dim")
|
|
148
|
+
|
|
149
|
+
for task in tasks:
|
|
150
|
+
table.add_row(
|
|
151
|
+
task.get("id", "")[:12],
|
|
152
|
+
task.get("task_type", ""),
|
|
153
|
+
task.get("status", ""),
|
|
154
|
+
task.get("priority", ""),
|
|
155
|
+
task.get("agent_id", "")[:12]
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
console.print(table)
|
|
159
|
+
console.print(f"\nTotal: {len(tasks)} tasks")
|
|
160
|
+
|
|
161
|
+
except Exception as e:
|
|
162
|
+
click.echo(f"Error: {str(e)}", err=True)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
@task_group.command(name="sequence")
|
|
166
|
+
@click.option("--name", required=True, help="Sequence name")
|
|
167
|
+
@click.option("--tasks", required=True, help="Task IDs (comma-separated)")
|
|
168
|
+
@click.option("--mode", default="sequential", help="Execution mode (sequential, parallel, conditional)")
|
|
169
|
+
def create_sequence(name: str, tasks: str, mode: str):
|
|
170
|
+
"""Create a task sequence."""
|
|
171
|
+
try:
|
|
172
|
+
client = get_client()
|
|
173
|
+
|
|
174
|
+
task_list = []
|
|
175
|
+
for task_id in tasks.split(","):
|
|
176
|
+
task_list.append({"task_id": task_id.strip()})
|
|
177
|
+
|
|
178
|
+
result = client.agent_coordination.create_task_sequence(
|
|
179
|
+
name=name,
|
|
180
|
+
tasks=task_list,
|
|
181
|
+
execution_mode=mode
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
console.print(Panel(
|
|
185
|
+
f"[green]✓[/green] Sequence created: {result.get('sequence_id')}",
|
|
186
|
+
title="Success"
|
|
187
|
+
))
|
|
188
|
+
console.print(json.dumps(result, indent=2))
|
|
189
|
+
|
|
190
|
+
except Exception as e:
|
|
191
|
+
click.echo(f"Error: {str(e)}", err=True)
|
ainative/exceptions.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AINative SDK Exception Classes
|
|
3
|
+
|
|
4
|
+
Custom exceptions for better error handling and debugging.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Optional, Dict, Any
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AINativeException(Exception):
|
|
11
|
+
"""Base exception for all AINative SDK errors."""
|
|
12
|
+
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
message: str,
|
|
16
|
+
error_code: Optional[str] = None,
|
|
17
|
+
details: Optional[Dict[str, Any]] = None,
|
|
18
|
+
):
|
|
19
|
+
super().__init__(message)
|
|
20
|
+
self.message = message
|
|
21
|
+
self.error_code = error_code
|
|
22
|
+
self.details = details or {}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class AuthenticationError(AINativeException):
|
|
26
|
+
"""Raised when authentication fails."""
|
|
27
|
+
|
|
28
|
+
def __init__(self, message: str = "Authentication failed"):
|
|
29
|
+
super().__init__(message, error_code="AUTH_ERROR")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class APIError(AINativeException):
|
|
33
|
+
"""Raised when API returns an error response."""
|
|
34
|
+
|
|
35
|
+
def __init__(
|
|
36
|
+
self,
|
|
37
|
+
message: str,
|
|
38
|
+
status_code: Optional[int] = None,
|
|
39
|
+
response_body: Optional[str] = None,
|
|
40
|
+
):
|
|
41
|
+
super().__init__(message, error_code="API_ERROR")
|
|
42
|
+
self.status_code = status_code
|
|
43
|
+
self.response_body = response_body
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class NetworkError(AINativeException):
|
|
47
|
+
"""Raised when network-related errors occur."""
|
|
48
|
+
|
|
49
|
+
def __init__(self, message: str = "Network error occurred"):
|
|
50
|
+
super().__init__(message, error_code="NETWORK_ERROR")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class ValidationError(AINativeException):
|
|
54
|
+
"""Raised when input validation fails."""
|
|
55
|
+
|
|
56
|
+
def __init__(self, message: str, field: Optional[str] = None):
|
|
57
|
+
super().__init__(message, error_code="VALIDATION_ERROR")
|
|
58
|
+
self.field = field
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class RateLimitError(AINativeException):
|
|
62
|
+
"""Raised when API rate limit is exceeded."""
|
|
63
|
+
|
|
64
|
+
def __init__(
|
|
65
|
+
self,
|
|
66
|
+
message: str = "Rate limit exceeded",
|
|
67
|
+
retry_after: Optional[int] = None,
|
|
68
|
+
):
|
|
69
|
+
super().__init__(message, error_code="RATE_LIMIT")
|
|
70
|
+
self.retry_after = retry_after
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class ResourceNotFoundError(AINativeException):
|
|
74
|
+
"""Raised when requested resource is not found."""
|
|
75
|
+
|
|
76
|
+
def __init__(self, resource_type: str, resource_id: str):
|
|
77
|
+
message = f"{resource_type} with ID {resource_id} not found"
|
|
78
|
+
super().__init__(message, error_code="NOT_FOUND")
|
|
79
|
+
self.resource_type = resource_type
|
|
80
|
+
self.resource_id = resource_id
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class TimeoutError(AINativeException):
|
|
84
|
+
"""Raised when operation times out."""
|
|
85
|
+
|
|
86
|
+
def __init__(self, message: str = "Operation timed out"):
|
|
87
|
+
super().__init__(message, error_code="TIMEOUT")
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ZeroDB Module for AINative SDK
|
|
3
|
+
|
|
4
|
+
Provides high-level interface for ZeroDB operations including projects,
|
|
5
|
+
vectors, memory, and analytics.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import TYPE_CHECKING, List, Dict, Any, Optional
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from ..client import AINativeClient
|
|
13
|
+
|
|
14
|
+
from .projects import ProjectsClient
|
|
15
|
+
from .vectors import VectorsClient
|
|
16
|
+
from .memory import MemoryClient
|
|
17
|
+
from .analytics import AnalyticsClient
|
|
18
|
+
from .tables import TablesClient
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ZeroDBClient:
|
|
22
|
+
"""Main client for ZeroDB operations."""
|
|
23
|
+
|
|
24
|
+
def __init__(self, client: "AINativeClient"):
|
|
25
|
+
"""
|
|
26
|
+
Initialize ZeroDB client.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
client: Parent AINative client instance
|
|
30
|
+
"""
|
|
31
|
+
self.client = client
|
|
32
|
+
self._projects: Optional[ProjectsClient] = None
|
|
33
|
+
self._vectors: Optional[VectorsClient] = None
|
|
34
|
+
self._memory: Optional[MemoryClient] = None
|
|
35
|
+
self._analytics: Optional[AnalyticsClient] = None
|
|
36
|
+
self._tables: Optional[TablesClient] = None
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def projects(self) -> ProjectsClient:
|
|
40
|
+
"""Get projects operations client."""
|
|
41
|
+
if not self._projects:
|
|
42
|
+
self._projects = ProjectsClient(self.client)
|
|
43
|
+
return self._projects
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def vectors(self) -> VectorsClient:
|
|
47
|
+
"""Get vectors operations client."""
|
|
48
|
+
if not self._vectors:
|
|
49
|
+
self._vectors = VectorsClient(self.client)
|
|
50
|
+
return self._vectors
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def memory(self) -> MemoryClient:
|
|
54
|
+
"""Get memory operations client."""
|
|
55
|
+
if not self._memory:
|
|
56
|
+
self._memory = MemoryClient(self.client)
|
|
57
|
+
return self._memory
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def analytics(self) -> AnalyticsClient:
|
|
61
|
+
"""Get analytics operations client."""
|
|
62
|
+
if not self._analytics:
|
|
63
|
+
self._analytics = AnalyticsClient(self.client)
|
|
64
|
+
return self._analytics
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def tables(self) -> TablesClient:
|
|
68
|
+
"""Get NoSQL tables operations client."""
|
|
69
|
+
if not self._tables:
|
|
70
|
+
self._tables = TablesClient(self.client)
|
|
71
|
+
return self._tables
|
|
72
|
+
|
|
73
|
+
def health_check(self) -> Dict[str, Any]:
|
|
74
|
+
"""Check ZeroDB health status."""
|
|
75
|
+
return self.client.get("/zerodb/health")
|
|
76
|
+
|
|
77
|
+
def get_usage_stats(self) -> Dict[str, Any]:
|
|
78
|
+
"""Get usage statistics for ZeroDB."""
|
|
79
|
+
return self.client.get("/zerodb/usage")
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
__all__ = [
|
|
83
|
+
"ZeroDBClient",
|
|
84
|
+
"ProjectsClient",
|
|
85
|
+
"VectorsClient",
|
|
86
|
+
"MemoryClient",
|
|
87
|
+
"AnalyticsClient",
|
|
88
|
+
"TablesClient",
|
|
89
|
+
]
|