Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
896d432
docs(designs): add evaluation filtering, package architecture, and ET…
ardaerzin May 16, 2026
dabed3f
docs(designs): performance corrections, eviction promotion, and four …
ardaerzin May 17, 2026
2c51add
docs(designs): split etl engine into general + eval consumer, add fil…
ardaerzin May 17, 2026
7f5b7d1
docs(designs): add headless PoC strategy to etl-engine RFC
ardaerzin May 17, 2026
0e927d8
feat(@agenta/entities/etl): scaffold loop engine + verify real entiti…
ardaerzin May 17, 2026
3a13b86
test(etl): scope A — memory bound + overhead assertions
ardaerzin May 17, 2026
1d178b8
test(etl): scope B — per-scenario benchmarks + long-run leak detectio…
ardaerzin May 17, 2026
df2c5d4
poc + docs: clarify "scanned" semantics + add chunk-size sizing guidance
ardaerzin May 18, 2026
006fe31
poc + docs: rows-per-RTT, network instrumentation, cursor robustness,…
ardaerzin May 18, 2026
da794a0
feat(entities): Node-safe api+core+state layers + EvaluationMetric API
ardaerzin May 18, 2026
b150381
feat(entities): hydrateScenariosTransform with pluggable HydrateFetchers
ardaerzin May 18, 2026
0b28bd5
feat(entities): resolveMappings — declarative column resolution + gro…
ardaerzin May 18, 2026
3e892f3
feat(entities): result/metric molecules + cache-aware prefetch + leak…
ardaerzin May 18, 2026
d2e4ed8
feat(entities): instrumentedAtomFamily + paginated store dispose() + …
ardaerzin May 18, 2026
4019c21
feat(entities): rowPredicateFilter + hitRatioMeter (v1 filter + v2 es…
ardaerzin May 18, 2026
541f42d
feat(poc): integrate ETL PoC end-to-end against real backend
ardaerzin May 18, 2026
83177a6
chore(poc): move etl-poc-entities.ts to entities package
ardaerzin May 18, 2026
bcaa047
feat(entities): findInTrace handles {count, traces} envelope shape
ardaerzin May 19, 2026
b19a4a9
feat(entities): symmetric prefetch surface across 4 ETL-hydrated enti…
ardaerzin May 19, 2026
6ce2f40
feat(entities): predicateToEntitySlices — filter-aware hydrate signal
ardaerzin May 19, 2026
ef0f57e
feat(poc): sink modes + heap walk + slice-filter A/B knob
ardaerzin May 19, 2026
2f54ea7
feat(oss): /etl-poc test page — IVT mounted on entities-package ETL p…
ardaerzin May 19, 2026
7f3ce18
feat(oss): Auto mode = pure on-demand hydrate (no-predicate → 0 page …
ardaerzin May 19, 2026
9a69556
fix(oss): viewport-fill loop for client-side filtered tables
ardaerzin May 19, 2026
0b0acd5
fix(oss): useCellMaterialization batched drains never fire
ardaerzin May 19, 2026
4b14c79
feat(oss): page-load lookahead prefetch for smooth-scroll UX
ardaerzin May 19, 2026
348c5d8
fix(oss): lookahead targets filteredRows, not pagination.rows
ardaerzin May 19, 2026
1237552
fix(oss): filteredRows reactive to hydrationVersion — purge stale mat…
ardaerzin May 19, 2026
d22dae8
fix(entities,oss): drop traces from evaluator-annotation slice set + …
ardaerzin May 19, 2026
be93ecc
fix(oss): stop infinite refetch loop when slice fetch returns empty (…
ardaerzin May 19, 2026
6640d67
fix(oss): reset scroll to top on predicate change
ardaerzin May 19, 2026
7d30033
feat(ee): re-export /etl-poc test page for EE web
ardaerzin May 20, 2026
f514ccc
Merge branch 'release/v0.100.0' into fe-experiment/etl-poc
ardaerzin May 20, 2026
56bcd5f
fix(entities): add missing comma in package.json scripts
ardaerzin May 20, 2026
2b4a9f8
Merge branch 'release/v0.100.0' into fe-experiment/etl-poc
ardaerzin May 20, 2026
3d73f5f
[fix] Resolve broken CORS headers
jp-agenta May 20, 2026
cae7a4c
v0.100.1
junaway May 20, 2026
62e303e
Merge branch 'release/v0.100.1' into fix/broken-exposed-cors-headers
junaway May 20, 2026
17884b9
Add missing check
jp-agenta May 20, 2026
14f43c1
Merge pull request #4381 from Agenta-AI/fix/broken-exposed-cors-headers
junaway May 20, 2026
2a6c2bd
Merge branch 'release/v0.100.1' into fe-experiment/etl-poc
ardaerzin May 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion api/entrypoints/routers.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,6 @@ async def lifespan(*args, **kwargs):
allow_credentials=True,
allow_methods=["*"],
allow_headers=["Content-Type"] + get_all_supertokens_cors_headers(),
expose_headers=["front-token", "x-ag-support-id", "x-ag-support-ts"],
)

if ee and is_ee():
Expand Down
31 changes: 31 additions & 0 deletions api/oss/src/apis/fastapi/shared/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,31 @@
from oss.src.utils.context import support_ctx


def _expose_support_headers(
headers: List[Tuple[bytes, bytes]],
exposed: List[bytes],
) -> None:
"""Add `exposed` to Access-Control-Expose-Headers so browser JS can read
the support headers. Done here, not in the CORS config, because listing
them there broke the `--web-local` cross-origin setup. CORS leaves this
header alone (its own `expose_headers` is unset), so we won't be clobbered.
"""
name = b"access-control-expose-headers"

for index, (key, value) in enumerate(headers):
if key.lower() == name:
existing = {
part.strip().lower() for part in value.split(b",") if part.strip()
}
additions = [h for h in exposed if h.lower() not in existing]
if additions:
merged = value + b", " + b", ".join(additions)
headers[index] = (key, merged)
return

headers.append((name, b", ".join(exposed)))


class SupportHeadersMiddleware:
"""Pure-ASGI middleware that emits x-ag-support-* headers when
a downstream decorator stashes support metadata in `support_ctx`.
Expand All @@ -34,20 +59,26 @@ async def send_with_support(message):
support = support_ctx.get()
if support is not None:
headers = list(message.get("headers", []))
exposed: List[bytes] = []
if support.support_id:
headers.append(
(
b"x-ag-support-id",
support.support_id.encode("latin-1"),
)
)
exposed.append(b"x-ag-support-id")
if support.support_ts:
headers.append(
(
b"x-ag-support-ts",
support.support_ts.isoformat().encode("latin-1"),
)
)
exposed.append(b"x-ag-support-ts")
# Make the headers we just emitted readable by browser JS.
if exposed:
_expose_support_headers(headers, exposed)
message["headers"] = headers
await send(message)

Expand Down
43 changes: 43 additions & 0 deletions api/oss/tests/pytest/unit/utils/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,46 @@ def test_support_headers_survive_base_http_middleware():
assert response.status_code == 200
assert "x-ag-support-id" in response.headers
assert "x-ag-support-ts" in response.headers


def _build_test_app_with_cors() -> FastAPI:
# Mirrors the production wiring: CORSMiddleware (added last, so outermost)
# wraps SupportHeadersMiddleware (added first, innermost). The support
# middleware must declare its headers in Access-Control-Expose-Headers
# itself, because the CORS layer intentionally does NOT list them
# (doing so broke the `--web-local` cross-origin setup).
from starlette.middleware.cors import CORSMiddleware

app = FastAPI()
app.add_middleware(SupportHeadersMiddleware)
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["Content-Type"],
)

@app.get("/fail")
@suppress_exceptions(default={"count": 0}, verbose=False)
async def fail(request: Request):
raise RuntimeError("boom")

return app


def test_support_headers_exposed_to_allowed_cross_origin():
client = TestClient(_build_test_app_with_cors())

response = client.get("/fail", headers={"Origin": "http://localhost:3000"})

assert response.status_code == 200
# CORS still mirrors the allowed origin — the regression that the commented
# `expose_headers` CORS config caused for `--web-local`.
assert response.headers["access-control-allow-origin"] == "http://localhost:3000"
# Support headers are both emitted and readable by browser JS.
assert "x-ag-support-id" in response.headers
assert "x-ag-support-ts" in response.headers
expose = response.headers["access-control-expose-headers"].lower()
assert "x-ag-support-id" in expose
assert "x-ag-support-ts" in expose
2 changes: 1 addition & 1 deletion api/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "api"
version = "0.100.0"
version = "0.100.1"
description = "Agenta API"
requires-python = ">=3.11,<3.14"
authors = [
Expand Down
6 changes: 3 additions & 3 deletions api/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion clients/python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "agenta-client"
version = "0.100.0"
version = "0.100.1"
description = "Fern-generated Python client for the Agenta API."
requires-python = ">=3.11,<3.14"
authors = [
Expand Down
2 changes: 1 addition & 1 deletion clients/python/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading