agentlisp 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.
- agentlisp-2.0.0.dist-info/METADATA +482 -0
- agentlisp-2.0.0.dist-info/RECORD +36 -0
- agentlisp-2.0.0.dist-info/WHEEL +4 -0
- agentlisp-2.0.0.dist-info/entry_points.txt +3 -0
- agentlisp_runtime/__init__.py +29 -0
- agentlisp_runtime/cli.py +145 -0
- agentlisp_runtime/engine.py +253 -0
- agentlisp_runtime/loader.py +126 -0
- agentlisp_runtime/models.py +129 -0
- host/__init__.py +5 -0
- host/gateway.py +128 -0
- host/gateway_sse.py +788 -0
- host/sandbox.py +143 -0
- host/sandbox_e2b.py +173 -0
- host/tests/test_infra_docker_e2e.py +247 -0
- host/workflow.py +803 -0
- host/workflow_temporal.py +89 -0
- runtime/__init__.py +29 -0
- runtime/base_agent_harness.py +164 -0
- runtime/base_harness.py +359 -0
- runtime/base_harness_v2.py +1379 -0
- runtime/checker.py +654 -0
- runtime/checkpoint.py +98 -0
- runtime/errors.py +37 -0
- runtime/llm_client.py +644 -0
- runtime/mcp_client.py +86 -0
- runtime/memory_fs.py +90 -0
- runtime/otel_tracer.py +124 -0
- runtime/status_bar.py +86 -0
- runtime/tests/test_ac1_rackunit_18cases_roundtrip.py +255 -0
- runtime/tests/test_cli_if_cli_1_exit_encoding.py +309 -0
- runtime/tests/test_harness_v2.py +2030 -0
- runtime/tests/test_sideeffect_builtin_tools_racket_and_python_ssot_8_items_bitwise_equal.py +132 -0
- runtime/tests/test_srs_acceptance.py +1369 -0
- runtime/tests/test_t2_bench_dataset.py +86 -0
- runtime/tests/test_v2_smoke.py +139 -0
host/gateway.py
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"""FastAPI HTTP + SSE gateway skeleton.
|
|
2
|
+
|
|
3
|
+
Imports even without optional web deps installed (raises FeatureNotInstalledError only
|
|
4
|
+
when constructing the app; import-level smoke stays green).
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
from collections.abc import AsyncIterable
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from runtime.base_harness import BaseHarness, ExecutionTrace
|
|
14
|
+
from runtime.errors import FeatureNotInstalledError
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Gateway:
|
|
18
|
+
"""Lazy FastAPI container. Builds the app only when `app` is accessed; imports fail
|
|
19
|
+
only if optional dep group `web` is missing and user actually instantiates it."""
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self,
|
|
23
|
+
harness_registry: dict[str, BaseHarness] | None = None,
|
|
24
|
+
) -> None:
|
|
25
|
+
self.registry: dict[str, BaseHarness] = harness_registry or {}
|
|
26
|
+
self.traces: dict[str, ExecutionTrace] = {}
|
|
27
|
+
self._app: Any | None = None
|
|
28
|
+
|
|
29
|
+
def register(self, name: str, harness: BaseHarness) -> None:
|
|
30
|
+
self.registry[name] = harness
|
|
31
|
+
|
|
32
|
+
# --------------------------------------------------------- FastAPI lazy build
|
|
33
|
+
@property
|
|
34
|
+
def app(self) -> Any:
|
|
35
|
+
if self._app is None:
|
|
36
|
+
try:
|
|
37
|
+
from fastapi import FastAPI, HTTPException
|
|
38
|
+
from fastapi.responses import StreamingResponse
|
|
39
|
+
from pydantic import BaseModel as _BM # noqa: N814
|
|
40
|
+
except ImportError as exc: # pragma: no cover
|
|
41
|
+
raise FeatureNotInstalledError("FastAPI gateway", "web") from exc
|
|
42
|
+
|
|
43
|
+
app = FastAPI(
|
|
44
|
+
title="AgentLisp Gateway",
|
|
45
|
+
version="2.0.0",
|
|
46
|
+
description="HTTP/SSE gateway for AgentLisp v2 compiled harnesses",
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
class RunRequest(_BM):
|
|
50
|
+
inputs: dict[str, Any] = {}
|
|
51
|
+
workflow: str | None = None
|
|
52
|
+
stream: bool = False
|
|
53
|
+
|
|
54
|
+
@app.get("/health", tags=["meta"])
|
|
55
|
+
async def health() -> dict[str, Any]:
|
|
56
|
+
return {
|
|
57
|
+
"status": "ok",
|
|
58
|
+
"agents": sorted(self.registry.keys()),
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@app.post("/v1/agents/{name}/run", tags=["agents"])
|
|
62
|
+
async def run_agent(name: str, req: RunRequest):
|
|
63
|
+
if name not in self.registry:
|
|
64
|
+
raise HTTPException(status_code=404, detail=f"agent not found: {name}")
|
|
65
|
+
if req.stream:
|
|
66
|
+
trace_ref: dict[str, Any] = {}
|
|
67
|
+
|
|
68
|
+
async def _events() -> AsyncIterable[str]:
|
|
69
|
+
harness = self.registry[name]
|
|
70
|
+
async for evt in harness.stream_async(inputs=req.inputs):
|
|
71
|
+
yield (
|
|
72
|
+
"data: " + json.dumps(evt, default=str, ensure_ascii=False) + "\n\n"
|
|
73
|
+
)
|
|
74
|
+
final = trace_ref.get("trace")
|
|
75
|
+
if final is not None:
|
|
76
|
+
yield (
|
|
77
|
+
"data: "
|
|
78
|
+
+ json.dumps(
|
|
79
|
+
{"event": "trace", "value": final.model_dump(mode="json")},
|
|
80
|
+
ensure_ascii=False,
|
|
81
|
+
default=str,
|
|
82
|
+
)
|
|
83
|
+
+ "\n\n"
|
|
84
|
+
)
|
|
85
|
+
yield "data: [DONE]\n\n"
|
|
86
|
+
|
|
87
|
+
return StreamingResponse(_events(), media_type="text/event-stream")
|
|
88
|
+
|
|
89
|
+
trace = await self.registry[name].run_async(
|
|
90
|
+
inputs=req.inputs, workflow=req.workflow
|
|
91
|
+
)
|
|
92
|
+
self.traces[trace.run_id] = trace
|
|
93
|
+
return trace.model_dump(mode="json")
|
|
94
|
+
|
|
95
|
+
@app.get("/v1/runs/{run_id}", tags=["runs"])
|
|
96
|
+
async def get_run(run_id: str):
|
|
97
|
+
t = self.traces.get(run_id)
|
|
98
|
+
if t is None:
|
|
99
|
+
raise HTTPException(status_code=404, detail="run not found")
|
|
100
|
+
return t.model_dump(mode="json")
|
|
101
|
+
|
|
102
|
+
self._app = app
|
|
103
|
+
return self._app
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
# ---------------------------------------------------------------- quick launcher
|
|
107
|
+
def serve(
|
|
108
|
+
gateway: Gateway,
|
|
109
|
+
*,
|
|
110
|
+
host: str = "0.0.0.0",
|
|
111
|
+
port: int = 8000,
|
|
112
|
+
uvicorn_kwargs: dict[str, Any] | None = None,
|
|
113
|
+
) -> None: # pragma: no cover
|
|
114
|
+
"""Convenience launcher. Requires 'web' optional group."""
|
|
115
|
+
try:
|
|
116
|
+
import uvicorn # type: ignore[import-not-found]
|
|
117
|
+
except ImportError as exc:
|
|
118
|
+
raise FeatureNotInstalledError("uvicorn launcher", "web") from exc
|
|
119
|
+
kwargs = uvicorn_kwargs or {}
|
|
120
|
+
uvicorn.run(gateway.app, host=host, port=port, **kwargs)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
if __name__ == "__main__": # pragma: no cover
|
|
124
|
+
from runtime.base_harness import BaseHarness
|
|
125
|
+
|
|
126
|
+
gw = Gateway()
|
|
127
|
+
gw.register("demo", BaseHarness(agent_cfg={"name": "demo", "purpose": "smoke"}))
|
|
128
|
+
serve(gw)
|