RouteKitAI 0.1.0__py3-none-any.whl → 0.2.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.
routekitai/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """RouteKitAI: An agent development + orchestration framework."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.2.0"
4
4
 
5
5
  # Import hooks first to ensure ToolFilter is defined before Agent
6
6
  from routekitai.core import (
@@ -1,12 +1,12 @@
1
1
  """Message primitive for RouteKit."""
2
2
 
3
- from enum import Enum
3
+ from enum import StrEnum
4
4
  from typing import Any
5
5
 
6
6
  from pydantic import BaseModel, Field
7
7
 
8
8
 
9
- class MessageRole(str, Enum):
9
+ class MessageRole(StrEnum):
10
10
  """Message role types."""
11
11
 
12
12
  SYSTEM = "system"
@@ -57,6 +57,7 @@ class ReActPolicy(Policy):
57
57
  ToolAction(
58
58
  tool_name=tc["name"],
59
59
  tool_input=tc.get("arguments", {}),
60
+ tool_call_id=tc.get("id", ""),
60
61
  )
61
62
  for tc in last_message.tool_calls
62
63
  ]
@@ -120,6 +121,7 @@ class FunctionCallingPolicy(Policy):
120
121
  ToolAction(
121
122
  tool_name=tool_name,
122
123
  tool_input=tc.get("arguments", {}),
124
+ tool_call_id=tc.get("id", ""),
123
125
  )
124
126
  )
125
127
 
@@ -178,6 +180,10 @@ class GraphPolicy(Policy, BaseModel):
178
180
  # Execute graph
179
181
  graph_result = await executor.execute(input_data=input_data)
180
182
 
183
+ # Store on runtime so callers can inspect steps and state (e.g. for logging)
184
+ if runtime is not None:
185
+ runtime._last_graph_result = graph_result
186
+
181
187
  # Return final output as result
182
188
  final_output = graph_result.get("state", {}).get("output") or graph_result.get(
183
189
  "state", {}
@@ -302,19 +308,18 @@ class SupervisorPolicy(Policy, BaseModel):
302
308
  if iteration >= self.max_iterations:
303
309
  return [Final(output=Message.assistant("Max iterations reached"))]
304
310
 
305
- # Check if we're waiting for a sub-agent result
306
- if state.get("waiting_for_subagent"):
307
- # Sub-agent has completed, merge result
308
- subagent_result = state.get("subagent_result")
309
- if subagent_result:
310
- # Create message with sub-agent result
311
- result_message = Message.assistant(
312
- f"Sub-agent completed: {subagent_result.get('output', 'Task completed') if isinstance(subagent_result, dict) else str(subagent_result)}"
313
- )
314
- # Note: State mutations should be done via reflect(), not here
315
- # But we need to signal completion, so we'll let the runtime handle it
316
- # Supervisor processes the result
317
- return [ModelAction(messages=[*messages, result_message])]
311
+ # Sub-agent just completed: finalize with its result (runtime set waiting_for_subagent=False)
312
+ subagent_result = state.get("subagent_result")
313
+ if subagent_result and not state.get("waiting_for_subagent"):
314
+ if isinstance(subagent_result, dict) and "output" in subagent_result:
315
+ content = subagent_result["output"]
316
+ if hasattr(content, "content"):
317
+ content = content.content
318
+ else:
319
+ content = str(content)
320
+ else:
321
+ content = str(subagent_result)
322
+ return [Final(output=Message.assistant(content))]
318
323
 
319
324
  # If no messages, supervisor decides which agent to use
320
325
  if not messages:
routekitai/core/policy.py CHANGED
@@ -28,6 +28,9 @@ class ToolAction(Action):
28
28
  action_type: str = Field(default="tool", description="Action type")
29
29
  tool_name: str = Field(..., description="Tool name to execute")
30
30
  tool_input: dict[str, Any] = Field(..., description="Tool input arguments")
31
+ tool_call_id: str = Field(
32
+ default="", description="Tool call ID from assistant message (for API compatibility)"
33
+ )
31
34
 
32
35
 
33
36
  class Parallel(Action):
@@ -107,6 +107,7 @@ class PolicyAdapter(RuntimePolicy):
107
107
  input_data={
108
108
  "tool_name": action.tool_name,
109
109
  "tool_args": action.tool_input,
110
+ "tool_call_id": action.tool_call_id,
110
111
  },
111
112
  )
112
113
  )
@@ -122,12 +123,26 @@ class PolicyAdapter(RuntimePolicy):
122
123
  input_data={
123
124
  "tool_name": sub_action.tool_name,
124
125
  "tool_args": sub_action.tool_input,
126
+ "tool_call_id": sub_action.tool_call_id,
125
127
  },
126
128
  )
127
129
  )
128
130
  # Other action types in parallel not yet supported
129
131
  elif isinstance(action, Final):
130
- # Final action - return empty to signal completion
131
- return []
132
+ # Final action - return a "final" step so runtime uses this output
133
+ steps.append(
134
+ Step(
135
+ step_id=str(uuid.uuid4()),
136
+ step_type="final",
137
+ input_data={"output": action.output},
138
+ )
139
+ )
140
+ return steps
132
141
 
133
142
  return steps
143
+
144
+ async def reflect(self, state: dict[str, Any], observation: dict[str, Any]) -> dict[str, Any]:
145
+ """Delegate to the underlying policy's reflect if it has one."""
146
+ if hasattr(self.policy, "reflect") and callable(self.policy.reflect):
147
+ return await self.policy.reflect(state, observation)
148
+ return state.copy()
@@ -107,6 +107,8 @@ class Runtime(BaseModel):
107
107
  self._current_step: int = 0
108
108
  self._total_steps: int = 0
109
109
  self._progress_callbacks: list[Callable[[dict[str, Any]], None]] = []
110
+ # Last graph execution result (set by GraphPolicy for callers to inspect steps/state)
111
+ self._last_graph_result: dict[str, Any] | None = None
110
112
 
111
113
  def register_agent(self, agent: "Agent") -> None:
112
114
  """Register an agent with the runtime.
@@ -244,16 +246,10 @@ class Runtime(BaseModel):
244
246
  }
245
247
  trace.add_event("run_completed", {"trace_id": trace_id, "result": result_dict})
246
248
 
247
- # Export trace asynchronously (fire and forget)
249
+ # Export trace so it is on disk before returning (needed for replay and tests)
248
250
  if exporter and self.trace_dir:
249
- # Ensure directory exists before async export
250
251
  self.trace_dir.mkdir(parents=True, exist_ok=True)
251
- # Create background task for trace export
252
- export_task = asyncio.create_task(exporter.export(trace))
253
- # Store task reference for potential cleanup
254
- # Note: Task will complete in background, errors are logged by exporter
255
- # For testing, we could await here, but in production we want fire-and-forget
256
- # The exporter now creates the directory itself, so this should work
252
+ await exporter.export(trace)
257
253
 
258
254
  return result
259
255
  except asyncio.CancelledError:
@@ -394,7 +390,13 @@ class Runtime(BaseModel):
394
390
  step_results = await self._execute_steps_parallel(steps, agent, trace)
395
391
 
396
392
  # Process step results
393
+ final_output_message: Message | None = None
394
+ last_model_response: ModelResponse | None = None
397
395
  for step_result in step_results:
396
+ if step_result.step_type == "final":
397
+ if step_result.output_data and "output" in step_result.output_data:
398
+ final_output_message = step_result.output_data["output"]
399
+ break
398
400
  if step_result.step_type == "model_call":
399
401
  # Handle model response
400
402
  if (
@@ -413,6 +415,11 @@ class Runtime(BaseModel):
413
415
  if isinstance(response_data, dict)
414
416
  else []
415
417
  )
418
+ last_model_response = ModelResponse(
419
+ content=content,
420
+ tool_calls=None,
421
+ usage=None,
422
+ )
416
423
 
417
424
  # Create assistant message with tool calls
418
425
  tool_calls: list[dict[str, Any]] | None = None
@@ -445,13 +452,22 @@ class Runtime(BaseModel):
445
452
  if step_result.input_data
446
453
  else ""
447
454
  )
455
+ tool_call_id = (
456
+ step_result.input_data.get("tool_call_id", "")
457
+ if step_result.input_data
458
+ else ""
459
+ )
448
460
  tool_result = step_result.output_data["result"]
449
461
 
450
- # Add tool result message
462
+ # Add tool result message (tool_call_id required by OpenAI API)
451
463
  messages.append(
452
464
  Message.tool(
453
465
  f"Tool {tool_name} executed",
454
- {"result": tool_result, "tool": tool_name},
466
+ {
467
+ "result": tool_result,
468
+ "tool": tool_name,
469
+ "tool_call_id": tool_call_id,
470
+ },
455
471
  )
456
472
  )
457
473
 
@@ -495,6 +511,24 @@ class Runtime(BaseModel):
495
511
  }
496
512
  state["waiting_for_subagent"] = False
497
513
 
514
+ # Let policy reflect on step results (e.g. PlanExecutePolicy updates phase/plan)
515
+ if (
516
+ last_model_response is not None
517
+ and hasattr(policy, "reflect")
518
+ and callable(policy.reflect)
519
+ ):
520
+ state.setdefault(
521
+ "phase", "planning"
522
+ ) # so policies can detect first (planning) phase
523
+ observation = {"result": last_model_response}
524
+ reflected = await policy.reflect(state, observation)
525
+ if isinstance(reflected, dict):
526
+ state.update(reflected)
527
+
528
+ if final_output_message is not None:
529
+ output_message = final_output_message
530
+ break
531
+
498
532
  iteration += 1
499
533
 
500
534
  # Finalize if we hit max iterations
@@ -600,7 +634,10 @@ class Runtime(BaseModel):
600
634
  )
601
635
 
602
636
  try:
603
- if step.step_type == "model_call":
637
+ if step.step_type == "final":
638
+ # Policy produced a final output (e.g. GraphPolicy); pass it through
639
+ step.output_data = {"output": step.input_data.get("output")}
640
+ elif step.step_type == "model_call":
604
641
  # Check if in replay mode
605
642
  if self._replay_mode and self._replay_trace:
606
643
  # Match by sequential order using step_completed events
@@ -1394,6 +1431,7 @@ class DefaultPolicy(Policy):
1394
1431
  input_data={
1395
1432
  "tool_name": tool_call["name"],
1396
1433
  "tool_args": tool_call.get("arguments", {}),
1434
+ "tool_call_id": tool_call.get("id", ""),
1397
1435
  },
1398
1436
  )
1399
1437
  )
routekitai/core/tool.py CHANGED
@@ -1,7 +1,7 @@
1
1
  """Tool primitive for RouteKit."""
2
2
 
3
3
  from abc import ABC, abstractmethod
4
- from enum import Enum
4
+ from enum import StrEnum
5
5
  from typing import Any, TypeVar
6
6
 
7
7
  from pydantic import BaseModel, Field, create_model
@@ -12,7 +12,7 @@ TInput = TypeVar("TInput", bound=BaseModel)
12
12
  TOutput = TypeVar("TOutput", bound=BaseModel)
13
13
 
14
14
 
15
- class ToolPermission(str, Enum):
15
+ class ToolPermission(StrEnum):
16
16
  """Tool permission types."""
17
17
 
18
18
  NETWORK = "network"
@@ -1,13 +1,13 @@
1
1
  """Graph definition for agent orchestration."""
2
2
 
3
3
  from collections.abc import Callable
4
- from enum import Enum
4
+ from enum import StrEnum
5
5
  from typing import Any
6
6
 
7
7
  from pydantic import BaseModel, Field
8
8
 
9
9
 
10
- class NodeType(str, Enum):
10
+ class NodeType(StrEnum):
11
11
  """Type of graph node."""
12
12
 
13
13
  MODEL = "model" # Execute a model call
routekitai/message.py CHANGED
@@ -1,12 +1,12 @@
1
1
  """Message primitive for RouteKit."""
2
2
 
3
- from enum import Enum
3
+ from enum import StrEnum
4
4
  from typing import Any
5
5
 
6
6
  from pydantic import BaseModel, Field
7
7
 
8
8
 
9
- class MessageRole(str, Enum):
9
+ class MessageRole(StrEnum):
10
10
  """Message role types."""
11
11
 
12
12
  USER = "user"
@@ -1,13 +1,13 @@
1
1
  """Permission management for tool execution."""
2
2
 
3
- from enum import Enum
3
+ from enum import StrEnum
4
4
 
5
5
  from pydantic import BaseModel, Field
6
6
 
7
7
  from routekitai.core.tool import ToolPermission
8
8
 
9
9
 
10
- class PermissionLevel(str, Enum):
10
+ class PermissionLevel(StrEnum):
11
11
  """Permission levels for sandbox execution."""
12
12
 
13
13
  NONE = "none"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: RouteKitAI
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: An agent development + orchestration framework
5
5
  Author: Mohamed Ghassen Brahim
6
6
  License: MIT
@@ -195,50 +195,53 @@ asyncio.run(main())
195
195
 
196
196
  - **[Architecture Guide](docs/architecture.md)**: Deep dive into RouteKitAI's design
197
197
  - **[Security & Governance](docs/security-and-governance.md)**: Security features and best practices
198
- - **[API Reference](https://RouteKitAI.readthedocs.io)**: Complete API documentation (coming soon)
198
+ - **[Full documentation](https://routekitai.readthedocs.io)**: Architecture, security, and guides (Read the Docs)
199
199
 
200
200
  ## 🎓 Examples
201
201
 
202
202
  Check out the [`examples/`](examples/) directory for complete examples:
203
203
 
204
- - **[Basic Agent](examples/hello_RouteKitAI.py)**: Simple agent with tools
205
- - **[Graph Orchestration](examples/graph_agent.py)**: Multi-agent workflow
206
- - **[Supervisor Pattern](examples/supervisor_agent.py)**: Supervisor delegating to sub-agents
204
+ - **[Basic Agent](examples/basic.py)** / **[Hello RouteKit](examples/hello_routekit.py)**: Simple agent with tools
205
+ - **[Graph Orchestration](examples/graph_agent.py)** / **[Graph Policy](examples/graph_policy.py)**: Multi-agent workflows
206
+ - **[Supervisor Pattern](examples/supervisor_agent.py)** / **[Supervisor Policy](examples/supervisor_policy.py)**: Supervisor delegating to sub-agents
207
+ - **[ReAct / Plan–Execute / Function Calling](examples/react_policy.py)**, **[Plan–Execute](examples/plan_execute_policy.py)**, **[Function Calling](examples/function_calling_policy.py)**: Policy examples
207
208
  - **[Evaluation Harness](examples/eval_regression.py)**: Testing agents with datasets
208
209
 
210
+ Run all examples: `./scripts/run_examples.sh` (or `bash scripts/run_examples.sh`).
211
+
209
212
  ## 🛠️ CLI Commands
210
213
 
211
- RouteKitAI provides a CLI for common operations:
214
+ RouteKitAI provides a CLI (`routekitai`) for common operations:
212
215
 
213
216
  ```bash
214
217
  # Run an agent script
215
- RouteKitAI run agent_script.py
218
+ routekitai run agent_script.py
216
219
 
217
220
  # View a trace (multiple formats available)
218
- RouteKitAI trace <trace_id> # Table view (default)
219
- RouteKitAI trace <trace_id> --format timeline # Timeline visualization
220
- RouteKitAI trace <trace_id> --format steps # Step-by-step execution
221
- RouteKitAI trace <trace_id> --format json # JSON output
222
- RouteKitAI trace <trace_id> --format raw # Raw JSONL
221
+ routekitai trace <trace_id> # Table view (default)
222
+ routekitai trace <trace_id> --format timeline # Timeline visualization
223
+ routekitai trace <trace_id> --format steps # Step-by-step execution
224
+ routekitai trace <trace_id> --format json # JSON output
225
+ routekitai trace <trace_id> --format raw # Raw JSONL
223
226
 
224
227
  # Analyze trace metrics
225
- RouteKitAI trace-analyze <trace_id> # Performance metrics, token usage, costs
228
+ routekitai trace-analyze <trace_id> # Performance metrics, token usage, costs
226
229
 
227
230
  # Search traces
228
- RouteKitAI trace-search "error" # Search all traces for "error"
229
- RouteKitAI trace-search "model" --trace-id abc # Search specific trace
230
- RouteKitAI trace-search "tool" --event-type tool_called # Filter by event type
231
+ routekitai trace-search "error" # Search all traces for "error"
232
+ routekitai trace-search "model" --trace-id abc # Search specific trace
233
+ routekitai trace-search "tool" --event-type tool_called # Filter by event type
231
234
 
232
235
  # Replay a trace
233
- RouteKitAI replay <trace_id> --agent my_agent
236
+ routekitai replay <trace_id> --agent my_agent
234
237
 
235
238
  # Start web UI for trace visualization
236
- RouteKitAI serve # Start on default port 8080
237
- RouteKitAI serve --port 3000 # Custom port
238
- RouteKitAI serve --host 0.0.0.0 # Make accessible from network
239
+ routekitai serve # Start on default port 8080
240
+ routekitai serve --port 3000 # Custom port
241
+ routekitai serve --host 0.0.0.0 # Make accessible from network
239
242
 
240
243
  # Run sanity checks
241
- RouteKitAI test-agent
244
+ routekitai test-agent
242
245
  ```
243
246
 
244
247
  ## 🏗️ Core Primitives
@@ -271,7 +274,7 @@ pip install -e ".[dev]"
271
274
  pytest
272
275
 
273
276
  # Run with coverage
274
- pytest --cov=RouteKitAI --cov-report=html
277
+ pytest --cov=routekitai --cov-report=html
275
278
 
276
279
  # Run specific test file
277
280
  pytest tests/test_runtime.py
@@ -284,15 +287,15 @@ pytest tests/test_runtime.py
284
287
  mypy src/
285
288
 
286
289
  # Linting
287
- ruff check src/
290
+ ruff check src/ tests/ examples/
288
291
 
289
292
  # Format code
290
- ruff format src/
293
+ ruff format src/ tests/ examples/
291
294
  ```
292
295
 
293
296
  ## 🤝 Contributing
294
297
 
295
- Contributions are welcome! Please read our contributing guidelines (coming soon) and:
298
+ Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) and:
296
299
 
297
300
  1. Fork the repository
298
301
  2. Create a feature branch (`git checkout -b feature/amazing-feature`)
@@ -316,7 +319,7 @@ RouteKitAI is inspired by the need for testable, observable AI agent frameworks.
316
319
  ## 🔗 Links
317
320
 
318
321
  - **GitHub**: [https://github.com/MedGhassen/RouteKitAI](https://github.com/MedGhassen/RouteKitAI)
319
- - **Documentation**: [https://RouteKitAI.readthedocs.io](https://RouteKitAI.readthedocs.io) (coming soon)
322
+ - **Documentation**: [https://routekitai.readthedocs.io](https://routekitai.readthedocs.io)
320
323
  - **Issues**: [https://github.com/MedGhassen/RouteKitAI/issues](https://github.com/MedGhassen/RouteKitAI/issues)
321
324
 
322
325
  ---
@@ -1,5 +1,5 @@
1
- routekitai/__init__.py,sha256=n5oNaNxhqdqDFCBCLBhtG0qoNz3SCWP4l3S1ublAqVc,1091
2
- routekitai/message.py,sha256=HvUTT9UdOlbHwoQAX7tcWCX51GD-AGanUwsb2WwKEXM,829
1
+ routekitai/__init__.py,sha256=tXiazo0NHxFeWcHWsKLCoDMn_fFBH_RQsF-vGeqTWpo,1091
2
+ routekitai/message.py,sha256=owTgRvHctqquWROng2w06c6sMrarKlB6avxHoPhuC3k,830
3
3
  routekitai/model.py,sha256=FfGla6Hep-L1bz-rC89leGdbtQed433FZ1yz4eF0wko,1357
4
4
  routekitai/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  routekitai/tool.py,sha256=o3fOyz_iOyrbYcrc7NYrI7m7JXOLEBZ5WkaKYjsvbF8,1027
@@ -17,13 +17,13 @@ routekitai/core/agent.py,sha256=z1mkIekJ8bbWebmzNADl3vMQURXDMx82eo2O_GC-TFk,1230
17
17
  routekitai/core/errors.py,sha256=YN7uo6B7R7KRk5Lwmk4JclJNBQbKOe5YzXLQtvTLKa8,1224
18
18
  routekitai/core/hooks.py,sha256=lnp5tK_amFDUbkYWxvWnIDwQ2uI4em2Go0KLb1QtD7c,5644
19
19
  routekitai/core/memory.py,sha256=szDTIr3tCgM4aeFO19tOlGj6a8lLPBHTv4KByeUxC2k,1429
20
- routekitai/core/message.py,sha256=kMQIQ6GgYT5Wet7qfkVbqtQyxqCOoo-2UOSEyNVbWTw,3470
20
+ routekitai/core/message.py,sha256=-nc3rPahQFADkeoA_Ipaq4ELPI14e23JAPIskIvM7js,3471
21
21
  routekitai/core/model.py,sha256=vghe66IRXmRO5vNtxQl_L2aVrODE_5Fyj0g_BLCaSMQ,3158
22
- routekitai/core/policies.py,sha256=uQYagWB3LPRiP_mE963H_o7mbt7QmAobLAH_ILIFbf4,13765
23
- routekitai/core/policy.py,sha256=94XiqPm2fKvW7Z8o_6YwrSQUm202kFZwXbKhKy5_PXk,2683
24
- routekitai/core/policy_adapter.py,sha256=Nv_gf7lo9hvOnv-ojRm6idaf-GDoju_Z6vApGTIRtqw,5130
25
- routekitai/core/runtime.py,sha256=nXfIbJRwDXMmi-V7PY78Pu-qMB-neato2uD79cLRrG4,59624
26
- routekitai/core/tool.py,sha256=lN_LtV5dHok3kokt8TUGtWhvkqVow__3JhlaGq7_fRw,4958
22
+ routekitai/core/policies.py,sha256=bSC9v7clYZLxkHsiAgneCGEQfXs7Jzvpd_rK8lFQutE,13872
23
+ routekitai/core/policy.py,sha256=CscLNg2Z4U_XV-xC0mf7QlZN-QCJ3zewSz8uPE5NIR8,2814
24
+ routekitai/core/policy_adapter.py,sha256=GeVVQBfd4Bo3Ijzgcq8fdn1CRtC9XOVwb7f4SkfylYY,5887
25
+ routekitai/core/runtime.py,sha256=rgSD88vxrLV0ZhhuF-q8jsuQprjAqm1z3iS-_lre0zk,61402
26
+ routekitai/core/tool.py,sha256=96zHRidFV8NX9x8fWvbNyT3Up2UL-0BjaNLBl_P79_o,4959
27
27
  routekitai/core/tools.py,sha256=9jye7xa1NcJnSARRarRAIMsbF6gmyI4DlyCCv7HuRYM,5215
28
28
  routekitai/evals/__init__.py,sha256=9J7kySk46qCOApOlIMvOsPSjc3_NzvxCSuZ8-OejBNU,336
29
29
  routekitai/evals/dataset.py,sha256=yivm0NKUjV91OY1jBXdueS64CusHZWnB_f-XyVRTDNA,2512
@@ -31,7 +31,7 @@ routekitai/evals/metrics.py,sha256=_sSkQxWpXVc_cC8FFzriFyNEQce8aGbx-q5rcqkesEM,3
31
31
  routekitai/evals/runner.py,sha256=cUpGjfgQy_biq2O1mOf9mZ61jMk6Y6G6Y7Cpv6RZuzQ,6980
32
32
  routekitai/graphs/__init__.py,sha256=jCmCWWtV29uDBy47U5OrBwwie6eqMC-uS-AGrXLuonM,274
33
33
  routekitai/graphs/executors.py,sha256=1wrZ5mXUMRf6TGbvfddUUm9h8ruyNjMJB6xlZDdRxh0,18329
34
- routekitai/graphs/graph.py,sha256=__Jl7YYqTLRTPOLDzePJAx4aiiCGRTLp34Q-s4aQ5Xc,6301
34
+ routekitai/graphs/graph.py,sha256=vX70acCsKWs2vv7ccuUWhqhDVB1fJ-L5tKMVhpFhQLM,6302
35
35
  routekitai/memory/__init__.py,sha256=Y4QrSbzzQuutlbfnTqOwBBp6Q0ODtcoVkvXOM6eERqk,343
36
36
  routekitai/memory/episodic.py,sha256=iGWpeWo5KikTBHhWZsk41YWuT12JJ139I7Dz54LTdhk,8166
37
37
  routekitai/memory/kv.py,sha256=3w883l7MpLmDz3VhX-fzQQXtxpZhElxgCJv3RczgzE8,785
@@ -55,10 +55,10 @@ routekitai/providers/openai.py,sha256=ImTGXOiHyNtXUNF2tzBF4Dkv8r_aPrmQDUH6Cu7-zi
55
55
  routekitai/sandbox/__init__.py,sha256=erkRO6xnq7NcOmv_rV444IRJl0WmhRWoVX1Sx8XiqXg,352
56
56
  routekitai/sandbox/filesystem.py,sha256=5bLMhrutoJQVfOM49v1L1ykVpjFee50dERdyY4VaiGM,4744
57
57
  routekitai/sandbox/network.py,sha256=cFK--kZ88irTREWgTWhXDBDvynzq9XdHjFn_jGcF3HI,4668
58
- routekitai/sandbox/permissions.py,sha256=p2Kgqpe_HgfTv7_JEUVLGhFn5UbsFErkmtyzBqFucWk,2093
59
- routekitai-0.1.0.dist-info/licenses/LICENSE,sha256=TftL8ryIHKESApEmr5TBlRg5mengWfrzzjlr7nz46iE,1079
60
- routekitai-0.1.0.dist-info/METADATA,sha256=0Kf-5L9YrKiTseYOd1IJgBo3EnxbWnUQho_AhSCSPK4,10113
61
- routekitai-0.1.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
62
- routekitai-0.1.0.dist-info/entry_points.txt,sha256=pHUdSYPaXtmUY5LmHWKcgh2dR-t0DRrgUZ3AO0Pk9L0,56
63
- routekitai-0.1.0.dist-info/top_level.txt,sha256=lbYswJspf7-baehrsDZboTTxhrabTTPf4mGYC_jXKaY,11
64
- routekitai-0.1.0.dist-info/RECORD,,
58
+ routekitai/sandbox/permissions.py,sha256=5rGeF_4JcpetrsVYZuAw-S-rV5vsic1OSJAh0we-uDs,2094
59
+ routekitai-0.2.0.dist-info/licenses/LICENSE,sha256=TftL8ryIHKESApEmr5TBlRg5mengWfrzzjlr7nz46iE,1079
60
+ routekitai-0.2.0.dist-info/METADATA,sha256=XS91zXumQ49sZuoJHxXX4kRu9FK5CC-5mRe0D671D8g,10592
61
+ routekitai-0.2.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
62
+ routekitai-0.2.0.dist-info/entry_points.txt,sha256=pHUdSYPaXtmUY5LmHWKcgh2dR-t0DRrgUZ3AO0Pk9L0,56
63
+ routekitai-0.2.0.dist-info/top_level.txt,sha256=lbYswJspf7-baehrsDZboTTxhrabTTPf4mGYC_jXKaY,11
64
+ routekitai-0.2.0.dist-info/RECORD,,