|
@@ -1,3 +1,4 @@
|
|
|
|
|
+import asyncio
|
|
|
import hashlib
|
|
import hashlib
|
|
|
import json
|
|
import json
|
|
|
import tempfile
|
|
import tempfile
|
|
@@ -22,6 +23,10 @@ from cyber_agent.application import (
|
|
|
ToolSpec,
|
|
ToolSpec,
|
|
|
)
|
|
)
|
|
|
from cyber_agent.application.models import canonical_json
|
|
from cyber_agent.application.models import canonical_json
|
|
|
|
|
+from cyber_agent.application.bootstrap import (
|
|
|
|
|
+ APPLICATION_FACTORIES_ENV,
|
|
|
|
|
+ build_runtime_from_environment,
|
|
|
|
|
+)
|
|
|
from cyber_agent.core.context_policy import (
|
|
from cyber_agent.core.context_policy import (
|
|
|
ContextPolicyError,
|
|
ContextPolicyError,
|
|
|
build_child_context_access,
|
|
build_child_context_access,
|
|
@@ -41,6 +46,7 @@ from cyber_agent.trace.models import Trace
|
|
|
from cyber_agent.trace.run_api import (
|
|
from cyber_agent.trace.run_api import (
|
|
|
CreateRequest,
|
|
CreateRequest,
|
|
|
_restore_runner_and_config,
|
|
_restore_runner_and_config,
|
|
|
|
|
+ create_and_run,
|
|
|
set_application_runtime,
|
|
set_application_runtime,
|
|
|
)
|
|
)
|
|
|
from cyber_agent.trace.store import FileSystemTraceStore
|
|
from cyber_agent.trace.store import FileSystemTraceStore
|
|
@@ -186,6 +192,25 @@ class ApplicationRuntimeIntegrationTest(unittest.IsolatedAsyncioTestCase):
|
|
|
self.assertEqual(1, self.provider.list_calls)
|
|
self.assertEqual(1, self.provider.list_calls)
|
|
|
self.assertEqual(1, self.provider.resolve_calls)
|
|
self.assertEqual(1, self.provider.resolve_calls)
|
|
|
|
|
|
|
|
|
|
+ async def test_application_http_handler_uses_the_bound_runtime(self):
|
|
|
|
|
+ with patch.dict("os.environ", {"AGENT_MODE": "recursive"}, clear=False):
|
|
|
|
|
+ response = await create_and_run(CreateRequest(
|
|
|
|
|
+ messages=[{"role": "user", "content": "Start through HTTP"}],
|
|
|
|
|
+ application_id="creative.reference",
|
|
|
|
|
+ application_version="0.1.0",
|
|
|
|
|
+ uid="http-user",
|
|
|
|
|
+ root_task_anchor=ROOT_ANCHOR,
|
|
|
|
|
+ ))
|
|
|
|
|
+ trace = await self.store.get_trace(response.trace_id)
|
|
|
|
|
+ self.assertIsNotNone(trace)
|
|
|
|
|
+ snapshot = load_run_config_snapshot(trace.context)
|
|
|
|
|
+ self.assertIsInstance(snapshot, RunConfigSnapshotV2)
|
|
|
|
|
+ self.assertEqual(
|
|
|
|
|
+ self.binding.application_ref.model_dump(mode="json"),
|
|
|
|
|
+ snapshot.application_ref,
|
|
|
|
|
+ )
|
|
|
|
|
+ await asyncio.sleep(0)
|
|
|
|
|
+
|
|
|
async def test_restore_rejects_registry_hash_and_trace_binding_tampering(self):
|
|
async def test_restore_rejects_registry_hash_and_trace_binding_tampering(self):
|
|
|
trace, base_runner, _config = await self._create_trace()
|
|
trace, base_runner, _config = await self._create_trace()
|
|
|
changed_registry = ApplicationRegistry()
|
|
changed_registry = ApplicationRegistry()
|
|
@@ -380,6 +405,28 @@ class ApplicationCreateRequestTest(unittest.TestCase):
|
|
|
application_version="0.1.0",
|
|
application_version="0.1.0",
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
+ def test_deployment_factory_builds_the_http_runtime_registry(self):
|
|
|
|
|
+ with tempfile.TemporaryDirectory() as temp_dir:
|
|
|
|
|
+ store = FileSystemTraceStore(temp_dir)
|
|
|
|
|
+ runtime = build_runtime_from_environment(
|
|
|
|
|
+ trace_store=store,
|
|
|
|
|
+ llm_call=unused_llm,
|
|
|
|
|
+ environ={
|
|
|
|
|
+ APPLICATION_FACTORIES_ENV: (
|
|
|
|
|
+ "examples.application_reference.application:"
|
|
|
|
|
+ "build_reference_components"
|
|
|
|
|
+ ),
|
|
|
|
|
+ },
|
|
|
|
|
+ )
|
|
|
|
|
+ self.assertIsNotNone(runtime)
|
|
|
|
|
+ binding = runtime.registry.resolve("application_reference", "1")
|
|
|
|
|
+ self.assertEqual("editor", binding.application.root_role)
|
|
|
|
|
+ self.assertIsNone(build_runtime_from_environment(
|
|
|
|
|
+ trace_store=store,
|
|
|
|
|
+ llm_call=unused_llm,
|
|
|
|
|
+ environ={},
|
|
|
|
|
+ ))
|
|
|
|
|
+
|
|
|
|
|
|
|
|
def _tool_names(schemas):
|
|
def _tool_names(schemas):
|
|
|
return {item["function"]["name"] for item in schemas or []}
|
|
return {item["function"]["name"] for item in schemas or []}
|
|
@@ -455,7 +502,18 @@ class ApplicationChildPropagationTest(unittest.IsolatedAsyncioTestCase):
|
|
|
),
|
|
),
|
|
|
),
|
|
),
|
|
|
tool_sets=(
|
|
tool_sets=(
|
|
|
- ToolSet(tool_set_id="root-tools", tools=declarations),
|
|
|
|
|
|
|
+ ToolSet(
|
|
|
|
|
+ tool_set_id="root-tools",
|
|
|
|
|
+ tools=tuple(
|
|
|
|
|
+ item
|
|
|
|
|
+ for item in declarations
|
|
|
|
|
+ if item.tool_name in {
|
|
|
|
|
+ "agent",
|
|
|
|
|
+ "update_task_progress",
|
|
|
|
|
+ "review_task_result",
|
|
|
|
|
+ }
|
|
|
|
|
+ ),
|
|
|
|
|
+ ),
|
|
|
ToolSet(
|
|
ToolSet(
|
|
|
tool_set_id="child-tools",
|
|
tool_set_id="child-tools",
|
|
|
tools=tuple(
|
|
tools=tuple(
|