prompture 0.0.41.dev1__tar.gz → 0.0.42__tar.gz
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.
- {prompture-0.0.41.dev1 → prompture-0.0.42}/.env.copy +1 -1
- {prompture-0.0.41.dev1/prompture.egg-info → prompture-0.0.42}/PKG-INFO +1 -1
- prompture-0.0.42/VERSION +1 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/_version.py +2 -2
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/agent.py +11 -11
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/async_agent.py +11 -11
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/async_groups.py +63 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/cost_mixin.py +25 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/async_azure_driver.py +3 -2
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/async_moonshot_driver.py +3 -2
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/async_openai_driver.py +3 -2
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/async_openrouter_driver.py +3 -2
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/async_zai_driver.py +3 -2
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/azure_driver.py +3 -2
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/moonshot_driver.py +3 -2
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/openai_driver.py +3 -2
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/openrouter_driver.py +10 -2
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/zai_driver.py +3 -2
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/groups.py +42 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/settings.py +1 -1
- {prompture-0.0.41.dev1 → prompture-0.0.42/prompture.egg-info}/PKG-INFO +1 -1
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture.egg-info/SOURCES.txt +1 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/.claude/skills/add-driver/SKILL.md +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/.claude/skills/add-driver/references/driver-template.md +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/.claude/skills/add-example/SKILL.md +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/.claude/skills/add-field/SKILL.md +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/.claude/skills/add-test/SKILL.md +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/.claude/skills/run-tests/SKILL.md +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/.claude/skills/scaffold-extraction/SKILL.md +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/.claude/skills/update-pricing/SKILL.md +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/.github/FUNDING.yml +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/.github/scripts/update_docs_version.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/.github/scripts/update_wrapper_version.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/.github/workflows/dev.yml +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/.github/workflows/documentation.yml +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/.github/workflows/publish.yml +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/CLAUDE.md +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/LICENSE +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/MANIFEST.in +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/README.md +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/ROADMAP.md +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/docs/source/_static/custom.css +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/docs/source/_templates/footer.html +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/docs/source/api/core.rst +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/docs/source/api/drivers.rst +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/docs/source/api/field_definitions.rst +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/docs/source/api/index.rst +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/docs/source/api/runner.rst +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/docs/source/api/tools.rst +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/docs/source/api/validator.rst +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/docs/source/conf.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/docs/source/contributing.rst +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/docs/source/examples.rst +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/docs/source/field_definitions_reference.rst +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/docs/source/index.rst +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/docs/source/installation.rst +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/docs/source/quickstart.rst +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/docs/source/toon_input_guide.rst +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/packages/README.md +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/packages/llm_to_json/README.md +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/packages/llm_to_json/llm_to_json/__init__.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/packages/llm_to_json/pyproject.toml +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/packages/llm_to_json/test.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/packages/llm_to_toon/README.md +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/packages/llm_to_toon/llm_to_toon/__init__.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/packages/llm_to_toon/pyproject.toml +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/packages/llm_to_toon/test.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/__init__.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/agent_types.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/aio/__init__.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/async_conversation.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/async_core.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/async_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/cache.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/callbacks.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/cli.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/conversation.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/core.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/discovery.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/__init__.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/airllm_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/async_airllm_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/async_claude_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/async_google_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/async_grok_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/async_groq_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/async_hugging_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/async_lmstudio_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/async_local_http_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/async_modelscope_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/async_ollama_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/async_registry.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/claude_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/google_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/grok_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/groq_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/hugging_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/lmstudio_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/local_http_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/modelscope_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/ollama_driver.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/registry.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/drivers/vision_helpers.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/field_definitions.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/group_types.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/image.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/ledger.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/logging.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/model_rates.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/persistence.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/persona.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/runner.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/scaffold/__init__.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/scaffold/generator.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/scaffold/templates/Dockerfile.j2 +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/scaffold/templates/README.md.j2 +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/scaffold/templates/config.py.j2 +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/scaffold/templates/env.example.j2 +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/scaffold/templates/main.py.j2 +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/scaffold/templates/models.py.j2 +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/scaffold/templates/requirements.txt.j2 +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/serialization.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/server.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/session.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/tools.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/tools_schema.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture/validator.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture.egg-info/dependency_links.txt +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture.egg-info/entry_points.txt +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture.egg-info/requires.txt +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/prompture.egg-info/top_level.txt +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/pyproject.toml +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/requirements.txt +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/setup.cfg +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/test.py +0 -0
- {prompture-0.0.41.dev1 → prompture-0.0.42}/test_version_diagnosis.py +0 -0
|
@@ -53,7 +53,7 @@ GROQ_MODEL=llama2-70b-4096
|
|
|
53
53
|
# OpenRouter Configuration
|
|
54
54
|
# Required if AI_PROVIDER=openrouter
|
|
55
55
|
OPENROUTER_API_KEY=your-api-key-here
|
|
56
|
-
OPENROUTER_MODEL=openai/gpt-
|
|
56
|
+
OPENROUTER_MODEL=openai/gpt-4o-mini
|
|
57
57
|
|
|
58
58
|
# Grok Configuration
|
|
59
59
|
# Required if AI_PROVIDER=grok
|
prompture-0.0.42/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.0.42
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.0.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 0,
|
|
31
|
+
__version__ = version = '0.0.42'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 0, 42)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -188,7 +188,7 @@ class Agent(Generic[DepsType]):
|
|
|
188
188
|
for fn in tools:
|
|
189
189
|
self._tools.register(fn)
|
|
190
190
|
|
|
191
|
-
self.
|
|
191
|
+
self._lifecycle = AgentState.idle
|
|
192
192
|
self._stop_requested = False
|
|
193
193
|
|
|
194
194
|
# ------------------------------------------------------------------
|
|
@@ -206,7 +206,7 @@ class Agent(Generic[DepsType]):
|
|
|
206
206
|
@property
|
|
207
207
|
def state(self) -> AgentState:
|
|
208
208
|
"""Current lifecycle state of the agent."""
|
|
209
|
-
return self.
|
|
209
|
+
return self._lifecycle
|
|
210
210
|
|
|
211
211
|
def stop(self) -> None:
|
|
212
212
|
"""Request graceful shutdown after the current iteration."""
|
|
@@ -265,16 +265,16 @@ class Agent(Generic[DepsType]):
|
|
|
265
265
|
prompt: The user prompt to send.
|
|
266
266
|
deps: Optional dependencies injected into :class:`RunContext`.
|
|
267
267
|
"""
|
|
268
|
-
self.
|
|
268
|
+
self._lifecycle = AgentState.running
|
|
269
269
|
self._stop_requested = False
|
|
270
270
|
steps: list[AgentStep] = []
|
|
271
271
|
|
|
272
272
|
try:
|
|
273
273
|
result = self._execute(prompt, steps, deps)
|
|
274
|
-
self.
|
|
274
|
+
self._lifecycle = AgentState.idle
|
|
275
275
|
return result
|
|
276
276
|
except Exception:
|
|
277
|
-
self.
|
|
277
|
+
self._lifecycle = AgentState.errored
|
|
278
278
|
raise
|
|
279
279
|
|
|
280
280
|
# ------------------------------------------------------------------
|
|
@@ -722,7 +722,7 @@ class Agent(Generic[DepsType]):
|
|
|
722
722
|
|
|
723
723
|
def _execute_iter(self, prompt: str, deps: Any) -> Generator[AgentStep, None, AgentResult]:
|
|
724
724
|
"""Generator that executes the agent loop and yields each step."""
|
|
725
|
-
self.
|
|
725
|
+
self._lifecycle = AgentState.running
|
|
726
726
|
self._stop_requested = False
|
|
727
727
|
steps: list[AgentStep] = []
|
|
728
728
|
|
|
@@ -730,10 +730,10 @@ class Agent(Generic[DepsType]):
|
|
|
730
730
|
result = self._execute(prompt, steps, deps)
|
|
731
731
|
# Yield each step one at a time
|
|
732
732
|
yield from result.steps
|
|
733
|
-
self.
|
|
733
|
+
self._lifecycle = AgentState.idle
|
|
734
734
|
return result
|
|
735
735
|
except Exception:
|
|
736
|
-
self.
|
|
736
|
+
self._lifecycle = AgentState.errored
|
|
737
737
|
raise
|
|
738
738
|
|
|
739
739
|
# ------------------------------------------------------------------
|
|
@@ -757,7 +757,7 @@ class Agent(Generic[DepsType]):
|
|
|
757
757
|
|
|
758
758
|
def _execute_stream(self, prompt: str, deps: Any) -> Generator[StreamEvent, None, AgentResult]:
|
|
759
759
|
"""Generator that executes the agent loop and yields stream events."""
|
|
760
|
-
self.
|
|
760
|
+
self._lifecycle = AgentState.running
|
|
761
761
|
self._stop_requested = False
|
|
762
762
|
steps: list[AgentStep] = []
|
|
763
763
|
|
|
@@ -853,10 +853,10 @@ class Agent(Generic[DepsType]):
|
|
|
853
853
|
data=result,
|
|
854
854
|
)
|
|
855
855
|
|
|
856
|
-
self.
|
|
856
|
+
self._lifecycle = AgentState.idle
|
|
857
857
|
return result
|
|
858
858
|
except Exception:
|
|
859
|
-
self.
|
|
859
|
+
self._lifecycle = AgentState.errored
|
|
860
860
|
raise
|
|
861
861
|
|
|
862
862
|
|
|
@@ -182,7 +182,7 @@ class AsyncAgent(Generic[DepsType]):
|
|
|
182
182
|
for fn in tools:
|
|
183
183
|
self._tools.register(fn)
|
|
184
184
|
|
|
185
|
-
self.
|
|
185
|
+
self._lifecycle = AgentState.idle
|
|
186
186
|
self._stop_requested = False
|
|
187
187
|
|
|
188
188
|
# ------------------------------------------------------------------
|
|
@@ -197,7 +197,7 @@ class AsyncAgent(Generic[DepsType]):
|
|
|
197
197
|
@property
|
|
198
198
|
def state(self) -> AgentState:
|
|
199
199
|
"""Current lifecycle state of the agent."""
|
|
200
|
-
return self.
|
|
200
|
+
return self._lifecycle
|
|
201
201
|
|
|
202
202
|
def stop(self) -> None:
|
|
203
203
|
"""Request graceful shutdown after the current iteration."""
|
|
@@ -264,16 +264,16 @@ class AsyncAgent(Generic[DepsType]):
|
|
|
264
264
|
Creates a fresh conversation, sends the prompt, handles tool calls,
|
|
265
265
|
and optionally parses the final response into ``output_type``.
|
|
266
266
|
"""
|
|
267
|
-
self.
|
|
267
|
+
self._lifecycle = AgentState.running
|
|
268
268
|
self._stop_requested = False
|
|
269
269
|
steps: list[AgentStep] = []
|
|
270
270
|
|
|
271
271
|
try:
|
|
272
272
|
result = await self._execute(prompt, steps, deps)
|
|
273
|
-
self.
|
|
273
|
+
self._lifecycle = AgentState.idle
|
|
274
274
|
return result
|
|
275
275
|
except Exception:
|
|
276
|
-
self.
|
|
276
|
+
self._lifecycle = AgentState.errored
|
|
277
277
|
raise
|
|
278
278
|
|
|
279
279
|
async def iter(self, prompt: str, *, deps: Any = None) -> AsyncAgentIterator:
|
|
@@ -714,7 +714,7 @@ class AsyncAgent(Generic[DepsType]):
|
|
|
714
714
|
|
|
715
715
|
async def _execute_iter(self, prompt: str, deps: Any) -> AsyncGenerator[AgentStep, None]:
|
|
716
716
|
"""Async generator that executes the agent loop and yields each step."""
|
|
717
|
-
self.
|
|
717
|
+
self._lifecycle = AgentState.running
|
|
718
718
|
self._stop_requested = False
|
|
719
719
|
steps: list[AgentStep] = []
|
|
720
720
|
|
|
@@ -722,11 +722,11 @@ class AsyncAgent(Generic[DepsType]):
|
|
|
722
722
|
result = await self._execute(prompt, steps, deps)
|
|
723
723
|
for step in result.steps:
|
|
724
724
|
yield step
|
|
725
|
-
self.
|
|
725
|
+
self._lifecycle = AgentState.idle
|
|
726
726
|
# Store result on the generator for retrieval
|
|
727
727
|
self._last_iter_result = result
|
|
728
728
|
except Exception:
|
|
729
|
-
self.
|
|
729
|
+
self._lifecycle = AgentState.errored
|
|
730
730
|
raise
|
|
731
731
|
|
|
732
732
|
# ------------------------------------------------------------------
|
|
@@ -735,7 +735,7 @@ class AsyncAgent(Generic[DepsType]):
|
|
|
735
735
|
|
|
736
736
|
async def _execute_stream(self, prompt: str, deps: Any) -> AsyncGenerator[StreamEvent, None]:
|
|
737
737
|
"""Async generator that executes the agent loop and yields stream events."""
|
|
738
|
-
self.
|
|
738
|
+
self._lifecycle = AgentState.running
|
|
739
739
|
self._stop_requested = False
|
|
740
740
|
steps: list[AgentStep] = []
|
|
741
741
|
|
|
@@ -803,10 +803,10 @@ class AsyncAgent(Generic[DepsType]):
|
|
|
803
803
|
|
|
804
804
|
yield StreamEvent(event_type=StreamEventType.output, data=result)
|
|
805
805
|
|
|
806
|
-
self.
|
|
806
|
+
self._lifecycle = AgentState.idle
|
|
807
807
|
self._last_stream_result = result
|
|
808
808
|
except Exception:
|
|
809
|
-
self.
|
|
809
|
+
self._lifecycle = AgentState.errored
|
|
810
810
|
raise
|
|
811
811
|
|
|
812
812
|
|
|
@@ -70,6 +70,27 @@ class ParallelGroup:
|
|
|
70
70
|
"""Request graceful shutdown."""
|
|
71
71
|
self._stop_requested = True
|
|
72
72
|
|
|
73
|
+
@property
|
|
74
|
+
def shared_state(self) -> dict[str, Any]:
|
|
75
|
+
"""Return a copy of the current shared execution state."""
|
|
76
|
+
return dict(self._state)
|
|
77
|
+
|
|
78
|
+
def inject_state(self, state: dict[str, Any], *, recursive: bool = False) -> None:
|
|
79
|
+
"""Merge external key-value pairs into this group's shared state.
|
|
80
|
+
|
|
81
|
+
Existing keys are NOT overwritten (uses setdefault semantics).
|
|
82
|
+
|
|
83
|
+
Args:
|
|
84
|
+
state: Key-value pairs to inject.
|
|
85
|
+
recursive: If True, also inject into nested sub-groups.
|
|
86
|
+
"""
|
|
87
|
+
for k, v in state.items():
|
|
88
|
+
self._state.setdefault(k, v)
|
|
89
|
+
if recursive:
|
|
90
|
+
for agent, _ in self._agents:
|
|
91
|
+
if hasattr(agent, "inject_state"):
|
|
92
|
+
agent.inject_state(state, recursive=True)
|
|
93
|
+
|
|
73
94
|
async def run_async(self, prompt: str = "") -> GroupResult:
|
|
74
95
|
"""Execute all agents concurrently."""
|
|
75
96
|
self._stop_requested = False
|
|
@@ -213,6 +234,27 @@ class AsyncSequentialGroup:
|
|
|
213
234
|
def stop(self) -> None:
|
|
214
235
|
self._stop_requested = True
|
|
215
236
|
|
|
237
|
+
@property
|
|
238
|
+
def shared_state(self) -> dict[str, Any]:
|
|
239
|
+
"""Return a copy of the current shared execution state."""
|
|
240
|
+
return dict(self._state)
|
|
241
|
+
|
|
242
|
+
def inject_state(self, state: dict[str, Any], *, recursive: bool = False) -> None:
|
|
243
|
+
"""Merge external key-value pairs into this group's shared state.
|
|
244
|
+
|
|
245
|
+
Existing keys are NOT overwritten (uses setdefault semantics).
|
|
246
|
+
|
|
247
|
+
Args:
|
|
248
|
+
state: Key-value pairs to inject.
|
|
249
|
+
recursive: If True, also inject into nested sub-groups.
|
|
250
|
+
"""
|
|
251
|
+
for k, v in state.items():
|
|
252
|
+
self._state.setdefault(k, v)
|
|
253
|
+
if recursive:
|
|
254
|
+
for agent, _ in self._agents:
|
|
255
|
+
if hasattr(agent, "inject_state"):
|
|
256
|
+
agent.inject_state(state, recursive=True)
|
|
257
|
+
|
|
216
258
|
async def run(self, prompt: str = "") -> GroupResult:
|
|
217
259
|
"""Execute all agents in sequence (async)."""
|
|
218
260
|
self._stop_requested = False
|
|
@@ -351,6 +393,27 @@ class AsyncLoopGroup:
|
|
|
351
393
|
def stop(self) -> None:
|
|
352
394
|
self._stop_requested = True
|
|
353
395
|
|
|
396
|
+
@property
|
|
397
|
+
def shared_state(self) -> dict[str, Any]:
|
|
398
|
+
"""Return a copy of the current shared execution state."""
|
|
399
|
+
return dict(self._state)
|
|
400
|
+
|
|
401
|
+
def inject_state(self, state: dict[str, Any], *, recursive: bool = False) -> None:
|
|
402
|
+
"""Merge external key-value pairs into this group's shared state.
|
|
403
|
+
|
|
404
|
+
Existing keys are NOT overwritten (uses setdefault semantics).
|
|
405
|
+
|
|
406
|
+
Args:
|
|
407
|
+
state: Key-value pairs to inject.
|
|
408
|
+
recursive: If True, also inject into nested sub-groups.
|
|
409
|
+
"""
|
|
410
|
+
for k, v in state.items():
|
|
411
|
+
self._state.setdefault(k, v)
|
|
412
|
+
if recursive:
|
|
413
|
+
for agent, _ in self._agents:
|
|
414
|
+
if hasattr(agent, "inject_state"):
|
|
415
|
+
agent.inject_state(state, recursive=True)
|
|
416
|
+
|
|
354
417
|
async def run(self, prompt: str = "") -> GroupResult:
|
|
355
418
|
"""Execute the loop (async)."""
|
|
356
419
|
self._stop_requested = False
|
|
@@ -2,9 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import copy
|
|
5
6
|
from typing import Any
|
|
6
7
|
|
|
7
8
|
|
|
9
|
+
def prepare_strict_schema(schema: dict[str, Any]) -> dict[str, Any]:
|
|
10
|
+
"""Prepare a JSON schema for OpenAI strict structured-output mode.
|
|
11
|
+
|
|
12
|
+
OpenAI's ``strict: true`` requires every object to have
|
|
13
|
+
``"additionalProperties": false`` and a ``"required"`` array listing
|
|
14
|
+
all property keys. This function recursively patches a schema copy
|
|
15
|
+
so callers don't need to worry about these constraints.
|
|
16
|
+
"""
|
|
17
|
+
schema = copy.deepcopy(schema)
|
|
18
|
+
_patch_strict(schema)
|
|
19
|
+
return schema
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _patch_strict(node: dict[str, Any]) -> None:
|
|
23
|
+
"""Recursively add strict-mode constraints to an object schema node."""
|
|
24
|
+
if node.get("type") == "object" and "properties" in node:
|
|
25
|
+
node.setdefault("additionalProperties", False)
|
|
26
|
+
node.setdefault("required", list(node["properties"].keys()))
|
|
27
|
+
for prop in node["properties"].values():
|
|
28
|
+
_patch_strict(prop)
|
|
29
|
+
elif node.get("type") == "array" and isinstance(node.get("items"), dict):
|
|
30
|
+
_patch_strict(node["items"])
|
|
31
|
+
|
|
32
|
+
|
|
8
33
|
class CostMixin:
|
|
9
34
|
"""Mixin that provides ``_calculate_cost`` to sync and async drivers.
|
|
10
35
|
|
|
@@ -11,7 +11,7 @@ except Exception:
|
|
|
11
11
|
AsyncAzureOpenAI = None
|
|
12
12
|
|
|
13
13
|
from ..async_driver import AsyncDriver
|
|
14
|
-
from ..cost_mixin import CostMixin
|
|
14
|
+
from ..cost_mixin import CostMixin, prepare_strict_schema
|
|
15
15
|
from .azure_driver import AzureDriver
|
|
16
16
|
|
|
17
17
|
|
|
@@ -89,12 +89,13 @@ class AsyncAzureDriver(CostMixin, AsyncDriver):
|
|
|
89
89
|
if options.get("json_mode"):
|
|
90
90
|
json_schema = options.get("json_schema")
|
|
91
91
|
if json_schema:
|
|
92
|
+
schema_copy = prepare_strict_schema(json_schema)
|
|
92
93
|
kwargs["response_format"] = {
|
|
93
94
|
"type": "json_schema",
|
|
94
95
|
"json_schema": {
|
|
95
96
|
"name": "extraction",
|
|
96
97
|
"strict": True,
|
|
97
|
-
"schema":
|
|
98
|
+
"schema": schema_copy,
|
|
98
99
|
},
|
|
99
100
|
}
|
|
100
101
|
else:
|
|
@@ -17,7 +17,7 @@ from typing import Any
|
|
|
17
17
|
import httpx
|
|
18
18
|
|
|
19
19
|
from ..async_driver import AsyncDriver
|
|
20
|
-
from ..cost_mixin import CostMixin
|
|
20
|
+
from ..cost_mixin import CostMixin, prepare_strict_schema
|
|
21
21
|
from .moonshot_driver import MoonshotDriver
|
|
22
22
|
|
|
23
23
|
|
|
@@ -88,12 +88,13 @@ class AsyncMoonshotDriver(CostMixin, AsyncDriver):
|
|
|
88
88
|
if options.get("json_mode"):
|
|
89
89
|
json_schema = options.get("json_schema")
|
|
90
90
|
if json_schema:
|
|
91
|
+
schema_copy = prepare_strict_schema(json_schema)
|
|
91
92
|
data["response_format"] = {
|
|
92
93
|
"type": "json_schema",
|
|
93
94
|
"json_schema": {
|
|
94
95
|
"name": "extraction",
|
|
95
96
|
"strict": True,
|
|
96
|
-
"schema":
|
|
97
|
+
"schema": schema_copy,
|
|
97
98
|
},
|
|
98
99
|
}
|
|
99
100
|
else:
|
|
@@ -13,7 +13,7 @@ except Exception:
|
|
|
13
13
|
AsyncOpenAI = None
|
|
14
14
|
|
|
15
15
|
from ..async_driver import AsyncDriver
|
|
16
|
-
from ..cost_mixin import CostMixin
|
|
16
|
+
from ..cost_mixin import CostMixin, prepare_strict_schema
|
|
17
17
|
from .openai_driver import OpenAIDriver
|
|
18
18
|
|
|
19
19
|
|
|
@@ -80,12 +80,13 @@ class AsyncOpenAIDriver(CostMixin, AsyncDriver):
|
|
|
80
80
|
if options.get("json_mode"):
|
|
81
81
|
json_schema = options.get("json_schema")
|
|
82
82
|
if json_schema:
|
|
83
|
+
schema_copy = prepare_strict_schema(json_schema)
|
|
83
84
|
kwargs["response_format"] = {
|
|
84
85
|
"type": "json_schema",
|
|
85
86
|
"json_schema": {
|
|
86
87
|
"name": "extraction",
|
|
87
88
|
"strict": True,
|
|
88
|
-
"schema":
|
|
89
|
+
"schema": schema_copy,
|
|
89
90
|
},
|
|
90
91
|
}
|
|
91
92
|
else:
|
|
@@ -10,7 +10,7 @@ from typing import Any
|
|
|
10
10
|
import httpx
|
|
11
11
|
|
|
12
12
|
from ..async_driver import AsyncDriver
|
|
13
|
-
from ..cost_mixin import CostMixin
|
|
13
|
+
from ..cost_mixin import CostMixin, prepare_strict_schema
|
|
14
14
|
from .openrouter_driver import OpenRouterDriver
|
|
15
15
|
|
|
16
16
|
|
|
@@ -78,12 +78,13 @@ class AsyncOpenRouterDriver(CostMixin, AsyncDriver):
|
|
|
78
78
|
if options.get("json_mode"):
|
|
79
79
|
json_schema = options.get("json_schema")
|
|
80
80
|
if json_schema:
|
|
81
|
+
schema_copy = prepare_strict_schema(json_schema)
|
|
81
82
|
data["response_format"] = {
|
|
82
83
|
"type": "json_schema",
|
|
83
84
|
"json_schema": {
|
|
84
85
|
"name": "extraction",
|
|
85
86
|
"strict": True,
|
|
86
|
-
"schema":
|
|
87
|
+
"schema": schema_copy,
|
|
87
88
|
},
|
|
88
89
|
}
|
|
89
90
|
else:
|
|
@@ -13,7 +13,7 @@ from typing import Any
|
|
|
13
13
|
import httpx
|
|
14
14
|
|
|
15
15
|
from ..async_driver import AsyncDriver
|
|
16
|
-
from ..cost_mixin import CostMixin
|
|
16
|
+
from ..cost_mixin import CostMixin, prepare_strict_schema
|
|
17
17
|
from .zai_driver import ZaiDriver
|
|
18
18
|
|
|
19
19
|
|
|
@@ -83,12 +83,13 @@ class AsyncZaiDriver(CostMixin, AsyncDriver):
|
|
|
83
83
|
if options.get("json_mode"):
|
|
84
84
|
json_schema = options.get("json_schema")
|
|
85
85
|
if json_schema:
|
|
86
|
+
schema_copy = prepare_strict_schema(json_schema)
|
|
86
87
|
data["response_format"] = {
|
|
87
88
|
"type": "json_schema",
|
|
88
89
|
"json_schema": {
|
|
89
90
|
"name": "extraction",
|
|
90
91
|
"strict": True,
|
|
91
|
-
"schema":
|
|
92
|
+
"schema": schema_copy,
|
|
92
93
|
},
|
|
93
94
|
}
|
|
94
95
|
else:
|
|
@@ -10,7 +10,7 @@ try:
|
|
|
10
10
|
except Exception:
|
|
11
11
|
AzureOpenAI = None
|
|
12
12
|
|
|
13
|
-
from ..cost_mixin import CostMixin
|
|
13
|
+
from ..cost_mixin import CostMixin, prepare_strict_schema
|
|
14
14
|
from ..driver import Driver
|
|
15
15
|
|
|
16
16
|
|
|
@@ -128,12 +128,13 @@ class AzureDriver(CostMixin, Driver):
|
|
|
128
128
|
if options.get("json_mode"):
|
|
129
129
|
json_schema = options.get("json_schema")
|
|
130
130
|
if json_schema:
|
|
131
|
+
schema_copy = prepare_strict_schema(json_schema)
|
|
131
132
|
kwargs["response_format"] = {
|
|
132
133
|
"type": "json_schema",
|
|
133
134
|
"json_schema": {
|
|
134
135
|
"name": "extraction",
|
|
135
136
|
"strict": True,
|
|
136
|
-
"schema":
|
|
137
|
+
"schema": schema_copy,
|
|
137
138
|
},
|
|
138
139
|
}
|
|
139
140
|
else:
|
|
@@ -16,7 +16,7 @@ from typing import Any
|
|
|
16
16
|
|
|
17
17
|
import requests
|
|
18
18
|
|
|
19
|
-
from ..cost_mixin import CostMixin
|
|
19
|
+
from ..cost_mixin import CostMixin, prepare_strict_schema
|
|
20
20
|
from ..driver import Driver
|
|
21
21
|
|
|
22
22
|
|
|
@@ -116,12 +116,13 @@ class MoonshotDriver(CostMixin, Driver):
|
|
|
116
116
|
if options.get("json_mode"):
|
|
117
117
|
json_schema = options.get("json_schema")
|
|
118
118
|
if json_schema:
|
|
119
|
+
schema_copy = prepare_strict_schema(json_schema)
|
|
119
120
|
data["response_format"] = {
|
|
120
121
|
"type": "json_schema",
|
|
121
122
|
"json_schema": {
|
|
122
123
|
"name": "extraction",
|
|
123
124
|
"strict": True,
|
|
124
|
-
"schema":
|
|
125
|
+
"schema": schema_copy,
|
|
125
126
|
},
|
|
126
127
|
}
|
|
127
128
|
else:
|
|
@@ -12,7 +12,7 @@ try:
|
|
|
12
12
|
except Exception:
|
|
13
13
|
OpenAI = None
|
|
14
14
|
|
|
15
|
-
from ..cost_mixin import CostMixin
|
|
15
|
+
from ..cost_mixin import CostMixin, prepare_strict_schema
|
|
16
16
|
from ..driver import Driver
|
|
17
17
|
|
|
18
18
|
|
|
@@ -125,12 +125,13 @@ class OpenAIDriver(CostMixin, Driver):
|
|
|
125
125
|
if options.get("json_mode"):
|
|
126
126
|
json_schema = options.get("json_schema")
|
|
127
127
|
if json_schema:
|
|
128
|
+
schema_copy = prepare_strict_schema(json_schema)
|
|
128
129
|
kwargs["response_format"] = {
|
|
129
130
|
"type": "json_schema",
|
|
130
131
|
"json_schema": {
|
|
131
132
|
"name": "extraction",
|
|
132
133
|
"strict": True,
|
|
133
|
-
"schema":
|
|
134
|
+
"schema": schema_copy,
|
|
134
135
|
},
|
|
135
136
|
}
|
|
136
137
|
else:
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Requires the `requests` package. Uses OPENROUTER_API_KEY env var.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
import contextlib
|
|
5
6
|
import json
|
|
6
7
|
import os
|
|
7
8
|
from collections.abc import Iterator
|
|
@@ -9,7 +10,7 @@ from typing import Any
|
|
|
9
10
|
|
|
10
11
|
import requests
|
|
11
12
|
|
|
12
|
-
from ..cost_mixin import CostMixin
|
|
13
|
+
from ..cost_mixin import CostMixin, prepare_strict_schema
|
|
13
14
|
from ..driver import Driver
|
|
14
15
|
|
|
15
16
|
|
|
@@ -128,12 +129,13 @@ class OpenRouterDriver(CostMixin, Driver):
|
|
|
128
129
|
if options.get("json_mode"):
|
|
129
130
|
json_schema = options.get("json_schema")
|
|
130
131
|
if json_schema:
|
|
132
|
+
schema_copy = prepare_strict_schema(json_schema)
|
|
131
133
|
data["response_format"] = {
|
|
132
134
|
"type": "json_schema",
|
|
133
135
|
"json_schema": {
|
|
134
136
|
"name": "extraction",
|
|
135
137
|
"strict": True,
|
|
136
|
-
"schema":
|
|
138
|
+
"schema": schema_copy,
|
|
137
139
|
},
|
|
138
140
|
}
|
|
139
141
|
else:
|
|
@@ -149,7 +151,13 @@ class OpenRouterDriver(CostMixin, Driver):
|
|
|
149
151
|
response.raise_for_status()
|
|
150
152
|
resp = response.json()
|
|
151
153
|
except requests.exceptions.HTTPError as e:
|
|
154
|
+
body = ""
|
|
155
|
+
if e.response is not None:
|
|
156
|
+
with contextlib.suppress(Exception):
|
|
157
|
+
body = e.response.text
|
|
152
158
|
error_msg = f"OpenRouter API request failed: {e!s}"
|
|
159
|
+
if body:
|
|
160
|
+
error_msg += f"\nResponse: {body}"
|
|
153
161
|
raise RuntimeError(error_msg) from e
|
|
154
162
|
except requests.exceptions.RequestException as e:
|
|
155
163
|
raise RuntimeError(f"OpenRouter API request failed: {e!s}") from e
|
|
@@ -12,7 +12,7 @@ from typing import Any
|
|
|
12
12
|
|
|
13
13
|
import requests
|
|
14
14
|
|
|
15
|
-
from ..cost_mixin import CostMixin
|
|
15
|
+
from ..cost_mixin import CostMixin, prepare_strict_schema
|
|
16
16
|
from ..driver import Driver
|
|
17
17
|
|
|
18
18
|
|
|
@@ -96,12 +96,13 @@ class ZaiDriver(CostMixin, Driver):
|
|
|
96
96
|
if options.get("json_mode"):
|
|
97
97
|
json_schema = options.get("json_schema")
|
|
98
98
|
if json_schema:
|
|
99
|
+
schema_copy = prepare_strict_schema(json_schema)
|
|
99
100
|
data["response_format"] = {
|
|
100
101
|
"type": "json_schema",
|
|
101
102
|
"json_schema": {
|
|
102
103
|
"name": "extraction",
|
|
103
104
|
"strict": True,
|
|
104
|
-
"schema":
|
|
105
|
+
"schema": schema_copy,
|
|
105
106
|
},
|
|
106
107
|
}
|
|
107
108
|
else:
|
|
@@ -114,6 +114,27 @@ class SequentialGroup:
|
|
|
114
114
|
"""Request graceful shutdown after the current agent finishes."""
|
|
115
115
|
self._stop_requested = True
|
|
116
116
|
|
|
117
|
+
@property
|
|
118
|
+
def shared_state(self) -> dict[str, Any]:
|
|
119
|
+
"""Return a copy of the current shared execution state."""
|
|
120
|
+
return dict(self._state)
|
|
121
|
+
|
|
122
|
+
def inject_state(self, state: dict[str, Any], *, recursive: bool = False) -> None:
|
|
123
|
+
"""Merge external key-value pairs into this group's shared state.
|
|
124
|
+
|
|
125
|
+
Existing keys are NOT overwritten (uses setdefault semantics).
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
state: Key-value pairs to inject.
|
|
129
|
+
recursive: If True, also inject into nested sub-groups.
|
|
130
|
+
"""
|
|
131
|
+
for k, v in state.items():
|
|
132
|
+
self._state.setdefault(k, v)
|
|
133
|
+
if recursive:
|
|
134
|
+
for agent, _ in self._agents:
|
|
135
|
+
if hasattr(agent, "inject_state"):
|
|
136
|
+
agent.inject_state(state, recursive=True)
|
|
137
|
+
|
|
117
138
|
def save(self, path: str) -> None:
|
|
118
139
|
"""Run and save result to file. Convenience wrapper."""
|
|
119
140
|
result = self.run()
|
|
@@ -267,6 +288,27 @@ class LoopGroup:
|
|
|
267
288
|
"""Request graceful shutdown."""
|
|
268
289
|
self._stop_requested = True
|
|
269
290
|
|
|
291
|
+
@property
|
|
292
|
+
def shared_state(self) -> dict[str, Any]:
|
|
293
|
+
"""Return a copy of the current shared execution state."""
|
|
294
|
+
return dict(self._state)
|
|
295
|
+
|
|
296
|
+
def inject_state(self, state: dict[str, Any], *, recursive: bool = False) -> None:
|
|
297
|
+
"""Merge external key-value pairs into this group's shared state.
|
|
298
|
+
|
|
299
|
+
Existing keys are NOT overwritten (uses setdefault semantics).
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
state: Key-value pairs to inject.
|
|
303
|
+
recursive: If True, also inject into nested sub-groups.
|
|
304
|
+
"""
|
|
305
|
+
for k, v in state.items():
|
|
306
|
+
self._state.setdefault(k, v)
|
|
307
|
+
if recursive:
|
|
308
|
+
for agent, _ in self._agents:
|
|
309
|
+
if hasattr(agent, "inject_state"):
|
|
310
|
+
agent.inject_state(state, recursive=True)
|
|
311
|
+
|
|
270
312
|
def run(self, prompt: str = "") -> GroupResult:
|
|
271
313
|
"""Execute the loop."""
|
|
272
314
|
self._stop_requested = False
|
|
File without changes
|
{prompture-0.0.41.dev1 → prompture-0.0.42}/.claude/skills/add-driver/references/driver-template.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|