diff --git a/agents/fce.py b/agents/fce.py index 8bf58f6..7d4525a 100644 --- a/agents/fce.py +++ b/agents/fce.py @@ -18,7 +18,7 @@ async def run_fce( flight_id: str, mcp: MCPMultiClient, on_event: Any = None, - langfuse: Any = None, + lf: Any = None, ) -> dict: run_start = time.time() errors = [] @@ -67,10 +67,10 @@ async def run_fce( async def _call(server, tool, args, is_live=False, timeout=15.0): t = time.time() - ctx = langfuse.start_as_current_observation( - name=tool, as_type="tool", - input=args, metadata={"server": server, "is_live": is_live}, - ) if langfuse else None + ctx = lf.start_as_current_observation( + name=tool, as_type="tool", input=args, + metadata={"server": server, "is_live": is_live}, + ) if lf else None if ctx: ctx.__enter__() try: @@ -79,14 +79,14 @@ async def run_fce( ) lat = int((time.time() - t) * 1000) if ctx: - langfuse.update_current_span(output=result, metadata={"latency_ms": lat}) + lf.update_current_span(output=result, metadata={"latency_ms": lat}) ctx.__exit__(None, None, None) await emit("tool_call_end", tool=tool, latency_ms=lat, is_live=is_live) return result except asyncio.TimeoutError: lat = int((time.time() - t) * 1000) if ctx: - langfuse.update_current_span(output={"error": "timeout"}, level="ERROR") + lf.update_current_span(output={"error": "timeout"}, level="ERROR") ctx.__exit__(None, None, None) await emit("tool_call_error", tool=tool, error="timeout", latency_ms=lat) errors.append(f"{tool}: timeout after {timeout}s") @@ -94,7 +94,7 @@ async def run_fce( except Exception as e: lat = int((time.time() - t) * 1000) if ctx: - langfuse.update_current_span(output={"error": str(e)}, level="ERROR") + lf.update_current_span(output={"error": str(e)}, level="ERROR") ctx.__exit__(None, None, None) await emit("tool_call_error", tool=tool, error=str(e), latency_ms=lat) errors.append(f"{tool}: {e}") diff --git a/agents/handover.py b/agents/handover.py index 110f3e5..0d0f229 100644 --- a/agents/handover.py +++ b/agents/handover.py @@ -26,7 +26,7 @@ async def run_handover( hubs: list[str] | None = None, mcp: MCPMultiClient | None = None, on_event: Any = None, - langfuse: Any = None, + lf: Any = None, ) -> dict: target_hubs = hubs or ALL_HUBS run_start = time.time() @@ -45,10 +45,10 @@ async def run_handover( async def _call(server, tool, args, is_live=False, timeout=15.0): t = time.time() - ctx = langfuse.start_as_current_observation( - name=tool, as_type="tool", - input=args, metadata={"server": server, "is_live": is_live}, - ) if langfuse else None + ctx = lf.start_as_current_observation( + name=tool, as_type="tool", input=args, + metadata={"server": server, "is_live": is_live}, + ) if lf else None if ctx: ctx.__enter__() try: @@ -57,14 +57,14 @@ async def run_handover( ) lat = int((time.time() - t) * 1000) if ctx: - langfuse.update_current_span(output=result, metadata={"latency_ms": lat}) + lf.update_current_span(output=result, metadata={"latency_ms": lat}) ctx.__exit__(None, None, None) await emit("tool_call_end", tool=tool, latency_ms=lat, is_live=is_live) return result except asyncio.TimeoutError: lat = int((time.time() - t) * 1000) if ctx: - langfuse.update_current_span(output={"error": "timeout"}, level="ERROR") + lf.update_current_span(output={"error": "timeout"}, level="ERROR") ctx.__exit__(None, None, None) await emit("tool_call_error", tool=tool, error="timeout", latency_ms=lat) errors.append(f"{tool}: timeout after {timeout}s") @@ -72,7 +72,7 @@ async def run_handover( except Exception as e: lat = int((time.time() - t) * 1000) if ctx: - langfuse.update_current_span(output={"error": str(e)}, level="ERROR") + lf.update_current_span(output={"error": str(e)}, level="ERROR") ctx.__exit__(None, None, None) await emit("tool_call_error", tool=tool, error=str(e), latency_ms=lat) errors.append(f"{tool}: {e}") diff --git a/api/main.py b/api/main.py index 4006d6e..3c01ae9 100644 --- a/api/main.py +++ b/api/main.py @@ -153,29 +153,29 @@ async def trigger_fce(req: FCERequest): async def on_event(event): await event_hub.broadcast({"run_id": run_id, **event}) - langfuse = _get_langfuse() + lf = _get_langfuse() try: - if langfuse: - with langfuse.start_as_current_observation( - name="fce", as_type="agent", - input={"flight_id": req.flight_id}, - metadata={"run_id": run_id, "scenario": scenario_manager.active_id}, - ): - async with connect_servers(["shared", "ops", "passenger"]) as mcp: - result = await run_fce(req.flight_id, mcp, on_event=on_event, langfuse=langfuse) - langfuse.set_current_trace_io(output=result) - else: - async with connect_servers(["shared", "ops", "passenger"]) as mcp: - result = await run_fce(req.flight_id, mcp, on_event=on_event) + ctx = lf.start_as_current_observation( + name="fce", as_type="agent", + input={"flight_id": req.flight_id}, + metadata={"run_id": run_id, "scenario": scenario_manager.active_id}, + ) if lf else None + if ctx: + ctx.__enter__() + async with connect_servers(["shared", "ops", "passenger"]) as mcp: + result = await run_fce(req.flight_id, mcp, on_event=on_event, lf=lf) runs[run_id] = {"status": "completed", "agent": "fce", "result": result} + if ctx: + lf.set_current_trace_io(output=result) + ctx.__exit__(None, None, None) logger.info("agent_complete agent=fce run_id=%s flight=%s", run_id, req.flight_id) except Exception as e: runs[run_id] = {"status": "error", "agent": "fce", "error": str(e)} logger.error("agent_error agent=fce run_id=%s error=%s", run_id, e) finally: - if langfuse: - langfuse.flush() + if lf: + lf.shutdown() logger.info("agent_start agent=fce run_id=%s flight=%s", run_id, req.flight_id) asyncio.create_task(_run()) @@ -201,29 +201,29 @@ async def trigger_handover(req: HandoverRequest): async def on_event(event): await event_hub.broadcast({"run_id": run_id, **event}) - langfuse = _get_langfuse() + lf = _get_langfuse() try: - if langfuse: - with langfuse.start_as_current_observation( - name="handover", as_type="agent", - input={"hubs": req.hubs}, - metadata={"run_id": run_id, "scenario": scenario_manager.active_id}, - ): - async with connect_servers(["shared", "ops"]) as mcp: - result = await run_handover(hubs=req.hubs, mcp=mcp, on_event=on_event, langfuse=langfuse) - langfuse.set_current_trace_io(output=result) - else: - async with connect_servers(["shared", "ops"]) as mcp: - result = await run_handover(hubs=req.hubs, mcp=mcp, on_event=on_event) + ctx = lf.start_as_current_observation( + name="handover", as_type="agent", + input={"hubs": req.hubs}, + metadata={"run_id": run_id, "scenario": scenario_manager.active_id}, + ) if lf else None + if ctx: + ctx.__enter__() + async with connect_servers(["shared", "ops"]) as mcp: + result = await run_handover(hubs=req.hubs, mcp=mcp, on_event=on_event, lf=lf) runs[run_id] = {"status": "completed", "agent": "handover", "result": result} + if ctx: + lf.set_current_trace_io(output=result) + ctx.__exit__(None, None, None) logger.info("agent_complete agent=handover run_id=%s hubs=%s", run_id, req.hubs) except Exception as e: runs[run_id] = {"status": "error", "agent": "handover", "error": str(e)} logger.error("agent_error agent=handover run_id=%s error=%s", run_id, e) finally: - if langfuse: - langfuse.flush() + if lf: + lf.shutdown() logger.info("agent_start agent=handover run_id=%s hubs=%s", run_id, req.hubs) asyncio.create_task(_run()) diff --git a/ctrl/Dockerfile.api b/ctrl/Dockerfile.api index 0f5a688..441f7ff 100644 --- a/ctrl/Dockerfile.api +++ b/ctrl/Dockerfile.api @@ -10,6 +10,6 @@ RUN uv sync --no-dev --no-install-project COPY mcp_servers/ mcp_servers/ COPY agents/ agents/ COPY api/ api/ -COPY irrop/ irrop/ + CMD ["uv", "run", "uvicorn", "api.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] diff --git a/ctrl/k8s/base/clickhouse.yaml b/ctrl/k8s/base/clickhouse.yaml new file mode 100644 index 0000000..6d26f66 --- /dev/null +++ b/ctrl/k8s/base/clickhouse.yaml @@ -0,0 +1,48 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: clickhouse + namespace: unt +spec: + replicas: 1 + selector: + matchLabels: + app: clickhouse + template: + metadata: + labels: + app: clickhouse + spec: + containers: + - name: clickhouse + image: clickhouse/clickhouse-server:24-alpine + ports: + - containerPort: 8123 + - containerPort: 9000 + env: + - name: CLICKHOUSE_USER + value: "default" + - name: CLICKHOUSE_PASSWORD + value: "clickhouse" + resources: + requests: + memory: 256Mi + cpu: 100m + limits: + memory: 1Gi +--- +apiVersion: v1 +kind: Service +metadata: + name: clickhouse + namespace: unt +spec: + selector: + app: clickhouse + ports: + - name: http + port: 8123 + targetPort: 8123 + - name: native + port: 9000 + targetPort: 9000 diff --git a/ctrl/k8s/base/configmap.yaml b/ctrl/k8s/base/configmap.yaml index 5f2a8c5..602d1fd 100644 --- a/ctrl/k8s/base/configmap.yaml +++ b/ctrl/k8s/base/configmap.yaml @@ -9,6 +9,6 @@ data: GROQ_API_KEY: "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" GROQ_MODEL: "llama-3.3-70b-versatile" LANGFUSE_HOST: "http://langfuse:3000" - LANGFUSE_PUBLIC_KEY: "pk-lf-34928c5c-8525-4e1f-98be-d46c5bda6785" - LANGFUSE_SECRET_KEY: "sk-lf-e1f1e753-c9b9-476b-9caa-3fd6bb911b56" + LANGFUSE_PUBLIC_KEY: "pk-lf-6642fd68-e09b-4aa7-828d-5b13265703d8" + LANGFUSE_SECRET_KEY: "sk-lf-d6574b94-e63c-4bb8-8993-1f2db41a1bc0" KONG_PROXY_URL: "" diff --git a/ctrl/k8s/base/kustomization.yaml b/ctrl/k8s/base/kustomization.yaml index 54cff10..96dc4c5 100644 --- a/ctrl/k8s/base/kustomization.yaml +++ b/ctrl/k8s/base/kustomization.yaml @@ -7,6 +7,7 @@ resources: - namespace.yaml - configmap.yaml - postgres.yaml + - clickhouse.yaml - langfuse.yaml - api.yaml - ui.yaml diff --git a/ctrl/k8s/base/langfuse.yaml b/ctrl/k8s/base/langfuse.yaml index 9265faf..a224c39 100644 --- a/ctrl/k8s/base/langfuse.yaml +++ b/ctrl/k8s/base/langfuse.yaml @@ -15,16 +15,38 @@ spec: spec: containers: - name: langfuse - image: langfuse/langfuse:2 + image: langfuse/langfuse:3 ports: - containerPort: 3000 env: - name: DATABASE_URL value: "postgresql://langfuse:langfuse@postgres:5432/langfuse" + - name: CLICKHOUSE_URL + value: "http://clickhouse:8123" + - name: CLICKHOUSE_MIGRATION_URL + value: "clickhouse://clickhouse:9000" + - name: CLICKHOUSE_USER + value: "default" + - name: CLICKHOUSE_PASSWORD + value: "clickhouse" + - name: CLICKHOUSE_CLUSTER_ENABLED + value: "false" + - name: LANGFUSE_S3_EVENT_UPLOAD_ENABLED + value: "false" + - name: LANGFUSE_S3_EVENT_UPLOAD_BUCKET + value: "unused" + - name: LANGFUSE_S3_MEDIA_UPLOAD_ENABLED + value: "false" + - name: LANGFUSE_S3_MEDIA_UPLOAD_BUCKET + value: "unused" - name: NEXTAUTH_SECRET value: "unt-dev-secret" - name: NEXTAUTH_URL value: "http://localhost:3000" + - name: HOSTNAME + value: "0.0.0.0" + - name: AUTH_DISABLE_SIGNUP + value: "true" - name: SALT value: "unt-dev-salt-not-for-production-use" readinessProbe: diff --git a/ctrl/k8s/kind-config.yaml b/ctrl/k8s/kind-config.yaml index 7c316d3..68d47c8 100644 --- a/ctrl/k8s/kind-config.yaml +++ b/ctrl/k8s/kind-config.yaml @@ -12,5 +12,5 @@ nodes: # Langfuse observability - containerPort: 30030 hostPort: 3000 - listenAddress: "127.0.0.1" + listenAddress: "0.0.0.0" protocol: TCP diff --git a/irrop/__init__.py b/irrop/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/irrop/models/__init__.py b/irrop/models/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/irrop/pipeline/__init__.py b/irrop/pipeline/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/irrop/rules/__init__.py b/irrop/rules/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/uv.lock b/uv.lock index 11e1b56..2d03ab6 100644 --- a/uv.lock +++ b/uv.lock @@ -498,18 +498,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f5/48/84b6dcba793178a44b9d99b4def6cd62f870dcfc5bb7b9153ac390135812/fastmcp-3.2.3-py3-none-any.whl", hash = "sha256:cc50af6eed1f62ed8b6ebf4987286d8d1d006f08d5bec739d5c7fb76160e0911", size = 707260, upload-time = "2026-04-09T22:05:01.225Z" }, ] -[[package]] -name = "googleapis-common-protos" -version = "1.74.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "protobuf" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/20/18/a746c8344152d368a5aac738d4c857012f2c5d1fd2eac7e17b647a7861bd/googleapis_common_protos-1.74.0.tar.gz", hash = "sha256:57971e4eeeba6aad1163c1f0fc88543f965bb49129b8bb55b2b7b26ecab084f1", size = 151254, upload-time = "2026-04-02T21:23:26.679Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b6/b0/be5d3329badb9230b765de6eea66b73abd5944bdeb5afb3562ddcd80ae84/googleapis_common_protos-1.74.0-py3-none-any.whl", hash = "sha256:702216f78610bb510e3f12ac3cafd281b7ac45cc5d86e90ad87e4d301a3426b5", size = 300743, upload-time = "2026-04-02T21:22:49.108Z" }, -] - [[package]] name = "h11" version = "0.16.0" @@ -876,21 +864,21 @@ wheels = [ [[package]] name = "langfuse" -version = "4.2.0" +version = "2.60.10" source = { registry = "https://pypi.org/simple" } dependencies = [ + { name = "anyio" }, { name = "backoff" }, { name = "httpx" }, - { name = "opentelemetry-api" }, - { name = "opentelemetry-exporter-otlp-proto-http" }, - { name = "opentelemetry-sdk" }, + { name = "idna" }, { name = "packaging" }, { name = "pydantic" }, + { name = "requests" }, { name = "wrapt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/45/9c/b912a00ffae92ff9955cdd9b74fb839be58f631d4329ae2a8a0376f697f2/langfuse-4.2.0.tar.gz", hash = "sha256:d0bd26d5065cf6a59d7d1093b08d8910e2458dc3da7ed8ccec160db114c18342", size = 275582, upload-time = "2026-04-10T11:55:25.21Z" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/45/77fdf53c9e9f49bb78f72eba3f992f2f3d8343e05976aabfe1fca276a640/langfuse-2.60.10.tar.gz", hash = "sha256:a26d0d927a28ee01b2d12bb5b862590b643cc4e60a28de6e2b0c2cfff5dbfc6a", size = 152648, upload-time = "2025-09-16T15:08:12.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/be/0a/b84e3e68a690ccfe6d64953c572772c685fcb0915b7f2ee3a87c22e388ab/langfuse-4.2.0-py3-none-any.whl", hash = "sha256:bfd760bf10fd0228f297f6369436620f76d16b589de46393d65706b27e4e4082", size = 475449, upload-time = "2026-04-10T11:55:23.624Z" }, + { url = "https://files.pythonhosted.org/packages/76/69/08584fbd69e14398d3932a77d0c8d7e20389da3e6470210d6719afba2801/langfuse-2.60.10-py3-none-any.whl", hash = "sha256:815c6369194aa5b2a24f88eb9952f7c3fc863272c41e90642a71f3bc76f4a11f", size = 275568, upload-time = "2025-09-16T15:08:10.166Z" }, ] [[package]] @@ -1135,75 +1123,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/58/ee/99ab786653b3bda9c37ade7e24a7b607a1b1f696063172768417539d876d/opentelemetry_api-1.41.0-py3-none-any.whl", hash = "sha256:0e77c806e6a89c9e4f8d372034622f3e1418a11bdbe1c80a50b3d3397ad0fa4f", size = 69007, upload-time = "2026-04-09T14:38:11.833Z" }, ] -[[package]] -name = "opentelemetry-exporter-otlp-proto-common" -version = "1.41.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "opentelemetry-proto" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/8c/28/e8eca94966fe9a1465f6094dc5ddc5398473682180279c94020bc23b4906/opentelemetry_exporter_otlp_proto_common-1.41.0.tar.gz", hash = "sha256:966bbce537e9edb166154779a7c4f8ab6b8654a03a28024aeaf1a3eacb07d6ee", size = 20411, upload-time = "2026-04-09T14:38:36.572Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/26/c4/78b9bf2d9c1d5e494f44932988d9d91c51a66b9a7b48adf99b62f7c65318/opentelemetry_exporter_otlp_proto_common-1.41.0-py3-none-any.whl", hash = "sha256:7a99177bf61f85f4f9ed2072f54d676364719c066f6d11f515acc6c745c7acf0", size = 18366, upload-time = "2026-04-09T14:38:15.135Z" }, -] - -[[package]] -name = "opentelemetry-exporter-otlp-proto-http" -version = "1.41.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "googleapis-common-protos" }, - { name = "opentelemetry-api" }, - { name = "opentelemetry-exporter-otlp-proto-common" }, - { name = "opentelemetry-proto" }, - { name = "opentelemetry-sdk" }, - { name = "requests" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/19/63/d9f43cd75f3fabb7e01148c89cfa9491fc18f6580a6764c554ff7c953c46/opentelemetry_exporter_otlp_proto_http-1.41.0.tar.gz", hash = "sha256:dcd6e0686f56277db4eecbadd5262124e8f2cc739cadbc3fae3d08a12c976cf5", size = 24139, upload-time = "2026-04-09T14:38:38.128Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/64/b5/a214cd907eedc17699d1c2d602288ae17cb775526df04db3a3b3585329d2/opentelemetry_exporter_otlp_proto_http-1.41.0-py3-none-any.whl", hash = "sha256:a9c4ee69cce9c3f4d7ee736ad1b44e3c9654002c0816900abbafd9f3cf289751", size = 22673, upload-time = "2026-04-09T14:38:18.349Z" }, -] - -[[package]] -name = "opentelemetry-proto" -version = "1.41.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "protobuf" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e0/d9/08e3dc6156878713e8c811682bc76151f5fe1a3cb7f3abda3966fd56e71e/opentelemetry_proto-1.41.0.tar.gz", hash = "sha256:95d2e576f9fb1800473a3e4cfcca054295d06bdb869fda4dc9f4f779dc68f7b6", size = 45669, upload-time = "2026-04-09T14:38:45.978Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/49/8c/65ef7a9383a363864772022e822b5d5c6988e6f9dabeebb9278f5b86ebc3/opentelemetry_proto-1.41.0-py3-none-any.whl", hash = "sha256:b970ab537309f9eed296be482c3e7cca05d8aca8165346e929f658dbe153b247", size = 72074, upload-time = "2026-04-09T14:38:29.38Z" }, -] - -[[package]] -name = "opentelemetry-sdk" -version = "1.41.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "opentelemetry-api" }, - { name = "opentelemetry-semantic-conventions" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f8/0e/a586df1186f9f56b5a0879d52653effc40357b8e88fc50fe300038c3c08b/opentelemetry_sdk-1.41.0.tar.gz", hash = "sha256:7bddf3961131b318fc2d158947971a8e37e38b1cd23470cfb72b624e7cc108bd", size = 230181, upload-time = "2026-04-09T14:38:47.225Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/13/a7825118208cb32e6a4edcd0a99f925cbef81e77b3b0aedfd9125583c543/opentelemetry_sdk-1.41.0-py3-none-any.whl", hash = "sha256:a596f5687964a3e0d7f8edfdcf5b79cbca9c93c7025ebf5fb00f398a9443b0bd", size = 180214, upload-time = "2026-04-09T14:38:30.657Z" }, -] - -[[package]] -name = "opentelemetry-semantic-conventions" -version = "0.62b0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "opentelemetry-api" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a3/b0/c14f723e86c049b7bf8ff431160d982519b97a7be2857ed2247377397a24/opentelemetry_semantic_conventions-0.62b0.tar.gz", hash = "sha256:cbfb3c8fc259575cf68a6e1b94083cc35adc4a6b06e8cf431efa0d62606c0097", size = 145753, upload-time = "2026-04-09T14:38:48.274Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/58/6c/5e86fa1759a525ef91c2d8b79d668574760ff3f900d114297765eb8786cb/opentelemetry_semantic_conventions-0.62b0-py3-none-any.whl", hash = "sha256:0ddac1ce59eaf1a827d9987ab60d9315fb27aea23304144242d1fcad9e16b489", size = 231619, upload-time = "2026-04-09T14:38:32.394Z" }, -] - [[package]] name = "orjson" version = "3.11.8" @@ -1298,11 +1217,11 @@ wheels = [ [[package]] name = "packaging" -version = "26.0" +version = "24.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950, upload-time = "2024-11-08T09:47:47.202Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451, upload-time = "2024-11-08T09:47:44.722Z" }, ] [[package]] @@ -1332,21 +1251,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] -[[package]] -name = "protobuf" -version = "6.33.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/66/70/e908e9c5e52ef7c3a6c7902c9dfbb34c7e29c25d2f81ade3856445fd5c94/protobuf-6.33.6.tar.gz", hash = "sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135", size = 444531, upload-time = "2026-03-18T19:05:00.988Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/9f/2f509339e89cfa6f6a4c4ff50438db9ca488dec341f7e454adad60150b00/protobuf-6.33.6-cp310-abi3-win32.whl", hash = "sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3", size = 425739, upload-time = "2026-03-18T19:04:48.373Z" }, - { url = "https://files.pythonhosted.org/packages/76/5d/683efcd4798e0030c1bab27374fd13a89f7c2515fb1f3123efdfaa5eab57/protobuf-6.33.6-cp310-abi3-win_amd64.whl", hash = "sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326", size = 437089, upload-time = "2026-03-18T19:04:50.381Z" }, - { url = "https://files.pythonhosted.org/packages/5c/01/a3c3ed5cd186f39e7880f8303cc51385a198a81469d53d0fdecf1f64d929/protobuf-6.33.6-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a", size = 427737, upload-time = "2026-03-18T19:04:51.866Z" }, - { url = "https://files.pythonhosted.org/packages/ee/90/b3c01fdec7d2f627b3a6884243ba328c1217ed2d978def5c12dc50d328a3/protobuf-6.33.6-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2", size = 324610, upload-time = "2026-03-18T19:04:53.096Z" }, - { url = "https://files.pythonhosted.org/packages/9b/ca/25afc144934014700c52e05103c2421997482d561f3101ff352e1292fb81/protobuf-6.33.6-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3", size = 339381, upload-time = "2026-03-18T19:04:54.616Z" }, - { url = "https://files.pythonhosted.org/packages/16/92/d1e32e3e0d894fe00b15ce28ad4944ab692713f2e7f0a99787405e43533a/protobuf-6.33.6-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593", size = 323436, upload-time = "2026-03-18T19:04:55.768Z" }, - { url = "https://files.pythonhosted.org/packages/c4/72/02445137af02769918a93807b2b7890047c32bfb9f90371cbc12688819eb/protobuf-6.33.6-py3-none-any.whl", hash = "sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901", size = 170656, upload-time = "2026-03-18T19:04:59.826Z" }, -] - [[package]] name = "py-key-value-aio" version = "0.4.4"