diff --git a/agent_sdks/python/a2ui_agent/README.md b/agent_sdks/python/a2ui_agent/README.md
index e18deb7db0..7f26d935db 100644
--- a/agent_sdks/python/a2ui_agent/README.md
+++ b/agent_sdks/python/a2ui_agent/README.md
@@ -28,6 +28,13 @@ The following directories contain the base protocol logic, parsing, and schema o
- **`provider.py`**: Implementation of `BasicCatalog` for handling the basic
A2UI components.
+## Experimental Templates (`src/a2ui/inference_formats/experimental/template`)
+
+- **`models.py`**: Typed models (`StaticTemplate`, `DynamicTemplate`, `Param`, `ParamType`, AST expressions) and signature-based parameter inference.
+- **`processor.py`**: `TemplateProcessor` for generating synthetic inference catalogs and expanding template invocations into A2UI primitives.
+- **`format.py`**: `TemplateInferenceFormat` integrating template-aware prompt generation and synchronous parsing.
+- Reference schema: Located at `specification/proposals/templates/schema/template_definition.json`.
+
## A2A (`src/a2ui/a2a`)
- **`extension.py`**: Utilities for managing the A2UI extension URI and activation logic.
diff --git a/agent_sdks/python/a2ui_agent/pyproject.toml b/agent_sdks/python/a2ui_agent/pyproject.toml
index 0ef8ab3358..ef4e4d572b 100644
--- a/agent_sdks/python/a2ui_agent/pyproject.toml
+++ b/agent_sdks/python/a2ui_agent/pyproject.toml
@@ -25,7 +25,9 @@ dependencies = [
"google-adk>=1.28.1",
"google-genai>=1.27.0",
"httpx>=0.27.0",
- "jsonschema>=4.0.0"
+ "jsonschema>=4.0.0",
+ "nest-asyncio>=1.6.0",
+ "pyyaml>=6.0"
]
[project.scripts]
@@ -65,4 +67,5 @@ dev = [
"antlr4-tools>=0.2.1",
"hatchling>=1.30.1",
"types-jsonschema",
+ "types-pyyaml",
]
diff --git a/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/template/README.md b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/template/README.md
new file mode 100644
index 0000000000..81d8f2c70e
--- /dev/null
+++ b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/template/README.md
@@ -0,0 +1,124 @@
+# A2UI Python Template Engine (`a2ui.inference_formats.experimental.template`)
+
+The `a2ui.inference_formats.experimental.template` package provides server-side UI template expansion and synthetic catalog compilation for the A2UI Python Agent SDK.
+
+For the language-agnostic protocol specification, JSON schemas, and multi-platform design guidelines, see:
+👉 **[`specification/proposals/templates/README.md`](../../../../../../../../specification/proposals/templates/README.md)**
+
+---
+
+## Python API Reference
+
+### 1. `StaticTemplate`
+
+Represents a declarative, immutable UI template parsed from YAML or a dictionary.
+
+```python
+from a2ui.inference_formats.experimental.template import StaticTemplate
+
+# Load from single or multi-document ('---') YAML files
+templates = StaticTemplate.from_yaml_file("path/to/templates.yaml")
+
+# Load directly from a YAML string
+single_template = StaticTemplate.from_yaml(yaml_string)
+```
+
+### 2. `DynamicTemplate`
+
+Extends templates with server-side execution. Supports two modes:
+
+#### A. Data-Binding Mode (`resolver + layout`)
+
+Takes a lookup argument (e.g. `employeeId`), runs a resolver callback, and injects the result into a static YAML presentation layout:
+
+```python
+from a2ui.inference_formats.experimental.template import DynamicTemplate, StaticTemplate
+
+layout = StaticTemplate.from_yaml_file("salary_card.yaml")[0]
+
+def resolve_compensation(employeeId: str) -> dict:
+ return db.fetch_employee_salary(employeeId)
+
+dynamic_salary = DynamicTemplate(
+ template_id="EmployeeSalaryCard",
+ resolver=resolve_compensation,
+ layout=layout,
+ description="Verified compensation. Pass only employeeId.",
+ sample_data={"employeeId": "emp_101"},
+)
+```
+
+#### B. Programmatic Render Mode (`render`)
+
+Bypasses static layouts and runs native Python logic (loops, arithmetic, conditionals) returning a component AST:
+
+```python
+from a2ui.inference_formats.experimental.template import DynamicTemplate
+
+def render_server_health(serverId: str, includeDisks: bool = True) -> dict:
+ status_icon = "check_circle" if serverId == "srv_01" else "warning"
+ return {
+ "component": "Card",
+ "child": {
+ "component": "Column",
+ "children": [
+ {"component": "Text", "text": f"Server {serverId}", "variant": "h3"},
+ {"component": "Icon", "name": status_icon},
+ ]
+ }
+ }
+
+server_template = DynamicTemplate(
+ template_id="ServerHealthCard",
+ render=render_server_health,
+ description="Live server diagnostics.",
+ sample_data={"serverId": "srv_01", "includeDisks": True},
+)
+```
+
+### 3. `TemplateProcessor`
+
+The core synchronous template expansion and catalog generation engine.
+
+```python
+from a2ui.inference_formats.experimental.template import (
+ TemplateProcessor,
+ TemplateId,
+ A2UIComponentList,
+)
+
+processor = TemplateProcessor(templates=[user_profile, dynamic_salary, server_template])
+
+# 1. Synthesize virtual A2UI component catalog for LLMs
+synthetic_catalog = processor.generate_inference_catalog()
+
+# 2. Synchronously expand template invocations into standard A2UI primitives
+expanded_components: A2UIComponentList = processor.expand_template(
+ instance_id="root",
+ template_id="ServerHealthCard",
+ passed_params={"serverId": "srv_01", "includeDisks": True},
+)
+```
+
+### 4. `TemplateInferenceFormat`
+
+Integrates templates seamlessly with LLM prompting and parsing.
+
+```python
+from a2ui.inference_formats.experimental.template import TemplateInferenceFormat
+
+format_instance = TemplateInferenceFormat(
+ templates=[user_profile, dynamic_salary],
+ surface_id="main",
+ version="0.9.1",
+)
+
+# Generate system prompt instructions with template signatures
+system_prompt = format_instance.prompt_generator.generate(
+ role_description="You are an A2UI assistant.",
+ include_schema=True,
+)
+
+# Parse response & synchronously expand templates to standard A2UI messages
+messages = format_instance.parser.parse_response(llm_response_text)
+```
diff --git a/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/template/__init__.py b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/template/__init__.py
new file mode 100644
index 0000000000..976321b584
--- /dev/null
+++ b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/template/__init__.py
@@ -0,0 +1,81 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""A2UI Template module providing parameterized component expansion and dynamic resolvers."""
+
+from .models import (
+ Template,
+ StaticTemplate,
+ DynamicTemplate,
+ dynamic_template,
+ BaseTemplate,
+ Param,
+ ParamType,
+ ParamRef,
+ Concat,
+ FormatExpr,
+ TemplateLoop,
+ TemplateComponent,
+ normalize_a2ui_type_to_jsonschema,
+ flatten_nested_layout,
+ normalize_node,
+)
+from .processor import (
+ TemplateProcessor,
+ TemplateId,
+ InstanceId,
+ ComponentId,
+ ParamPath,
+ TemplateParams,
+ TemplateNodeDict,
+ A2UIComponent,
+ A2UIComponentList,
+ A2UIMessage,
+ CatalogSchema,
+ JSONSchemaDict,
+)
+from .format import TemplateInferenceFormat, A2uiTemplateManager, TemplateParser
+
+__all__ = [
+ "Template",
+ "StaticTemplate",
+ "DynamicTemplate",
+ "dynamic_template",
+ "BaseTemplate",
+ "Param",
+ "ParamType",
+ "ParamRef",
+ "Concat",
+ "FormatExpr",
+ "TemplateLoop",
+ "TemplateComponent",
+ "normalize_a2ui_type_to_jsonschema",
+ "flatten_nested_layout",
+ "normalize_node",
+ "TemplateProcessor",
+ "TemplateId",
+ "InstanceId",
+ "ComponentId",
+ "ParamPath",
+ "TemplateParams",
+ "TemplateNodeDict",
+ "A2UIComponent",
+ "A2UIComponentList",
+ "A2UIMessage",
+ "CatalogSchema",
+ "JSONSchemaDict",
+ "TemplateInferenceFormat",
+ "A2uiTemplateManager",
+ "TemplateParser",
+]
diff --git a/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/template/format.py b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/template/format.py
new file mode 100644
index 0000000000..e1a91e2561
--- /dev/null
+++ b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/template/format.py
@@ -0,0 +1,257 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Inference format coordinating prompt generation and parsing of LLM responses using templates."""
+
+from __future__ import annotations
+
+from typing import Any, Callable, Dict, List, Optional, Sequence, Union
+from a2ui.core.catalog import Catalog
+from a2ui.inference_format import InferenceFormat
+from a2ui.parser.parser import Parser
+from a2ui.parser.response_part import ResponsePart
+from a2ui.prompt import PromptGenerator
+from a2ui.schema.catalog import A2uiCatalog
+from a2ui.schema.constants import (
+ COMMON_TYPES_SCHEMA_KEY,
+ SERVER_TO_CLIENT_SCHEMA_KEY,
+ SPEC_VERSION_MAP,
+)
+from a2ui.schema.utils import load_from_bundled_resource
+from google.adk.utils.feature_decorator import experimental
+
+from .models import Template, StaticTemplate, DynamicTemplate, BaseTemplate
+from .processor import TemplateProcessor
+
+
+def _clean_version(version: str) -> str:
+ """Normalizes version string by removing leading 'v' if present."""
+ return version.lstrip("v")
+
+
+class TemplateParser(Parser):
+ """Parser decorator that runs template expansion on compiled A2UI messages."""
+
+ def __init__(self, underlying_parser: Parser, processor: TemplateProcessor):
+ """Initializes the TemplateParser.
+
+ Args:
+ underlying_parser: The underlying inference format parser (e.g.
+ ExpressParser).
+ processor: The TemplateProcessor instance to expand templates.
+ """
+ self.underlying_parser = underlying_parser
+ self.processor = processor
+
+ def has_format_content(self, content: str, *, complete: bool = False) -> bool:
+ """Checks if the content contains blocks belonging to the underlying parser."""
+ return self.underlying_parser.has_format_content(content, complete=complete)
+
+ def unwrap(self, content: str) -> List[ResponsePart]:
+ """Tokenizes response content into raw format-content parts."""
+ return self.underlying_parser.unwrap(content)
+
+ def compile(
+ self, format_content: str, *, is_final: bool = True
+ ) -> List[Dict[str, Any]]:
+ """Compiles raw format content and expands all template components."""
+ raw_msgs = self.underlying_parser.compile(format_content, is_final=is_final)
+ expanded = self.processor.process_message(raw_msgs)
+ if isinstance(expanded, list):
+ return expanded
+ elif isinstance(expanded, dict):
+ return [expanded]
+ return []
+
+ def parse_response(self, content: str) -> List[ResponsePart]:
+ """Parses full response content into standard JSON payload parts by unwrapping and expanding templates."""
+ parts = self.unwrap(content)
+ parsed_so_far: List[ResponsePart] = []
+ for part in parts:
+ if part.a2ui_raw is not None:
+ try:
+ part.a2ui_json = self.compile(part.a2ui_raw, is_final=part.is_final)
+ except Exception as e:
+ from a2ui.parser.errors import A2uiCompilationError
+
+ if isinstance(e, A2uiCompilationError):
+ e.partial_results = parsed_so_far
+ raise e
+ raise A2uiCompilationError(
+ message=str(e),
+ raw_content=part.a2ui_raw,
+ partial_results=parsed_so_far,
+ ) from e
+ parsed_so_far.append(part)
+ return parts
+
+ @property
+ def supports_streaming(self) -> bool:
+ """Streaming is intentionally disabled for template expansion to keep architectures simple."""
+ return False
+
+ def decompile(self, val: Any) -> str:
+ """Decompiles structured A2UI payloads into raw format notation."""
+ return self.underlying_parser.decompile(val)
+
+ def wrap_decompiled_blocks(self, blocks: List[str]) -> str:
+ """Wraps multiple decompiled blocks with the format's enclosing tags."""
+ return self.underlying_parser.wrap_decompiled_blocks(blocks)
+
+
+@experimental
+class TemplateInferenceFormat(InferenceFormat):
+ """Inference format providing template generation and synchronous expansion."""
+
+ def __init__(
+ self,
+ templates: Sequence[
+ Union[BaseTemplate, Template, StaticTemplate, DynamicTemplate]
+ ],
+ catalog: Optional[Union[Catalog[Any, Any], A2uiCatalog, Dict[str, Any]]] = None,
+ allowed_primitives: Optional[List[str]] = None,
+ surface_id: str = "main",
+ version: str = "0.9.1",
+ underlying_format_factory: Optional[
+ Callable[[A2uiCatalog, str, str], InferenceFormat]
+ ] = None,
+ ):
+ """Initializes the TemplateInferenceFormat with registered templates and base catalog.
+
+ Args:
+ templates: List of registered Template definitions.
+ catalog: Optional base catalog instance or schema dictionary.
+ allowed_primitives: List of primitive components from the base
+ catalog to allow.
+ surface_id: Surface identifier for layout targeting.
+ version: Target A2UI protocol version ("0.9", "0.9.1", or "1.0").
+ underlying_format_factory: Optional custom factory for underlying
+ InferenceFormat.
+ """
+ self.templates = templates
+ self.surface_id = surface_id
+ self.version = _clean_version(version)
+ self.allowed_primitives = allowed_primitives
+
+ # 1. Resolve base catalog
+ if catalog is None:
+ from a2ui.basic_catalog.provider import BasicCatalog
+
+ config = BasicCatalog.get_config(self.version)
+ schema = config.provider.load()
+ s2c = load_from_bundled_resource(
+ self.version, SERVER_TO_CLIENT_SCHEMA_KEY, SPEC_VERSION_MAP
+ )
+ common_types = load_from_bundled_resource(
+ self.version, COMMON_TYPES_SCHEMA_KEY, SPEC_VERSION_MAP
+ )
+ self.base_catalog = A2uiCatalog(
+ version=self.version,
+ name="basic",
+ catalog_schema=schema,
+ s2c_schema=s2c,
+ common_types_schema=common_types,
+ )
+ elif isinstance(catalog, A2uiCatalog):
+ self.base_catalog = catalog
+ elif hasattr(catalog, "catalog_schema"):
+ s2c = getattr(catalog, "s2c_schema", None) or load_from_bundled_resource(
+ self.version, SERVER_TO_CLIENT_SCHEMA_KEY, SPEC_VERSION_MAP
+ )
+ common_types = getattr(
+ catalog, "common_types_schema", None
+ ) or load_from_bundled_resource(
+ self.version, COMMON_TYPES_SCHEMA_KEY, SPEC_VERSION_MAP
+ )
+ self.base_catalog = A2uiCatalog(
+ version=self.version,
+ name="custom",
+ catalog_schema=getattr(catalog, "catalog_schema"),
+ s2c_schema=s2c,
+ common_types_schema=common_types,
+ )
+ else:
+ s2c = load_from_bundled_resource(
+ self.version, SERVER_TO_CLIENT_SCHEMA_KEY, SPEC_VERSION_MAP
+ )
+ common_types = load_from_bundled_resource(
+ self.version, COMMON_TYPES_SCHEMA_KEY, SPEC_VERSION_MAP
+ )
+ self.base_catalog = A2uiCatalog(
+ version=self.version,
+ name="custom",
+ catalog_schema=catalog if isinstance(catalog, dict) else {},
+ s2c_schema=s2c,
+ common_types_schema=common_types,
+ )
+
+ if self.allowed_primitives is None and hasattr(
+ self.base_catalog, "catalog_schema"
+ ):
+ schema_dict = getattr(self.base_catalog, "catalog_schema", {})
+ if isinstance(schema_dict, dict) and "components" in schema_dict:
+ self.allowed_primitives = list(schema_dict["components"].keys())
+
+ # 2. Initialize TemplateProcessor
+ self.processor = TemplateProcessor(
+ templates=self.templates,
+ catalogs=self.base_catalog,
+ version=self.version,
+ )
+
+ # 3. Construct synthetic A2uiCatalog containing allowed primitives + templates
+ self.synthetic_catalog_schema = self.processor.generate_inference_catalog(
+ allowed_primitives=self.allowed_primitives
+ )
+ self.synthetic_catalog = A2uiCatalog(
+ version=self.version,
+ name="synthetic",
+ catalog_schema=self.synthetic_catalog_schema,
+ s2c_schema=self.base_catalog.s2c_schema,
+ common_types_schema=self.base_catalog.common_types_schema,
+ )
+
+ # 4. Initialize underlying inference format
+ express_version = f"v{self.version}"
+ if underlying_format_factory:
+ self._underlying_format = underlying_format_factory(
+ self.synthetic_catalog, self.surface_id, express_version
+ )
+ else:
+ from a2ui.inference_formats.experimental.express.format import (
+ ExpressFormat,
+ )
+
+ self._underlying_format = ExpressFormat(
+ catalog=self.synthetic_catalog,
+ surface_id=self.surface_id,
+ version=express_version,
+ )
+
+ # 5. Wrap parser with TemplateParser
+ self._parser = TemplateParser(self._underlying_format.parser, self.processor)
+
+ @property
+ def parser(self) -> TemplateParser:
+ """The parser instance associated with the template inference format."""
+ return self._parser
+
+ @property
+ def prompt_generator(self) -> PromptGenerator:
+ """The prompt generator instance associated with the template inference format."""
+ return self._underlying_format.prompt_generator
+
+
+# Backward-compatibility alias
+A2uiTemplateManager = TemplateInferenceFormat
diff --git a/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/template/models.py b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/template/models.py
new file mode 100644
index 0000000000..36268835ee
--- /dev/null
+++ b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/template/models.py
@@ -0,0 +1,1009 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Data models for A2UI Template definitions, typed parameters, expressions, and dynamic resolvers."""
+
+from __future__ import annotations
+
+import asyncio
+from enum import Enum
+import functools
+import inspect
+import json
+import os
+from pathlib import Path
+import re
+from dataclasses import dataclass, field
+from typing import Any, Callable, Dict, List, Optional, Tuple, Union
+import jsonschema
+import yaml
+
+
+def _find_template_schema_path() -> Optional[Path]:
+ """Finds the template definition JSON schema in specification/proposals/templates/schema/."""
+ current = Path(__file__).resolve()
+ for parent in current.parents:
+ candidate = (
+ parent
+ / "specification"
+ / "proposals"
+ / "templates"
+ / "schema"
+ / "template_definition.json"
+ )
+ if candidate.is_file():
+ return candidate
+ return None
+
+
+SCHEMA_PATH = _find_template_schema_path()
+TEMPLATE_DEFINITION_SCHEMA: Optional[Dict[str, Any]] = None
+if SCHEMA_PATH and SCHEMA_PATH.is_file():
+ with open(SCHEMA_PATH, "r", encoding="utf-8") as _f:
+ TEMPLATE_DEFINITION_SCHEMA = json.load(_f)
+
+
+class ParamType(str, Enum):
+ """Supported A2UI semantic parameter types."""
+
+ STRING = "string"
+ NUMBER = "number"
+ INTEGER = "integer"
+ BOOLEAN = "boolean"
+ ENUM = "enum"
+ OBJECT = "object"
+ ARRAY = "array"
+ CHILD = "child"
+ CHILDREN = "children"
+ ACTION = "action"
+
+
+@dataclass
+class Param:
+ """Strongly typed template parameter definition."""
+
+ type: Union[ParamType, str]
+ title: Optional[str] = None
+ description: Optional[str] = None
+ default: Optional[Any] = None
+ values: Optional[List[str]] = None
+ properties: Optional[Dict[str, Any]] = None
+ items: Optional[Union[Param, Dict[str, Any], str]] = None
+ required: bool = True
+ minimum: Optional[float] = None
+ maximum: Optional[float] = None
+
+ @classmethod
+ def string(
+ cls,
+ description: Optional[str] = None,
+ title: Optional[str] = None,
+ default: Optional[str] = None,
+ ) -> Param:
+ return cls(
+ type=ParamType.STRING,
+ description=description,
+ title=title,
+ default=default,
+ )
+
+ @classmethod
+ def number(
+ cls,
+ description: Optional[str] = None,
+ title: Optional[str] = None,
+ default: Optional[float] = None,
+ ) -> Param:
+ return cls(
+ type=ParamType.NUMBER,
+ description=description,
+ title=title,
+ default=default,
+ )
+
+ @classmethod
+ def integer(
+ cls,
+ description: Optional[str] = None,
+ title: Optional[str] = None,
+ default: Optional[int] = None,
+ ) -> Param:
+ return cls(
+ type=ParamType.INTEGER,
+ description=description,
+ title=title,
+ default=default,
+ )
+
+ @classmethod
+ def boolean(
+ cls,
+ description: Optional[str] = None,
+ title: Optional[str] = None,
+ default: Optional[bool] = None,
+ ) -> Param:
+ return cls(
+ type=ParamType.BOOLEAN,
+ description=description,
+ title=title,
+ default=default,
+ )
+
+ @classmethod
+ def enum(
+ cls,
+ values: List[str],
+ description: Optional[str] = None,
+ title: Optional[str] = None,
+ default: Optional[str] = None,
+ ) -> Param:
+ return cls(
+ type=ParamType.ENUM,
+ values=values,
+ description=description,
+ title=title,
+ default=default,
+ )
+
+ @classmethod
+ def child(
+ cls, description: Optional[str] = None, title: Optional[str] = None
+ ) -> Param:
+ return cls(type=ParamType.CHILD, description=description, title=title)
+
+ @classmethod
+ def children(
+ cls, description: Optional[str] = None, title: Optional[str] = None
+ ) -> Param:
+ return cls(
+ type=ParamType.CHILDREN,
+ description=description,
+ title=title,
+ default=[],
+ )
+
+ @classmethod
+ def action(
+ cls, description: Optional[str] = None, title: Optional[str] = None
+ ) -> Param:
+ return cls(type=ParamType.ACTION, description=description, title=title)
+
+ @classmethod
+ def array(
+ cls,
+ items: Union[Param, Dict[str, Any], str],
+ description: Optional[str] = None,
+ title: Optional[str] = None,
+ ) -> Param:
+ return cls(
+ type=ParamType.ARRAY, items=items, description=description, title=title
+ )
+
+ @classmethod
+ def object(
+ cls,
+ properties: Dict[str, Any],
+ description: Optional[str] = None,
+ title: Optional[str] = None,
+ ) -> Param:
+ return cls(
+ type=ParamType.OBJECT,
+ properties=properties,
+ description=description,
+ title=title,
+ )
+
+ @classmethod
+ def from_dict(cls, data: Dict[str, Any]) -> Param:
+ raw_type = data.get("type", "string")
+ p_type = (
+ ParamType(raw_type)
+ if raw_type in ParamType._value2member_map_
+ else raw_type
+ )
+ return cls(
+ type=p_type,
+ title=data.get("title"),
+ description=data.get("description"),
+ default=data.get("default"),
+ values=data.get("values"),
+ properties=data.get("properties"),
+ items=data.get("items"),
+ required=data.get("required", True),
+ minimum=data.get("minimum"),
+ maximum=data.get("maximum"),
+ )
+
+ def to_dict(self) -> Dict[str, Any]:
+ res: Dict[str, Any] = {
+ "type": (
+ self.type.value if isinstance(self.type, ParamType) else str(self.type)
+ )
+ }
+ if self.title:
+ res["title"] = self.title
+ if self.description:
+ res["description"] = self.description
+ if self.default is not None:
+ res["default"] = self.default
+ if self.values is not None:
+ res["values"] = self.values
+ if self.properties is not None:
+ res["properties"] = {
+ k: v.to_dict() if isinstance(v, Param) else v
+ for k, v in self.properties.items()
+ }
+ if self.items is not None:
+ res["items"] = (
+ self.items.to_dict() if isinstance(self.items, Param) else self.items
+ )
+ if self.minimum is not None:
+ res["minimum"] = self.minimum
+ if self.maximum is not None:
+ res["maximum"] = self.maximum
+ return res
+
+
+@dataclass
+class ParamRef:
+ """Direct reference to a parameter or dot path."""
+
+ param: str
+ default: Optional[Any] = None
+
+ def to_dict(self) -> Dict[str, Any]:
+ res: Dict[str, Any] = {"param": self.param}
+ if self.default is not None:
+ res["default"] = self.default
+ return res
+
+
+@dataclass
+class Concat:
+ """String concatenation expression of literals and parameter references."""
+
+ concat: List[Union[str, ParamRef, Dict[str, Any]]]
+
+ def to_dict(self) -> Dict[str, Any]:
+ return {
+ "concat": [
+ (p.to_dict() if isinstance(p, ParamRef) else p) for p in self.concat
+ ]
+ }
+
+
+@dataclass
+class FormatExpr:
+ """String formatting expression with {key} arguments."""
+
+ format: str
+ args: Dict[str, Union[str, ParamRef, Dict[str, Any]]]
+
+ def to_dict(self) -> Dict[str, Any]:
+ return {
+ "format": self.format,
+ "args": {
+ k: v.to_dict() if isinstance(v, ParamRef) else v
+ for k, v in self.args.items()
+ },
+ }
+
+
+@dataclass
+class TemplateLoop:
+ """Array mapping parameter to child template instances or inline item layouts."""
+
+ param: str
+ template: Optional[str] = None
+ item: Optional[List[Union[TemplateComponent, Dict[str, Any]]]] = None
+ as_var: Optional[str] = None
+
+ def to_dict(self) -> Dict[str, Any]:
+ res: Dict[str, Any] = {"param": self.param}
+ if self.template:
+ res["template"] = self.template
+ if self.item:
+ res["item"] = [
+ (c.to_dict() if isinstance(c, TemplateComponent) else c)
+ for c in self.item
+ ]
+ if self.as_var:
+ res["as"] = self.as_var
+ return res
+
+
+@dataclass
+class TemplateComponent:
+ """Strongly typed template component definition."""
+
+ id: str
+ component: str
+ properties: Dict[str, Any] = field(default_factory=dict)
+ child: Optional[Union[str, ParamRef, Dict[str, Any]]] = None
+ children: Optional[Union[List[Any], ParamRef, TemplateLoop, Dict[str, Any]]] = None
+ catalog_id: Optional[str] = None
+
+ def to_dict(self) -> Dict[str, Any]:
+ res: Dict[str, Any] = {"id": self.id, "component": self.component}
+ if self.catalog_id is not None:
+ res["catalogId"] = self.catalog_id
+ if self.child is not None:
+ res["child"] = (
+ self.child.to_dict() if isinstance(self.child, ParamRef) else self.child
+ )
+ if self.children is not None:
+ if isinstance(self.children, (ParamRef, TemplateLoop)):
+ res["children"] = self.children.to_dict()
+ else:
+ res["children"] = self.children
+ for k, v in self.properties.items():
+ if isinstance(v, (ParamRef, Concat, FormatExpr, TemplateLoop)):
+ res[k] = v.to_dict()
+ else:
+ res[k] = v
+ return res
+
+ @classmethod
+ def from_dict(cls, data: Dict[str, Any]) -> TemplateComponent:
+ data_copy = dict(data)
+ c_id = data_copy.pop("id")
+ c_type = data_copy.pop("component")
+ c_cat = data_copy.pop("catalogId", None) or data_copy.pop("catalog_id", None)
+ child = data_copy.pop("child", None)
+ children = data_copy.pop("children", None)
+ return cls(
+ id=c_id,
+ component=c_type,
+ catalog_id=c_cat,
+ properties=data_copy,
+ child=child,
+ children=children,
+ )
+
+
+def normalize_node(node: Any) -> Any:
+ """Polymorphically converts builder objects, dataclasses, or Pydantic models into dicts."""
+ if node is None:
+ return None
+ if hasattr(node, "to_dict") and callable(node.to_dict):
+ return node.to_dict()
+ if hasattr(node, "model_dump") and callable(node.model_dump):
+ return node.model_dump(exclude_none=True, by_alias=True)
+ import dataclasses
+
+ if dataclasses.is_dataclass(node) and not isinstance(node, type):
+ return dataclasses.asdict(node)
+ return node
+
+
+def flatten_nested_layout(
+ node: Any,
+ parent_id: Optional[str] = None,
+ slot_name: Optional[str] = None,
+ index: Optional[int] = None,
+) -> Tuple[str, List[Dict[str, Any]]]:
+ """Recursively flattens a nested layout tree (dicts, builder objects) into a flat component graph with synthetic IDs.
+
+ Returns:
+ Tuple of (assigned_component_id, list_of_flattened_components)
+ """
+ node = normalize_node(node)
+ if not isinstance(node, dict):
+ return str(node), []
+
+ node_copy = dict(node)
+ comp_type = node_copy.get("component", "Node").lower()
+
+ # 1. Determine or generate synthetic component ID
+ if "id" in node_copy and node_copy["id"]:
+ node_id = str(node_copy["id"])
+ elif parent_id is None:
+ node_id = "root"
+ elif slot_name and index is not None:
+ node_id = f"{parent_id}_{slot_name}_{index}_{comp_type}"
+ elif slot_name:
+ node_id = f"{parent_id}_{slot_name}_{comp_type}"
+ elif index is not None:
+ node_id = f"{parent_id}_{index}_{comp_type}"
+ else:
+ node_id = f"{parent_id}_{comp_type}"
+
+ node_copy["id"] = node_id
+ flat_components: List[Dict[str, Any]] = []
+
+ # 2. Process nested 'child'
+ if "child" in node_copy:
+ child_val = normalize_node(node_copy["child"])
+ if isinstance(child_val, dict) and "component" in child_val:
+ child_id, sub_comps = flatten_nested_layout(
+ child_val, parent_id=node_id, slot_name="child"
+ )
+ node_copy["child"] = child_id
+ flat_components.extend(sub_comps)
+ else:
+ node_copy["child"] = child_val
+
+ # 3. Process nested 'children'
+ if "children" in node_copy:
+ children_val = normalize_node(node_copy["children"])
+ if isinstance(children_val, list):
+ flattened_child_ids: List[Any] = []
+ for idx, raw_item in enumerate(children_val):
+ item = normalize_node(raw_item)
+ if isinstance(item, dict) and "component" in item:
+ item_id, sub_comps = flatten_nested_layout(
+ item, parent_id=node_id, slot_name="child", index=idx
+ )
+ flattened_child_ids.append(item_id)
+ flat_components.extend(sub_comps)
+ elif isinstance(item, dict) and "loop" in item:
+ # Loop inside children list
+ loop_cfg = item["loop"]
+ loop_dict: Dict[str, Any] = {"param": loop_cfg.get("param")}
+ if "as" in loop_cfg:
+ loop_dict["as"] = loop_cfg["as"]
+ if "item" in loop_cfg and isinstance(loop_cfg["item"], dict):
+ _, item_sub_comps = flatten_nested_layout(loop_cfg["item"])
+ loop_dict["item"] = item_sub_comps
+ elif "template" in loop_cfg:
+ loop_dict["template"] = loop_cfg["template"]
+ flattened_child_ids.append(loop_dict)
+ else:
+ flattened_child_ids.append(item)
+ node_copy["children"] = flattened_child_ids
+ elif isinstance(children_val, dict) and "loop" in children_val:
+ loop_cfg = children_val["loop"]
+ loop_dict = {"param": loop_cfg.get("param")}
+ if "as" in loop_cfg:
+ loop_dict["as"] = loop_cfg["as"]
+ if "item" in loop_cfg and isinstance(loop_cfg["item"], dict):
+ _, item_sub_comps = flatten_nested_layout(loop_cfg["item"])
+ loop_dict["item"] = item_sub_comps
+ elif "template" in loop_cfg:
+ loop_dict["template"] = loop_cfg["template"]
+ node_copy["children"] = loop_dict
+ else:
+ node_copy["children"] = children_val
+
+ flat_components.insert(0, node_copy)
+ return node_id, flat_components
+
+
+def normalize_a2ui_type_to_jsonschema(meta: Any) -> Any:
+ """Recursively converts an A2UI parameter type schema into standard JSON Schema."""
+ if isinstance(meta, Param):
+ meta = meta.to_dict()
+ if not isinstance(meta, dict):
+ return meta
+ schema = dict(meta)
+ p_type = schema.get("type")
+ if p_type == "enum" and "values" in schema:
+ schema["type"] = "string"
+ schema["enum"] = schema.pop("values")
+ elif p_type in ["child", "action"]:
+ schema["type"] = "string"
+ elif p_type == "children":
+ schema["type"] = "array"
+ schema["items"] = {"type": "string"}
+
+ if "properties" in schema and isinstance(schema["properties"], dict):
+ schema["properties"] = {
+ k: normalize_a2ui_type_to_jsonschema(v)
+ for k, v in schema["properties"].items()
+ }
+ if "items" in schema:
+ if isinstance(schema["items"], (dict, Param)):
+ schema["items"] = normalize_a2ui_type_to_jsonschema(schema["items"])
+ elif isinstance(schema["items"], str):
+ schema["items"] = {"type": schema["items"]}
+ return schema
+
+
+@dataclass
+class BaseTemplate:
+ """Base class for all templates."""
+
+ name: str = ""
+ catalogs: List[str] = field(default_factory=list)
+ id: Optional[str] = None
+ imports: Union[List[str], Dict[str, str]] = field(default_factory=list)
+ version: str = "0.1"
+ description: Optional[str] = None
+ sample_data: Optional[Dict[str, Any]] = None
+ is_dynamic: bool = False
+ template_id: str = ""
+
+ def __post_init__(self):
+ if not self.name and self.template_id:
+ self.name = self.template_id
+ elif not self.template_id and self.name:
+ self.template_id = self.name
+ if isinstance(self.catalogs, str):
+ self.catalogs = [self.catalogs]
+
+
+@dataclass
+class StaticTemplate(BaseTemplate):
+ """Declarative A2UI template definition authored in YAML with layout trees and parameter substitutions."""
+
+ parameters: Dict[str, Union[Param, Dict[str, Any]]] = field(default_factory=dict)
+ components: List[Union[TemplateComponent, Dict[str, Any]]] = field(
+ default_factory=list
+ )
+ raw_layout: Optional[Dict[str, Any]] = None
+
+ @classmethod
+ def from_dict(cls, data: Dict[str, Any]) -> StaticTemplate:
+ """Constructs a StaticTemplate instance from a dictionary payload."""
+ name = data.get("name") or data.get("templateId") or data.get("template_id")
+ if not name:
+ raise ValueError(
+ "Template dictionary must contain 'name' (or 'templateId')."
+ )
+
+ version = data.get("version")
+ if not version:
+ raise ValueError(f"Template '{name}' missing required 'version' attribute.")
+ if version != "0.1":
+ raise ValueError(
+ f"Unsupported template version '{version}'. Currently only '0.1' is"
+ " supported."
+ )
+
+ catalogs_raw = data.get("catalogs", [])
+ if isinstance(catalogs_raw, str):
+ catalogs = [catalogs_raw]
+ elif isinstance(catalogs_raw, (list, tuple)):
+ catalogs = list(catalogs_raw)
+ else:
+ catalogs = []
+
+ id_val = data.get("id")
+ imports = data.get("imports", [])
+
+ raw_params = data.get("parameters", {})
+ parsed_params: Dict[str, Union[Param, Dict[str, Any]]] = {}
+ for k, v in raw_params.items():
+ parsed_params[k] = Param.from_dict(v) if isinstance(v, dict) else v
+
+ # Flatten nested layout if provided
+ raw_layout = data.get("layout")
+ components: List[Union[TemplateComponent, Dict[str, Any]]] = []
+ if raw_layout and isinstance(raw_layout, dict):
+ _, flat_comps = flatten_nested_layout(raw_layout)
+ components = list(flat_comps)
+ elif "components" in data and isinstance(data["components"], list):
+ components = list(data["components"])
+ else:
+ raise ValueError(
+ f"Template '{name}' must declare a 'layout' tree definition."
+ )
+
+ instance = cls(
+ name=name,
+ catalogs=catalogs,
+ id=id_val,
+ imports=imports,
+ template_id=name,
+ version=version,
+ parameters=parsed_params,
+ components=components,
+ raw_layout=raw_layout,
+ sample_data=data.get("sampleData") or data.get("sample_data"),
+ description=data.get("description"),
+ is_dynamic=False,
+ )
+ instance.validate_definition()
+ return instance
+
+ @classmethod
+ def from_yaml_string(cls, yaml_content: str) -> List[StaticTemplate]:
+ """Parses a YAML string containing one or more '---' separated template documents."""
+ docs = list(yaml.safe_load_all(yaml_content))
+ templates: List[StaticTemplate] = []
+ for doc in docs:
+ if not doc or not isinstance(doc, dict):
+ continue
+ templates.append(cls.from_dict(doc))
+ if not templates:
+ raise ValueError("No valid template definitions found in YAML content.")
+ return templates
+
+ @classmethod
+ def from_yaml_file(cls, file_path: Union[str, Path]) -> List[StaticTemplate]:
+ """Loads and parses all Template definitions from a YAML file."""
+ with open(file_path, "r", encoding="utf-8") as f:
+ content = f.read()
+ return cls.from_yaml_string(content)
+
+ @classmethod
+ def from_yaml(cls, yaml_content: str) -> StaticTemplate:
+ """Convenience method to load a single template definition from YAML."""
+ templates = cls.from_yaml_string(yaml_content)
+ return templates[0]
+
+ def to_dict(self) -> Dict[str, Any]:
+ """Serializes the template instance to a dictionary."""
+ params_dict: Dict[str, Any] = {}
+ for k, v in self.parameters.items():
+ params_dict[k] = v.to_dict() if isinstance(v, Param) else v
+
+ comps_list: List[Dict[str, Any]] = []
+ for c in self.components:
+ comps_list.append(c.to_dict() if isinstance(c, TemplateComponent) else c)
+
+ res: Dict[str, Any] = {
+ "version": self.version,
+ "name": self.name,
+ "templateId": self.name,
+ "catalogs": self.catalogs,
+ "parameters": params_dict,
+ }
+ if self.id is not None:
+ res["id"] = self.id
+ if self.imports:
+ res["imports"] = self.imports
+ if self.raw_layout is not None:
+ res["layout"] = self.raw_layout
+ else:
+ res["components"] = comps_list
+
+ if self.description:
+ res["description"] = self.description
+ if self.sample_data is not None:
+ res["sampleData"] = self.sample_data
+ return res
+
+ def to_yaml(self) -> str:
+ """Serializes the template instance to a clean YAML string."""
+ return yaml.dump(self.to_dict(), sort_keys=False)
+
+ @staticmethod
+ def _collect_loop_vars(val: Any, loop_vars: set) -> None:
+ if isinstance(val, dict):
+ if "as" in val and isinstance(val["as"], str):
+ loop_vars.add(val["as"])
+ for v in val.values():
+ StaticTemplate._collect_loop_vars(v, loop_vars)
+ elif isinstance(val, list):
+ for item in val:
+ StaticTemplate._collect_loop_vars(item, loop_vars)
+
+ def _check_val(self, val: Any, loop_vars: set) -> None:
+ expr_pattern = re.compile(r"(? None:
+ parts = path.split(".")
+ root = parts[0]
+ if root not in self.parameters:
+ if root.startswith("__") or root in loop_vars:
+ return
+ raise ValueError(
+ f"Template '{self.template_id}': Component references parameter"
+ f" '{root}' in '{path}', but it is not declared in template"
+ " parameters."
+ )
+
+ curr_schema = self.parameters[root]
+ if isinstance(curr_schema, Param):
+ curr_schema = curr_schema.to_dict()
+ for part in parts[1:]:
+ if isinstance(curr_schema, dict) and "properties" in curr_schema:
+ props = curr_schema.get("properties", {})
+ if part not in props:
+ raise ValueError(
+ f"Template '{self.template_id}': Component references"
+ f" property '{part}' in '{path}', but it is not declared in"
+ f" parameter '{root}' properties."
+ )
+ curr_schema = props[part]
+
+ def validate_definition(self) -> None:
+ """Statically validates the template against the JSON Schema, verifies parameter references, and validates sampleData."""
+ if TEMPLATE_DEFINITION_SCHEMA is not None:
+ raw_dict = self.to_dict()
+ try:
+ jsonschema.validate(
+ instance=raw_dict, schema=TEMPLATE_DEFINITION_SCHEMA
+ )
+ except jsonschema.ValidationError as err:
+ raise ValueError(
+ f"Template '{self.template_id}' fails template_definition.json"
+ f" schema: {err.message}"
+ ) from err
+
+ loop_vars = {"item"}
+ for comp in self.components:
+ comp_dict = comp.to_dict() if isinstance(comp, TemplateComponent) else comp
+ self._collect_loop_vars(comp_dict, loop_vars)
+
+ for comp in self.components:
+ comp_dict = comp.to_dict() if isinstance(comp, TemplateComponent) else comp
+ self._check_val(comp_dict, loop_vars)
+
+ if self.sample_data and isinstance(self.sample_data, dict):
+ for p_name, p_val in self.sample_data.items():
+ if p_name in self.parameters:
+ p_meta = self.parameters[p_name]
+ if isinstance(p_meta, Param):
+ p_type = (
+ p_meta.type.value
+ if isinstance(p_meta.type, ParamType)
+ else str(p_meta.type)
+ )
+ else:
+ p_type = str(p_meta.get("type", "string"))
+ if p_type in ["child", "children", "action"]:
+ continue
+
+ val_schema = normalize_a2ui_type_to_jsonschema(p_meta)
+ try:
+ jsonschema.validate(instance=p_val, schema=val_schema)
+ except jsonschema.ValidationError as err:
+ raise ValueError(
+ f"Template '{self.template_id}': sampleData for parameter"
+ f" '{p_name}' fails validation: {err.message}"
+ ) from err
+
+
+# Retain Template alias for backward compatibility
+Template = StaticTemplate
+
+
+class DynamicTemplate(BaseTemplate):
+ """Programmatic template that either executes a data resolver for a static layout or runs a render function returning an AST."""
+
+ def __init__(
+ self,
+ name: Optional[str] = None,
+ catalogs: Optional[Union[List[str], str]] = None,
+ id: Optional[str] = None,
+ imports: Optional[Union[List[str], Dict[str, str]]] = None,
+ render: Optional[Callable[..., Any]] = None,
+ resolver: Optional[Callable[..., Any]] = None,
+ layout: Optional[Union[StaticTemplate, str, Dict[str, Any]]] = None,
+ parameters: Optional[Dict[str, Union[Param, Dict[str, Any]]]] = None,
+ description: Optional[str] = None,
+ sample_data: Optional[Dict[str, Any]] = None,
+ render_fn: Optional[Callable[..., Any]] = None,
+ version: str = "0.1",
+ template_id: Optional[str] = None,
+ ):
+ template_name = name or template_id
+ if not template_name:
+ raise ValueError("DynamicTemplate must provide 'name' (or 'template_id').")
+
+ self.layout: Optional[StaticTemplate] = None
+ if layout is not None:
+ if isinstance(layout, str):
+ if os.path.exists(layout):
+ self.layout = StaticTemplate.from_yaml_file(layout)[0]
+ else:
+ self.layout = StaticTemplate.from_yaml(layout)
+ elif isinstance(layout, dict):
+ self.layout = StaticTemplate.from_dict(layout)
+ else:
+ self.layout = layout
+
+ catalogs_list: List[str] = []
+ if catalogs is not None:
+ catalogs_list = [catalogs] if isinstance(catalogs, str) else list(catalogs)
+ elif self.layout is not None and self.layout.catalogs:
+ catalogs_list = list(self.layout.catalogs)
+
+ super().__init__(
+ name=template_name,
+ catalogs=catalogs_list,
+ id=id,
+ imports=imports or [],
+ template_id=template_name,
+ version=version,
+ description=description,
+ sample_data=sample_data,
+ is_dynamic=True,
+ )
+ self.render_fn = render or render_fn
+ self.resolver = resolver
+
+ target_fn = self.render_fn or self.resolver
+ if target_fn is None and self.layout is None:
+ raise ValueError(
+ f"DynamicTemplate '{template_name}' must provide either a 'render'"
+ " function or a ('resolver', 'layout') pair."
+ )
+
+ if parameters is not None:
+ self.parameters = parameters
+ elif target_fn is not None:
+ self.parameters = self._infer_parameters_from_resolver(target_fn)
+ else:
+ self.parameters = {}
+
+ @staticmethod
+ def _infer_parameters_from_resolver(
+ fn: Callable[..., Any],
+ ) -> Dict[str, Union[Param, Dict[str, Any]]]:
+ """Automatically derives parameter definitions from the Python function signature."""
+ sig = inspect.signature(fn)
+ inferred: Dict[str, Union[Param, Dict[str, Any]]] = {}
+ type_map = {
+ str: ParamType.STRING,
+ int: ParamType.INTEGER,
+ float: ParamType.NUMBER,
+ bool: ParamType.BOOLEAN,
+ }
+ for name, p in sig.parameters.items():
+ if name in ["self", "context"] or p.kind in (
+ inspect.Parameter.VAR_POSITIONAL,
+ inspect.Parameter.VAR_KEYWORD,
+ ):
+ continue
+ p_type = type_map.get(p.annotation, ParamType.STRING)
+ default = p.default if p.default is not inspect.Parameter.empty else None
+ inferred[name] = Param(
+ type=p_type,
+ default=default,
+ description=f"Input parameter '{name}' for dynamic resolver.",
+ )
+ return inferred
+
+ def resolve(self, passed_params: Dict[str, Any]) -> Dict[str, Any]:
+ """Executes the resolver synchronously or asynchronously."""
+ if self.resolver is None:
+ return {}
+ if isinstance(passed_params, dict):
+ sig = inspect.signature(self.resolver)
+ has_kwargs = any(
+ p.kind == inspect.Parameter.VAR_KEYWORD for p in sig.parameters.values()
+ )
+ if has_kwargs:
+ filtered_params = passed_params
+ else:
+ filtered_params = {
+ k: v for k, v in passed_params.items() if k in sig.parameters
+ }
+ res = self.resolver(**filtered_params)
+ elif isinstance(passed_params, list):
+ res = self.resolver(*passed_params)
+ else:
+ res = self.resolver(passed_params)
+
+ if asyncio.iscoroutine(res):
+ try:
+ loop = asyncio.get_event_loop()
+ if loop.is_running():
+ try:
+ import nest_asyncio # type: ignore
+
+ nest_asyncio.apply()
+ except ImportError as err:
+ raise RuntimeError(
+ "An event loop is already running. Please install"
+ " 'nest-asyncio' to run async resolvers synchronously."
+ ) from err
+ res_val = loop.run_until_complete(res)
+ else:
+ res_val = loop.run_until_complete(res)
+ except RuntimeError as err:
+ if "already running" in str(err) or "run_until_complete" in str(err):
+ raise
+ res_val = asyncio.run(res)
+ except Exception:
+ res_val = asyncio.run(res)
+ return dict(res_val) if isinstance(res_val, dict) else {}
+ return dict(res) if isinstance(res, dict) else {}
+
+ def to_dict(self) -> Dict[str, Any]:
+ params_dict: Dict[str, Any] = {}
+ for k, v in self.parameters.items():
+ params_dict[k] = v.to_dict() if isinstance(v, Param) else v
+
+ comps_list = []
+ if self.layout is not None:
+ comps_list = [
+ (c.to_dict() if isinstance(c, TemplateComponent) else c)
+ for c in self.layout.components
+ ]
+
+ res: Dict[str, Any] = {
+ "version": self.version,
+ "templateId": self.template_id,
+ "parameters": params_dict,
+ "components": comps_list,
+ "isDynamic": True,
+ }
+ if self.description:
+ res["description"] = self.description
+ if self.sample_data is not None:
+ res["sampleData"] = self.sample_data
+ return res
+
+ def __call__(self, *args: Any, **kwargs: Any) -> Any:
+ """Allows the DynamicTemplate instance to remain directly callable in unit tests or user code."""
+ if self.render_fn is not None:
+ return self.render_fn(*args, **kwargs)
+ if self.resolver is not None:
+ return self.resolve(kwargs if kwargs else (args[0] if args else {}))
+ raise TypeError(f"DynamicTemplate '{self.name}' is not callable.")
+
+ def to_yaml(self) -> str:
+ """Serializes the dynamic template or underlying layout to a clean YAML string."""
+ if self.layout is not None:
+ return self.layout.to_yaml()
+ return yaml.dump(self.to_dict(), sort_keys=False)
+
+
+def dynamic_template(
+ name_or_fn: Optional[Union[str, Callable[..., Any]]] = None,
+ *,
+ name: Optional[str] = None,
+ catalogs: Optional[Union[List[str], str]] = None,
+ id: Optional[str] = None,
+ imports: Optional[Union[List[str], Dict[str, str]]] = None,
+ description: Optional[str] = None,
+ sample_data: Optional[Dict[str, Any]] = None,
+ version: str = "0.1",
+ **kwargs: Any,
+) -> Union[DynamicTemplate, Callable[[Callable[..., Any]], DynamicTemplate]]:
+ """Decorator to declare an A2UI DynamicTemplate directly on a Python render function.
+
+ Can be used with or without arguments:
+ @dynamic_template(catalogs=["https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"])
+ def user_card(title: str): ...
+
+ @dynamic_template
+ def user_card(title: str): ...
+ """
+
+ def _decorator(fn: Callable[..., Any]) -> DynamicTemplate:
+ explicit_name = name or (name_or_fn if isinstance(name_or_fn, str) else None)
+ tmpl_name = explicit_name or "".join(
+ word.capitalize() for word in fn.__name__.split("_")
+ )
+ desc = description or (fn.__doc__.strip() if fn.__doc__ else None)
+
+ tmpl = DynamicTemplate(
+ name=tmpl_name,
+ catalogs=catalogs,
+ id=id,
+ imports=imports,
+ render=fn,
+ description=desc,
+ sample_data=sample_data,
+ version=version,
+ **kwargs,
+ )
+ functools.update_wrapper(tmpl, fn)
+ return tmpl
+
+ if callable(name_or_fn):
+ return _decorator(name_or_fn)
+ return _decorator
diff --git a/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/template/processor.py b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/template/processor.py
new file mode 100644
index 0000000000..4bf4d57949
--- /dev/null
+++ b/agent_sdks/python/a2ui_agent/src/a2ui/inference_formats/experimental/template/processor.py
@@ -0,0 +1,1111 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Core processing, expansion engine, and dynamic resolver execution for A2UI Templates."""
+
+from __future__ import annotations
+
+import asyncio
+import inspect
+import re
+from typing import (
+ Any,
+ Dict,
+ List,
+ Mapping,
+ Optional,
+ Sequence,
+ Tuple,
+ TypeAlias,
+ Union,
+)
+import jsonschema
+from .models import (
+ Template,
+ StaticTemplate,
+ DynamicTemplate,
+ BaseTemplate,
+ Param,
+ ParamType,
+ ParamRef,
+ Concat,
+ FormatExpr,
+ TemplateLoop,
+ TemplateComponent,
+ normalize_a2ui_type_to_jsonschema,
+ flatten_nested_layout,
+)
+
+# ---------------------------------------------------------------------------
+# Strong Semantic Type Aliases
+# ---------------------------------------------------------------------------
+
+# 1. Identifier Types
+TemplateId: TypeAlias = str
+InstanceId: TypeAlias = str
+ComponentId: TypeAlias = str
+ParamPath: TypeAlias = str
+
+# 2. Template Evaluation Types
+TemplateParams: TypeAlias = Mapping[str, Any]
+TemplateNodeDict: TypeAlias = Dict[str, Any]
+
+# 3. Standard A2UI Wire-Format Output Types
+A2UIComponent: TypeAlias = Dict[str, Any]
+A2UIComponentList: TypeAlias = List[A2UIComponent]
+A2UIMessage: TypeAlias = Dict[str, Any]
+
+# 4. Catalog and Schema Types
+CatalogSchema: TypeAlias = Dict[str, Any]
+JSONSchemaDict: TypeAlias = Dict[str, Any]
+
+# 5. Safety & Recursion Limits
+MAX_EXPANSION_DEPTH: int = 50
+
+__all__ = [
+ "MAX_EXPANSION_DEPTH",
+ "TemplateProcessor",
+ "TemplateId",
+ "InstanceId",
+ "ComponentId",
+ "ParamPath",
+ "TemplateParams",
+ "TemplateNodeDict",
+ "A2UIComponent",
+ "A2UIComponentList",
+ "A2UIMessage",
+ "CatalogSchema",
+ "JSONSchemaDict",
+]
+
+
+def _resolve_param_path(path: ParamPath, params: TemplateParams) -> Tuple[bool, Any]:
+ """Resolves a dot-separated parameter path (e.g. 'user.name' or 'user.metrics.count') from params dict."""
+ parts = path.split(".")
+ curr: Any = params
+ for part in parts:
+ if isinstance(curr, (dict, Mapping)) and part in curr:
+ curr = curr[part]
+ elif (
+ isinstance(curr, (list, tuple)) and part.isdigit() and int(part) < len(curr)
+ ):
+ curr = curr[int(part)]
+ else:
+ return False, None
+ return True, curr
+
+
+def _substitute_params(val: Any, params: TemplateParams) -> Any:
+ """Recursively replaces parameter references with their resolved values."""
+ if isinstance(val, (ParamRef, Concat, FormatExpr, TemplateLoop)):
+ val = val.to_dict()
+
+ if isinstance(val, dict):
+ # 1. Direct param reference: {"param": "userName", "default": ...}
+ if (
+ "param" in val
+ and isinstance(val["param"], str)
+ and "template" not in val
+ and "item" not in val
+ ):
+ param_path = val["param"]
+ found, res = _resolve_param_path(param_path, params)
+ if found and res is not None:
+ return res
+ if "default" in val:
+ return val["default"]
+ return None
+
+ # 2. String concatenation: {"concat": ["Strategic Objectives: ", {"param": "teamName"}]}
+ if "concat" in val and isinstance(val["concat"], list):
+ parts = []
+ for item in val["concat"]:
+ sub = _substitute_params(item, params)
+ if sub is not None:
+ parts.append(str(sub))
+ return "".join(parts)
+
+ # 3. String formatting: {"format": "Competency: {name}", "args": {...}}
+ if "format" in val and "args" in val and isinstance(val["args"], dict):
+ fmt_str = str(val["format"])
+ args_sub = {
+ k: _substitute_params(v, params) for k, v in val["args"].items()
+ }
+ try:
+ return fmt_str.format(**args_sub)
+ except Exception:
+ return fmt_str
+
+ # 4. Standard dictionary traversal
+ return {k: _substitute_params(v, params) for k, v in val.items()}
+
+ elif isinstance(val, list):
+ return [_substitute_params(x, params) for x in val]
+
+ elif isinstance(val, str):
+ # 1. Exact parameter match preserving type: e.g. "{{ user }}", "{{user}}", "${user}"
+ match = re.match(r"^(?:\{\{\s*|\$\{)([\w\.]+)(?:\s*\}\}|\})$", val)
+ if match:
+ param_path = match.group(1)
+ found, res = _resolve_param_path(param_path, params)
+ if found:
+ return res
+
+ # 2. Check for exact escaped token match: e.g. r"\{{ user }}" -> "{{ user }}" or r"\${user}" -> "${user}"
+ escaped_match = re.match(r"^\\((?:\{\{|\$\{)[^}]*(?:\}\}|\}))$", val)
+ if escaped_match:
+ return escaped_match.group(1)
+
+ # 3. In-string replacement with escape handling:
+ def replacer(m: re.Match[str]) -> str:
+ path = m.group(1)
+ found, res = _resolve_param_path(path, params)
+ if found and res is not None:
+ return str(res)
+ return str(m.group(0))
+
+ # Replace unescaped Mustache tokens: (? "{{...}}" and r"\${...}" -> "${...}"
+ final_str = re.sub(r"\\(\{\{.*?\}\}|\$\{.*?\})", r"\1", substituted)
+ return final_str
+
+ return val
+
+
+# Private aliases for internal backwards-compatibility if referenced
+resolve_param_path = _resolve_param_path
+substitute_params = _substitute_params
+
+
+class TemplateProcessor:
+ """Manages template registration, synthetic catalog compilation, and payload expansion."""
+
+ def __init__(
+ self,
+ templates: Sequence[
+ Union[BaseTemplate, Template, StaticTemplate, DynamicTemplate]
+ ],
+ catalogs: Optional[
+ Union[
+ CatalogSchema, Sequence[CatalogSchema], Mapping[str, CatalogSchema], Any
+ ]
+ ] = None,
+ base_catalog: Optional[Union[CatalogSchema, Any]] = None,
+ version: str = "v0.9.1",
+ ):
+ """Initializes the TemplateProcessor.
+
+ Args:
+ templates: List of registered Template definitions.
+ catalogs: Mandatory catalog schema(s) or A2uiCatalog instance(s) that templates
+ are validated and resolved against. No default to basic catalog is assumed.
+ base_catalog: Backwards-compatible alias for catalogs.
+ version: Target A2UI protocol version ("v0.9", "v0.9.1", or "v1.0").
+ """
+ raw_catalogs = catalogs if catalogs is not None else base_catalog
+ if raw_catalogs is None:
+ raise ValueError(
+ "TemplateProcessor requires explicit catalog(s) to be provided via"
+ " 'catalogs'. No defaults to the basic catalog are assumed."
+ )
+
+ self.version = version
+ self.catalogs: Dict[str, CatalogSchema] = {}
+
+ def _extract_catalog(c: Any) -> Tuple[str, CatalogSchema]:
+ if hasattr(c, "catalog_schema") and isinstance(c.catalog_schema, dict):
+ schema = c.catalog_schema
+ elif isinstance(c, dict):
+ schema = c
+ else:
+ raise ValueError(f"Invalid catalog object: {type(c)}")
+ c_id = (
+ schema.get("catalogId")
+ or schema.get("$id")
+ or schema.get("id")
+ or "default"
+ )
+ return str(c_id), schema
+
+ def _register_catalog(c_id: str, schema: CatalogSchema) -> None:
+ self.catalogs[c_id] = schema
+ if "v0_9/catalogs/basic/catalog.json" in c_id:
+ self.catalogs[c_id.replace("v0_9/", "v0_9_1/")] = schema
+ elif "v0_9_1/catalogs/basic/catalog.json" in c_id:
+ self.catalogs[c_id.replace("v0_9_1/", "v0_9/")] = schema
+
+ if isinstance(raw_catalogs, (list, tuple, set)):
+ for item in raw_catalogs:
+ c_id, s = _extract_catalog(item)
+ _register_catalog(c_id, s)
+ elif isinstance(raw_catalogs, dict):
+ if (
+ "components" in raw_catalogs
+ or "$id" in raw_catalogs
+ or "catalogId" in raw_catalogs
+ ):
+ c_id, s = _extract_catalog(raw_catalogs)
+ _register_catalog(c_id, s)
+ else:
+ for k, v in raw_catalogs.items():
+ _, s = _extract_catalog(v)
+ _register_catalog(str(k), s)
+ else:
+ c_id, s = _extract_catalog(raw_catalogs)
+ _register_catalog(c_id, s)
+
+ if not self.catalogs:
+ raise ValueError(
+ "TemplateProcessor requires at least one catalog. Empty catalog"
+ " collection provided."
+ )
+
+ self.base_catalog_id = next(iter(self.catalogs.keys()))
+ self.base_catalog = self.catalogs[self.base_catalog_id]
+
+ self.templates: Dict[
+ TemplateId, Union[BaseTemplate, Template, StaticTemplate, DynamicTemplate]
+ ] = {}
+ self.templates_by_id: Dict[
+ str, Union[BaseTemplate, Template, StaticTemplate, DynamicTemplate]
+ ] = {}
+
+ for t in templates:
+ t_name = getattr(t, "name", None) or getattr(t, "template_id", None)
+ if not t_name:
+ continue
+ self.templates[t_name] = t
+ self.templates[t.template_id] = t
+ t_id = getattr(t, "id", None)
+ if t_id:
+ self.templates_by_id[t_id] = t
+ self.templates[t_id] = t
+
+ self._validate_templates()
+
+ def generate_inference_catalog(
+ self,
+ allowed_primitives: Optional[Sequence[str]] = None,
+ ) -> CatalogSchema:
+ """Generates a synthetic JSON catalog containing allowed primitives and all registered templates."""
+ if allowed_primitives is None:
+ allowed_primitives = []
+ for cat in self.catalogs.values():
+ for comp_k in cat.get("components", {}).keys():
+ if comp_k not in allowed_primitives:
+ allowed_primitives.append(comp_k)
+
+ catalog_id = (
+ self.base_catalog_id
+ if self.base_catalog_id
+ else "https://a2ui.org/catalog/synthetic"
+ )
+
+ synthetic_catalog: CatalogSchema = {
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "$id": catalog_id,
+ "catalogId": catalog_id,
+ "title": "A2UI Synthetic Inference Catalog",
+ "components": {},
+ "functions": (
+ self.base_catalog.get("functions", {})
+ if self.base_catalog is not None
+ else {}
+ ),
+ "$defs": {
+ "anyComponent": {
+ "oneOf": [],
+ "discriminator": {"propertyName": "component"},
+ },
+ "anyFunction": (
+ self.base_catalog.get("$defs", {}).get("anyFunction", {})
+ if self.base_catalog is not None
+ else {}
+ ),
+ },
+ }
+
+ # 1. Copy over allowed primitives from registered catalogs
+ for cat in self.catalogs.values():
+ base_components = cat.get("components", {})
+ for prim in allowed_primitives:
+ if (
+ prim in base_components
+ and prim not in synthetic_catalog["components"]
+ ):
+ synthetic_catalog["components"][prim] = base_components[prim]
+ synthetic_catalog["$defs"]["anyComponent"]["oneOf"].append(
+ {"$ref": f"#/components/{prim}"}
+ )
+
+ # 2. Add registered custom templates as high-level component schemas
+ common_types_url = (
+ "https://a2ui.org/specification/v0_9/common_types.json"
+ if "0.9" in self.version
+ else "https://a2ui.org/specification/v1_0/common_types.json"
+ )
+
+ seen_templates = set()
+ for template in self.templates.values():
+ t_id = getattr(template, "name", template.template_id)
+ if t_id in seen_templates:
+ continue
+ seen_templates.add(t_id)
+
+ param_required = []
+ properties_dict: Dict[str, Any] = {"component": {"const": t_id}}
+
+ raw_params = (
+ template.parameters.items() if hasattr(template, "parameters") else {}
+ )
+
+ for p_name, p_meta in raw_params:
+ p_meta_dict = p_meta.to_dict() if isinstance(p_meta, Param) else p_meta
+ properties_dict[p_name] = self._promote_parameter(p_meta_dict)
+ p_type = (
+ p_meta.type.value
+ if isinstance(p_meta, Param) and isinstance(p_meta.type, ParamType)
+ else (
+ p_meta.get("type")
+ if isinstance(p_meta, dict)
+ else getattr(p_meta, "type", None)
+ )
+ )
+ has_default = (
+ p_meta.default is not None
+ if isinstance(p_meta, Param)
+ else (isinstance(p_meta, dict) and "default" in p_meta)
+ )
+ if not has_default and p_type != "array":
+ param_required.append(p_name)
+
+ template_schema = {
+ "type": "object",
+ "allOf": [
+ {"$ref": f"{common_types_url}#/$defs/ComponentCommon"},
+ {
+ "type": "object",
+ "properties": properties_dict,
+ "required": ["component"] + param_required,
+ },
+ ],
+ "unevaluatedProperties": False,
+ }
+ if template.description:
+ template_schema["description"] = template.description
+
+ synthetic_catalog["components"][t_id] = template_schema
+ synthetic_catalog["$defs"]["anyComponent"]["oneOf"].append(
+ {"$ref": f"#/components/{t_id}"}
+ )
+
+ return synthetic_catalog
+
+ def expand_template(
+ self,
+ instance_id: InstanceId,
+ template_id: TemplateId,
+ passed_params: TemplateParams,
+ _depth: int = 0,
+ _call_stack: Optional[List[TemplateId]] = None,
+ ) -> A2UIComponentList:
+ """Recursively expands a template instance into standard primitive components."""
+ if _call_stack is None:
+ _call_stack = []
+
+ template = self.templates.get(template_id)
+ if not template:
+ available = list(self.templates.keys())
+ raise ValueError(
+ f"Template '{template_id}' is not registered. Available: {available}"
+ )
+
+ if template_id in _call_stack:
+ raise ValueError(
+ f"Circular template reference detected: {' -> '.join(_call_stack)} ->"
+ f" {template_id}"
+ )
+
+ if _depth > MAX_EXPANSION_DEPTH:
+ raise RecursionError(
+ f"Maximum template expansion depth exceeded ({_depth}) at"
+ f" '{template_id}'. Call stack: {' -> '.join(_call_stack)}"
+ )
+
+ current_stack = _call_stack + [template_id]
+
+ # 1. Handle DynamicTemplate execution
+ if getattr(template, "is_dynamic", False):
+ dynamic_tmpl: DynamicTemplate = template # type: ignore
+
+ # Mode A: Programmatic Render Function (returns AST tree or list directly)
+ if dynamic_tmpl.render_fn is not None:
+ if isinstance(passed_params, (dict, Mapping)):
+ sig = inspect.signature(dynamic_tmpl.render_fn)
+ has_kwargs = any(
+ p.kind == inspect.Parameter.VAR_KEYWORD
+ for p in sig.parameters.values()
+ )
+ if has_kwargs:
+ filtered_params = dict(passed_params)
+ else:
+ filtered_params = {
+ k: v
+ for k, v in passed_params.items()
+ if k in sig.parameters
+ }
+ res = dynamic_tmpl.render_fn(**filtered_params)
+ elif isinstance(passed_params, list):
+ res = dynamic_tmpl.render_fn(*passed_params)
+ else:
+ res = dynamic_tmpl.render_fn(passed_params)
+ if asyncio.iscoroutine(res):
+ try:
+ loop = asyncio.get_event_loop()
+ if loop.is_running():
+ try:
+ import nest_asyncio # type: ignore
+
+ nest_asyncio.apply()
+ except ImportError as err:
+ raise RuntimeError(
+ "An event loop is already running. Please install"
+ " 'nest-asyncio' to run async render functions"
+ " synchronously."
+ ) from err
+ res_tree = loop.run_until_complete(res)
+ else:
+ res_tree = loop.run_until_complete(res)
+ except RuntimeError as err:
+ if "already running" in str(err) or "run_until_complete" in str(
+ err
+ ):
+ raise
+ res_tree = asyncio.run(res)
+ except Exception:
+ res_tree = asyncio.run(res)
+ else:
+ res_tree = res
+
+ if isinstance(res_tree, list):
+ flattened_list: A2UIComponentList = []
+ for item in res_tree:
+ _, comps = flatten_nested_layout(item, parent_id=instance_id)
+ flattened_list.extend(comps)
+ return flattened_list
+ else:
+ _, flat_components = flatten_nested_layout(res_tree)
+ # Normalize root ID to instance_id
+ result: A2UIComponentList = []
+ for c in flat_components:
+ c_copy = dict(c)
+ if c_copy["id"] == "root":
+ c_copy["id"] = instance_id
+ elif c_copy["id"].startswith("root_"):
+ c_copy["id"] = f"{instance_id}_{c_copy['id'][5:]}"
+ if "child" in c_copy and isinstance(c_copy["child"], str):
+ if c_copy["child"] == "root":
+ c_copy["child"] = instance_id
+ elif c_copy["child"].startswith("root_"):
+ c_copy["child"] = f"{instance_id}_{c_copy['child'][5:]}"
+ if "children" in c_copy and isinstance(
+ c_copy["children"], list
+ ):
+ c_copy["children"] = [
+ (
+ instance_id
+ if ch == "root"
+ else (
+ f"{instance_id}_{ch[5:]}"
+ if isinstance(ch, str)
+ and ch.startswith("root_")
+ else ch
+ )
+ )
+ for ch in c_copy["children"]
+ ]
+ result.append(c_copy)
+ return result
+
+ # Mode B: Resolver + Static Layout Binding
+ elif dynamic_tmpl.layout is not None:
+ resolved_data = dynamic_tmpl.resolve(dict(passed_params))
+ combined_params = {**dict(passed_params), **resolved_data}
+ layout = dynamic_tmpl.layout
+ return self._expand_static_layout(
+ instance_id,
+ layout,
+ combined_params,
+ _depth=_depth + 1,
+ _call_stack=current_stack,
+ )
+
+ # 2. Handle StaticTemplate execution
+ return self._expand_static_layout(
+ instance_id,
+ template,
+ passed_params,
+ _depth=_depth + 1,
+ _call_stack=current_stack,
+ )
+
+ @staticmethod
+ def _map_id(internal_id: str, instance_id: InstanceId) -> ComponentId:
+ if internal_id == "root":
+ return instance_id
+ if internal_id.startswith("root_"):
+ return f"{instance_id}_{internal_id[5:]}"
+ return f"{instance_id}_{internal_id}"
+
+ @staticmethod
+ def _resolve_slot(val: Any, params: TemplateParams) -> Tuple[bool, Any]:
+ if isinstance(val, (ParamRef, TemplateLoop)):
+ val = val.to_dict()
+ if (
+ isinstance(val, dict)
+ and "param" in val
+ and "template" not in val
+ and "item" not in val
+ ):
+ p_path = val["param"]
+ found, res = _resolve_param_path(p_path, params)
+ if found:
+ return True, res
+ if "default" in val:
+ return True, val["default"]
+ elif isinstance(val, str):
+ s = val.strip()
+ if s.startswith("{{") and s.endswith("}}"):
+ p_path = s[2:-2].strip()
+ found, res = _resolve_param_path(p_path, params)
+ if found:
+ return True, res
+ return True, None
+ elif val.startswith("${") and val.endswith("}"):
+ p_path = val[2:-1]
+ found, res = _resolve_param_path(p_path, params)
+ if found:
+ return True, res
+ return True, None
+ elif val.startswith("__PARAM__"):
+ p_name = val[9:]
+ found, res = _resolve_param_path(p_name, params)
+ if found:
+ return True, res
+ return True, None
+ return False, val
+
+ @classmethod
+ def _map_child_list(
+ cls, child_list: Any, instance_id: InstanceId, params: TemplateParams
+ ) -> Any:
+ if isinstance(child_list, list):
+ res_list: List[Any] = []
+ for c_id in child_list:
+ is_slot, slot_val = cls._resolve_slot(c_id, params)
+ if is_slot:
+ if isinstance(slot_val, list):
+ res_list.extend(slot_val)
+ elif slot_val is not None:
+ res_list.append(slot_val)
+ else:
+ res_list.append(
+ cls._map_id(c_id, instance_id)
+ if isinstance(c_id, str)
+ else c_id
+ )
+ return res_list
+ elif isinstance(child_list, (str, dict, ParamRef, TemplateLoop)):
+ is_slot, slot_val = cls._resolve_slot(child_list, params)
+ if is_slot:
+ return slot_val
+ if isinstance(child_list, str):
+ return cls._map_id(child_list, instance_id)
+ return child_list
+ return child_list
+
+ def _expand_static_layout(
+ self,
+ instance_id: InstanceId,
+ layout: Union[StaticTemplate, Template, Any],
+ passed_params: TemplateParams,
+ _depth: int = 0,
+ _call_stack: Optional[List[TemplateId]] = None,
+ ) -> A2UIComponentList:
+ template_id = getattr(layout, "template_id", "AnonymousTemplate")
+
+ # 1. Resolve parameters and assign default values
+ params: Dict[str, Any] = {}
+ layout_params = getattr(layout, "parameters", {})
+ for p_name, p_meta in layout_params.items():
+ if isinstance(p_meta, Param):
+ p_meta_dict = p_meta.to_dict()
+ p_type = (
+ p_meta.type.value
+ if isinstance(p_meta.type, ParamType)
+ else str(p_meta.type)
+ )
+ else:
+ p_meta_dict = p_meta
+ p_type = str(p_meta.get("type", "string"))
+
+ if p_name in passed_params:
+ val = passed_params[p_name]
+ if p_type == "children":
+ if isinstance(val, list):
+ params[p_name] = val
+ elif isinstance(val, (dict, str)):
+ params[p_name] = [val]
+ elif val == p_name or val is None:
+ params[p_name] = p_meta_dict.get("default", [])
+ else:
+ params[p_name] = [val]
+ else:
+ params[p_name] = val
+
+ # Validate parameter value if data type
+ is_expression = isinstance(params[p_name], dict) and any(
+ k in params[p_name] for k in ["path", "concat", "format", "param"]
+ )
+ if (
+ isinstance(p_meta_dict, dict)
+ and p_type not in ["child", "children", "action"]
+ and not is_expression
+ and not (
+ isinstance(params[p_name], str)
+ and (
+ params[p_name].strip().startswith("{{")
+ or params[p_name].startswith("${")
+ or params[p_name].startswith("__")
+ )
+ )
+ ):
+ val_schema = normalize_a2ui_type_to_jsonschema(p_meta_dict)
+ if val_schema:
+ try:
+ jsonschema.validate(
+ instance=params[p_name], schema=val_schema
+ )
+ except jsonschema.ValidationError as err:
+ raise ValueError(
+ f"Template '{template_id}': Parameter '{p_name}'"
+ f" failed validation: {err.message}"
+ ) from err
+ elif "default" in p_meta_dict and p_meta_dict["default"] is not None:
+ params[p_name] = p_meta_dict["default"]
+ elif p_type in ["array", "children"]:
+ params[p_name] = []
+ elif p_meta_dict.get("required") is False or (
+ isinstance(p_meta, Param) and not p_meta.required
+ ):
+ pass
+ else:
+ raise ValueError(
+ f"Missing required parameter '{p_name}' for template"
+ f" '{template_id}'"
+ )
+
+ # Merge in passed params that may not be in schema
+ for k, v in passed_params.items():
+ if k not in params:
+ params[k] = v
+
+ expanded_components: List[Dict[str, Any]] = []
+
+ # 2. First pass: Map internal component IDs, handle slots & loop unrolling
+ components_list = getattr(layout, "components", [])
+ for comp in components_list:
+ comp_copy = (
+ comp.to_dict() if isinstance(comp, TemplateComponent) else dict(comp)
+ )
+ comp_copy["id"] = self._map_id(comp_copy["id"], instance_id)
+
+ if "child" in comp_copy:
+ is_slot, slot_val = self._resolve_slot(comp_copy["child"], params)
+ if is_slot:
+ if slot_val is None:
+ comp_copy.pop("child", None)
+ else:
+ comp_copy["child"] = slot_val
+ else:
+ if isinstance(comp_copy["child"], str):
+ comp_copy["child"] = self._map_id(
+ comp_copy["child"], instance_id
+ )
+
+ if "children" in comp_copy:
+ is_slot, slot_val = self._resolve_slot(comp_copy["children"], params)
+ if is_slot:
+ if slot_val is None:
+ comp_copy["children"] = []
+ elif isinstance(slot_val, list):
+ comp_copy["children"] = slot_val
+ else:
+ comp_copy["children"] = [slot_val]
+ elif (
+ isinstance(comp_copy["children"], dict)
+ and "param" in comp_copy["children"]
+ and (
+ "template" in comp_copy["children"]
+ or "item" in comp_copy["children"]
+ )
+ ):
+ children_meta = comp_copy["children"]
+ param_name = children_meta["param"]
+ array_data = params.get(param_name, [])
+
+ if not isinstance(array_data, list):
+ raise ValueError(
+ f"Template '{template_id}': Parameter '{param_name}'"
+ " must be an array/list for loop unrolling."
+ )
+
+ unrolled_child_ids = []
+
+ # Case A: Inline item layout loop
+ if "item" in children_meta and isinstance(
+ children_meta["item"], list
+ ):
+ item_comps = children_meta["item"]
+ as_var = children_meta.get("as")
+ for idx, item in enumerate(array_data):
+ sub_instance_id = f"{comp_copy['id']}_item_{idx}"
+ unrolled_child_ids.append(sub_instance_id)
+
+ item_dict = (
+ dict(item)
+ if isinstance(item, dict)
+ else {"value": item}
+ )
+ sub_params = {**params, **item_dict}
+ if as_var:
+ sub_params[as_var] = item_dict
+
+ inline_template = StaticTemplate(
+ name=f"{template_id}_inline_{idx}",
+ template_id=f"{template_id}_inline_{idx}",
+ catalogs=getattr(
+ layout, "catalogs", list(self.catalogs.keys())
+ ),
+ parameters={},
+ components=item_comps,
+ )
+ sub_expanded = self._expand_static_layout(
+ sub_instance_id,
+ inline_template,
+ sub_params,
+ _depth=_depth + 1,
+ _call_stack=_call_stack,
+ )
+ expanded_components.extend(sub_expanded)
+
+ # Case B: Named template loop
+ elif "template" in children_meta:
+ item_template_id = children_meta["template"]
+ for idx, item in enumerate(array_data):
+ sub_instance_id = f"{comp_copy['id']}_item_{idx}"
+ unrolled_child_ids.append(sub_instance_id)
+ sub_params = (
+ item if isinstance(item, dict) else {"value": item}
+ )
+ sub_expanded = self.expand_template(
+ sub_instance_id,
+ item_template_id,
+ sub_params,
+ _depth=_depth + 1,
+ _call_stack=_call_stack,
+ )
+ expanded_components.extend(sub_expanded)
+
+ comp_copy["children"] = unrolled_child_ids
+ else:
+ comp_copy["children"] = self._map_child_list(
+ comp_copy["children"], instance_id, params
+ )
+
+ comp_final = _substitute_params(comp_copy, params)
+ expanded_components.append(comp_final)
+
+ # 4. Second pass: Flatten any nested template invocations
+ final_list: A2UIComponentList = []
+ for c in expanded_components:
+ c_type = c.get("component")
+ if c_type in self.templates:
+ nested_instance_id = c["id"]
+ nested_template_id = c_type
+ nested_params = self._get_template_params(
+ c, self.templates[nested_template_id]
+ )
+ nested_expanded = self.expand_template(
+ nested_instance_id,
+ nested_template_id,
+ nested_params,
+ _depth=_depth + 1,
+ _call_stack=_call_stack,
+ )
+ final_list.extend(nested_expanded)
+ else:
+ comp_out = dict(c)
+ if "0.9" in self.version:
+ comp_out.pop("catalogId", None)
+ elif "1.0" in self.version:
+ if "catalogId" not in comp_out:
+ matching = [
+ cat
+ for cat in getattr(layout, "catalogs", [])
+ if c_type
+ in self.catalogs.get(cat, {}).get("components", {})
+ ]
+ if matching and matching[0] != self.base_catalog_id:
+ comp_out["catalogId"] = matching[0]
+ final_list.append(comp_out)
+
+ return final_list
+
+ def process_message(
+ self, message: Union[A2UIMessage, Sequence[A2UIMessage]]
+ ) -> Union[A2UIMessage, List[A2UIMessage]]:
+ """Intercepts A2UI server-to-client messages and unwraps any embedded template components."""
+ if isinstance(message, list):
+ return [self.process_message(m) for m in message]
+
+ if not isinstance(message, dict):
+ return message
+
+ msg_copy = dict(message)
+
+ for envelope_key in ["createSurface", "updateComponents"]:
+ if envelope_key in msg_copy:
+ payload = dict(msg_copy[envelope_key])
+ if (
+ envelope_key == "createSurface"
+ and "catalogId" not in payload
+ and self.base_catalog_id is not None
+ ):
+ payload["catalogId"] = self.base_catalog_id
+ if "components" in payload:
+ components = payload["components"]
+
+ # Normalize single top-level template instances to root ID in createSurface
+ if envelope_key == "createSurface" and len(components) == 1:
+ single_comp = components[0]
+ if (
+ isinstance(single_comp, dict)
+ and single_comp.get("component") in self.templates
+ ):
+ fixed_comp = dict(single_comp)
+ fixed_comp["id"] = "root"
+ components = [fixed_comp]
+
+ expanded_list: A2UIComponentList = []
+ for comp in components:
+ comp_type = comp.get("component")
+ if comp_type in self.templates:
+ instance_id = comp.get("id", "root")
+ params = self._get_template_params(
+ comp, self.templates[comp_type]
+ )
+ expanded = self.expand_template(
+ instance_id, comp_type, params
+ )
+ expanded_list.extend(expanded)
+ else:
+ expanded_list.append(comp)
+
+ payload["components"] = expanded_list
+ msg_copy[envelope_key] = payload
+
+ return msg_copy
+
+ def _promote_parameter(self, p_meta: Dict[str, Any]) -> JSONSchemaDict:
+ """Promotes a template parameter to an A2UI catalog schema property."""
+ if not isinstance(p_meta, dict):
+ return p_meta
+
+ common_types_url = (
+ "https://a2ui.org/specification/v0_9/common_types.json"
+ if "0.9" in self.version
+ else "https://a2ui.org/specification/v1_0/common_types.json"
+ )
+
+ p_type = p_meta.get("type")
+ if p_type == "child":
+ res = {"$ref": f"{common_types_url}#/$defs/ComponentId"}
+ for k in ["title", "description", "default"]:
+ if k in p_meta:
+ res[k] = p_meta[k]
+ return res
+ if p_type == "children":
+ res = {"$ref": f"{common_types_url}#/$defs/ChildList"}
+ for k in ["title", "description", "default"]:
+ if k in p_meta:
+ res[k] = p_meta[k]
+ return res
+ if p_type == "action":
+ res = {"$ref": f"{common_types_url}#/$defs/Action"}
+ for k in ["title", "description", "default"]:
+ if k in p_meta:
+ res[k] = p_meta[k]
+ return res
+ if p_type == "enum" and "values" in p_meta:
+ res = {
+ "type": "string",
+ "enum": p_meta["values"],
+ }
+ for k in ["title", "description", "default"]:
+ if k in p_meta:
+ res[k] = p_meta[k]
+ return res
+
+ ref_map = {
+ "string": f"{common_types_url}#/$defs/DynamicString",
+ "number": f"{common_types_url}#/$defs/DynamicNumber",
+ "integer": f"{common_types_url}#/$defs/DynamicNumber",
+ "boolean": f"{common_types_url}#/$defs/DynamicBoolean",
+ }
+
+ target_ref = ref_map.get(str(p_type))
+ if target_ref:
+ promoted: JSONSchemaDict = {"allOf": [{"$ref": target_ref}]}
+ metadata = {}
+ for k in ["title", "description", "default"]:
+ if k in p_meta:
+ metadata[k] = p_meta[k]
+ if metadata:
+ promoted["allOf"].append(metadata)
+ return promoted
+
+ return dict(p_meta)
+
+ def _validate_templates(self) -> None:
+ """Validates all registered templates against declared catalogs and component references."""
+ for t_key, template in list(self.templates.items()):
+ t_name = getattr(template, "name", template.template_id)
+ if t_key != t_name:
+ continue
+
+ # 1. Resolve declared catalogs on template
+ t_catalogs = getattr(template, "catalogs", [])
+ if isinstance(t_catalogs, str):
+ t_catalogs = [t_catalogs]
+ template.catalogs = t_catalogs
+
+ if not t_catalogs:
+ if len(self.catalogs) == 1:
+ t_catalogs = list(self.catalogs.keys())
+ template.catalogs = t_catalogs
+ else:
+ raise ValueError(
+ f"Template '{t_name}' must declare which catalog(s) it is"
+ " written against via 'catalogs'. Registered catalogs:"
+ f" {list(self.catalogs.keys())}"
+ )
+
+ for c_uri in t_catalogs:
+ if c_uri not in self.catalogs:
+ raise ValueError(
+ f"Template '{t_name}' declares catalog '{c_uri}', which is not"
+ " registered in TemplateProcessor. Available catalogs:"
+ f" {list(self.catalogs.keys())}"
+ )
+
+ # In v0.9, a template cannot span multiple catalogs
+ if "0.9" in self.version and len(t_catalogs) > 1:
+ raise ValueError(
+ f"Template '{t_name}' declares multiple catalogs {t_catalogs}, but"
+ f" A2UI {self.version} only supports a single catalog."
+ )
+
+ # 2. Validate template definition schema if static
+ if isinstance(template, StaticTemplate):
+ template.validate_definition()
+
+ # 3. Validate components in layout
+ layout = getattr(template, "layout", None) or template
+ comps = getattr(layout, "components", [])
+ for comp in comps:
+ comp_dict = (
+ comp.to_dict() if isinstance(comp, TemplateComponent) else comp
+ )
+ comp_type = comp_dict.get("component")
+ if not comp_type:
+ raise ValueError(
+ f"Component in template '{t_name}' is missing 'component' type."
+ )
+
+ # Check if component is a sub-template invocation
+ if (
+ comp_type in self.templates
+ or comp_type in self.templates_by_id
+ or comp_type in getattr(template, "imports", [])
+ ):
+ continue
+
+ # Otherwise it must be a primitive in the declared catalogs
+ matching_cats = [
+ cat_uri
+ for cat_uri in t_catalogs
+ if comp_type in self.catalogs[cat_uri].get("components", {})
+ ]
+
+ explicit_cat = comp_dict.get("catalogId") or getattr(
+ comp, "catalog_id", None
+ )
+ if explicit_cat:
+ if explicit_cat not in t_catalogs:
+ raise ValueError(
+ f"Component '{comp_type}' in template '{t_name}' specifies"
+ f" catalogId '{explicit_cat}', which is not in template's"
+ f" declared catalogs: {t_catalogs}"
+ )
+ if comp_type not in self.catalogs[explicit_cat].get(
+ "components", {}
+ ):
+ raise ValueError(
+ f"Component '{comp_type}' not found in catalog"
+ f" '{explicit_cat}'"
+ )
+ else:
+ if len(matching_cats) == 0:
+ raise ValueError(
+ f"Component '{comp_type}' in template '{t_name}' was not"
+ f" found in any declared catalog: {t_catalogs}"
+ )
+ elif len(matching_cats) > 1:
+ raise ValueError(
+ f"Component '{comp_type}' in template '{t_name}' is"
+ " ambiguous across multiple declared catalogs:"
+ f" {matching_cats}. Specify 'catalogId' on the component."
+ )
+
+ def validate_templates(self) -> None:
+ """Deprecated alias for _validate_templates."""
+ self._validate_templates()
+
+ def _get_template_params(
+ self,
+ comp: A2UIComponent,
+ template: Union[BaseTemplate, Template, StaticTemplate, DynamicTemplate],
+ ) -> Dict[str, Any]:
+ """Extracts passed parameters from a component dictionary."""
+ params: Dict[str, Any] = {}
+ raw_keys = template.parameters.keys() if hasattr(template, "parameters") else []
+ for p_name in raw_keys:
+ if p_name in comp:
+ params[p_name] = comp[p_name]
+ return params
diff --git a/agent_sdks/python/a2ui_agent/src/a2ui/template/manager.py b/agent_sdks/python/a2ui_agent/src/a2ui/template/manager.py
deleted file mode 100644
index 3b34254b45..0000000000
--- a/agent_sdks/python/a2ui_agent/src/a2ui/template/manager.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright 2024 Google LLC
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# https://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from typing import Optional, Any, Union
-from a2ui.inference_format import InferenceFormat
-from a2ui.core.schema.client_capabilities import V09Capabilities
-
-
-class A2uiTemplateManager(InferenceFormat):
- """Manages prompt compilation and payload processing for template definitions."""
-
- @property
- def parser(self) -> Any:
- """The parser instance associated with the template manager."""
- raise NotImplementedError("This method is not yet implemented.")
-
- @property
- def prompt_generator(self) -> Any:
- """The prompt generator instance associated with the template manager."""
- raise NotImplementedError("This method is not yet implemented.")
-
- def generate_system_prompt(
- self,
- role_description: str,
- workflow_description: str = "",
- ui_description: str = "",
- client_ui_capabilities: Optional[Union[dict[str, Any], V09Capabilities]] = None,
- allowed_components: Optional[list[str]] = None,
- allowed_messages: Optional[list[str]] = None,
- include_schema: bool = False,
- include_examples: bool = False,
- validate_examples: bool = False,
- ) -> str:
- """Generates a system prompt for requests (not yet implemented)."""
- # TODO: Implementation logic for Template Manager
- raise NotImplementedError("This method is not yet implemented.")
diff --git a/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/README.md b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/README.md
new file mode 100644
index 0000000000..0e63eeaedb
--- /dev/null
+++ b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/README.md
@@ -0,0 +1,63 @@
+# A2UI Template Conformance Test Suite
+
+This directory contains the language-agnostic, data-driven conformance test suite for A2UI Templates.
+
+While currently maintained within the Python Agent SDK (`agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/`), the suite is defined entirely in declarative YAML and JSON Schema to enable seamless graduation to the root `conformance/templates/` directory as cross-platform SDKs (Dart, TypeScript, Kotlin) add template engines.
+
+---
+
+## Directory Structure
+
+```
+conformance/
+├── schema/
+│ └── template_conformance_schema.json <-- JSON Schema validating all YAML test suites
+├── suites/
+│ ├── 01_substitution.yaml <-- Exact match, interpolation, AST expressions, token escaping
+│ ├── 02_static_expansion.yaml <-- Single/multi-child expansion, slots, data bindings
+│ ├── 03_loop_unrolling.yaml <-- Inline loops, named loops, empty arrays, 2D unrolling
+│ ├── 04_parameter_validation.yaml <-- Parameter type enforcement, enum validation, required fields
+│ ├── 05_message_interception.yaml <-- createSurface, updateComponents, multi-envelope streams
+│ └── 06_error_invariants.yaml <-- Unregistered templates, cycle guards, recursion limits
+├── test_template_conformance.py <-- Pytest harness running the entire suite
+└── README.md
+```
+
+---
+
+## Action Runners
+
+Each test case declares an `action` attribute:
+
+1. **`substitute_params`**:
+ - Tests `_substitute_params(val, params)` directly.
+ - Asserts exact value and type preservation (integers, booleans, objects, arrays), string interpolation, AST expressions (`format`, `concat`), and literal escaping (`\${token}`).
+
+2. **`expand_template`**:
+ - Registers defined template(s) with `TemplateProcessor`.
+ - Executes `processor.expand_template(instance_id, template_id, args)`.
+ - Asserts exact component list structure and synthetic ID generation.
+
+3. **`process_message`**:
+ - Intercepts A2UI messages (`createSurface`, `updateComponents`).
+ - Asserts unrolling of template instances into standard primitive components.
+
+4. **`validate_template`**:
+ - Tests template ingestion and version validation (`version: "0.1"`).
+ - Asserts validation errors on invalid or missing version fields.
+
+---
+
+## Graduation to Cross-Platform
+
+When A2UI Templates graduate from experimental to standard protocol:
+
+1. Move the entire `conformance/` directory to root:
+ ```bash
+ mv agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/ conformance/templates/
+ ```
+2. The `suites/*.yaml` test definitions require **zero modifications**.
+3. Implement standard harnesses in other target languages:
+ - **TypeScript / React / Lit**: Vitest harness reading `suites/*.yaml`.
+ - **Dart / Flutter**: `package:test` harness reading `suites/*.yaml`.
+ - **Kotlin**: JUnit5 harness reading `suites/*.yaml`.
diff --git a/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/schema/template_conformance_schema.json b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/schema/template_conformance_schema.json
new file mode 100644
index 0000000000..d68f8a11ac
--- /dev/null
+++ b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/schema/template_conformance_schema.json
@@ -0,0 +1,75 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://a2ui.org/conformance/template_conformance_schema.json",
+ "title": "A2UI Template Conformance Test Suite Schema",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "required": ["name", "action"],
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "Unique name of the test case."
+ },
+ "description": {
+ "type": "string",
+ "description": "Human-readable description of what this test case asserts."
+ },
+ "action": {
+ "type": "string",
+ "enum": [
+ "substitute_params",
+ "expand_template",
+ "process_message",
+ "validate_template",
+ "generate_catalog"
+ ],
+ "description": "The template engine action being tested."
+ },
+ "templates": {
+ "type": "array",
+ "description": "List of template definitions registered with the processor."
+ },
+ "template": {
+ "type": "object",
+ "description": "Single template definition registered with the processor."
+ },
+ "instance_id": {
+ "type": "string",
+ "description": "Target component instance ID for expansion."
+ },
+ "template_id": {
+ "type": "string",
+ "description": "Identifier of the template being expanded."
+ },
+ "base_catalog": {
+ "type": ["object", "null"],
+ "description": "Optional base catalog schema provided to processor."
+ },
+ "catalogs": {
+ "description": "Optional catalogs schema provided to processor."
+ },
+ "args": {
+ "description": "Arguments/parameters passed to the action."
+ },
+ "message": {
+ "description": "Message payload passed to process_message."
+ },
+ "expect": {
+ "description": "Expected result matching the action return value."
+ },
+ "expect_error": {
+ "type": "object",
+ "properties": {
+ "category": {
+ "type": "string"
+ },
+ "message": {
+ "type": "string"
+ }
+ },
+ "description": "Expected error category and error substring."
+ }
+ }
+ }
+}
diff --git a/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/01_substitution.yaml b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/01_substitution.yaml
new file mode 100644
index 0000000000..dc8bbfb471
--- /dev/null
+++ b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/01_substitution.yaml
@@ -0,0 +1,218 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+- name: test_exact_integer_preservation
+ description: Verifies that exact token match preserves integer type without string
+ coercion.
+ action: substitute_params
+ args:
+ value: ${count}
+ params:
+ count: 42
+ expect: 42
+- name: test_exact_boolean_preservation
+ description: Verifies that exact token match preserves boolean type.
+ action: substitute_params
+ args:
+ value: ${isEnabled}
+ params:
+ isEnabled: true
+ expect: true
+- name: test_exact_array_preservation
+ description: Verifies that exact token match preserves array data structure.
+ action: substitute_params
+ args:
+ value: ${tags}
+ params:
+ tags:
+ - admin
+ - developer
+ - tester
+ expect:
+ - admin
+ - developer
+ - tester
+- name: test_exact_object_preservation
+ description: Verifies that exact token match preserves nested dictionary structure.
+ action: substitute_params
+ args:
+ value: ${binding}
+ params:
+ binding:
+ path: /session/user/name
+ expect:
+ path: /session/user/name
+- name: test_in_string_interpolation
+ description: Verifies string interpolation when token appears with surrounding text.
+ action: substitute_params
+ args:
+ value: Hello, ${name}!
+ params:
+ name: Alice
+ expect: Hello, Alice!
+- name: test_multiple_in_string_interpolations
+ description: Verifies multiple tokens interpolated in a single string.
+ action: substitute_params
+ args:
+ value: ${dept} - Grade ${grade} (${active})
+ params:
+ dept: Engineering
+ grade: 7
+ active: true
+ expect: Engineering - Grade 7 (True)
+- name: test_token_escaping_exact
+ description: Verifies that leading backslash prevents substitution of exact token.
+ action: substitute_params
+ args:
+ value: \${keep_literal}
+ params:
+ keep_literal: not_used
+ expect: ${keep_literal}
+- name: test_token_escaping_in_string
+ description: Verifies escaping in mixed string preserves literal token while substituting
+ unescaped token.
+ action: substitute_params
+ args:
+ value: Literal \${keep} and dynamic ${replace}
+ params:
+ keep: ignored
+ replace: substituted
+ expect: Literal ${keep} and dynamic substituted
+- name: test_deep_dot_notation_nested_dict
+ description: Verifies resolving multi-level dot-separated path in nested dictionary.
+ action: substitute_params
+ args:
+ value: ${user.profile.details.tier}
+ params:
+ user:
+ profile:
+ details:
+ tier: Enterprise
+ expect: Enterprise
+- name: test_deep_dot_notation_array_index
+ description: Verifies resolving dot-separated path with numeric array indices.
+ action: substitute_params
+ args:
+ value: ${teams.0.members.1.name}
+ params:
+ teams:
+ - members:
+ - name: First
+ - name: Second
+ expect: Second
+- name: test_format_expression_ast
+ description: Verifies evaluating format expression dictionary with arguments.
+ action: substitute_params
+ args:
+ value:
+ format: "Progress: {current} of {total} ({pct}%)"
+ args:
+ current: ${metrics.completed}
+ total: ${metrics.total}
+ pct: 75
+ params:
+ metrics:
+ completed: 15
+ total: 20
+ expect: "Progress: 15 of 20 (75%)"
+- name: test_concat_expression_ast
+ description: Verifies evaluating concat expression combining string literals and
+ param references.
+ action: substitute_params
+ args:
+ value:
+ concat:
+ - "Status: "
+ - param: state
+ - " ("
+ - param: code
+ - )
+ params:
+ state: OK
+ code: 200
+ expect: "Status: OK (200)"
+- name: test_concat_with_none_omits_part
+ description: Verifies that None or unresolved parts in concat do not insert 'None'
+ strings.
+ action: substitute_params
+ args:
+ value:
+ concat:
+ - Prefix-
+ - param: missing
+ - -Suffix
+ params: {}
+ expect: Prefix--Suffix
+- name: test_param_ref_with_default
+ description: Verifies that direct param ref uses explicit default when param missing.
+ action: substitute_params
+ args:
+ value:
+ param: role
+ default: Contributor
+ params: {}
+ expect: Contributor
+- name: test_mustache_exact_integer_preservation
+ description: Verifies that exact Mustache token match preserves integer type.
+ action: substitute_params
+ args:
+ value: "{{ count }}"
+ params:
+ count: 42
+ expect: 42
+- name: test_mustache_exact_boolean_preservation
+ description: Verifies that exact Mustache token match preserves boolean type.
+ action: substitute_params
+ args:
+ value: "{{ isEnabled }}"
+ params:
+ isEnabled: true
+ expect: true
+- name: test_mustache_exact_array_preservation
+ description: Verifies that exact Mustache token match preserves array data structure.
+ action: substitute_params
+ args:
+ value: "{{ tags }}"
+ params:
+ tags:
+ - admin
+ - developer
+ expect:
+ - admin
+ - developer
+- name: test_mustache_string_interpolation
+ description: Verifies multiple Mustache tokens interpolated inside string.
+ action: substitute_params
+ args:
+ value: "{{ dept }} - Grade {{ grade }}"
+ params:
+ dept: Eng
+ grade: 9
+ expect: "Eng - Grade 9"
+- name: test_mustache_escaping
+ description: Verifies that escaped Mustache syntax is emitted as a literal.
+ action: substitute_params
+ args:
+ value: 'Literal \{{ keep }} and dynamic {{ replace }}'
+ params:
+ replace: substituted
+ expect: "Literal {{ keep }} and dynamic substituted"
+- name: test_mustache_client_data_binding_passthrough
+ description: Verifies that client ${/data/path} bindings are preserved untouched.
+ action: substitute_params
+ args:
+ value: "Client: ${/user/name}, Server: {{ serverVal }}"
+ params:
+ serverVal: local
+ expect: "Client: ${/user/name}, Server: local"
diff --git a/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/02_static_expansion.yaml b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/02_static_expansion.yaml
new file mode 100644
index 0000000000..33fb8a0295
--- /dev/null
+++ b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/02_static_expansion.yaml
@@ -0,0 +1,230 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+- name: test_single_child_card_expansion
+ description: Verifies expanding card container with single child and deterministic
+ ID prefixing.
+ action: expand_template
+ template:
+ version: "0.1"
+ templateId: SimpleCard
+ parameters:
+ title:
+ type: string
+ layout:
+ component: Card
+ child:
+ component: Text
+ text: ${title}
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: SimpleCard
+ instance_id: card_inst
+ template_id: SimpleCard
+ args:
+ title: Welcome
+ expect:
+ - id: card_inst
+ component: Card
+ child: card_inst_child_text
+ - id: card_inst_child_text
+ component: Text
+ text: Welcome
+- name: test_default_param_values
+ description: Verifies default value is assigned when argument is omitted.
+ action: expand_template
+ template:
+ version: "0.1"
+ templateId: ProfileHeader
+ parameters:
+ name:
+ type: string
+ role:
+ type: string
+ default: Team Member
+ layout:
+ component: Column
+ children:
+ - component: Text
+ text: ${name}
+ - component: Text
+ text: ${role}
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: ProfileHeader
+ instance_id: prof_1
+ template_id: ProfileHeader
+ args:
+ name: Bob
+ expect:
+ - id: prof_1
+ component: Column
+ children:
+ - prof_1_child_0_text
+ - prof_1_child_1_text
+ - id: prof_1_child_0_text
+ component: Text
+ text: Bob
+ - id: prof_1_child_1_text
+ component: Text
+ text: Team Member
+- name: test_higher_order_child_slot
+ description: Verifies passing a component ID into a child slot parameter.
+ action: expand_template
+ template:
+ version: "0.1"
+ templateId: ContainerSlot
+ parameters:
+ content:
+ type: child
+ layout:
+ component: Card
+ child: ${content}
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: ContainerSlot
+ instance_id: slot_inst
+ template_id: ContainerSlot
+ args:
+ content: custom_chart_comp_id
+ expect:
+ - id: slot_inst
+ component: Card
+ child: custom_chart_comp_id
+- name: test_unfilled_optional_child_slot_omitted
+ description: Verifies that when an optional child slot parameter is omitted, the
+ child property is omitted from output.
+ action: expand_template
+ template:
+ version: "0.1"
+ templateId: OptionalChildCard
+ parameters:
+ optionalChild:
+ type: child
+ required: false
+ layout:
+ component: Card
+ child: ${optionalChild}
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: OptionalChildCard
+ instance_id: opt_card
+ template_id: OptionalChildCard
+ args: {}
+ expect:
+ - id: opt_card
+ component: Card
+- name: test_higher_order_action_slot
+ description: Verifies binding an Action object to a button action slot via parameter.
+ action: expand_template
+ template:
+ version: "0.1"
+ templateId: ActionButton
+ parameters:
+ label:
+ type: string
+ onPress:
+ type: action
+ layout:
+ component: Button
+ text: ${label}
+ action: ${onPress}
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: ActionButton
+ instance_id: btn_inst
+ template_id: ActionButton
+ args:
+ label: Deploy
+ onPress:
+ name: triggerDeployment
+ parameters:
+ env: production
+ expect:
+ - id: btn_inst
+ component: Button
+ text: Deploy
+ action:
+ name: triggerDeployment
+ parameters:
+ env: production
+- name: test_data_binding_passthrough
+ description: Verifies passing a client DataBinding dictionary through a parameter
+ preserving dictionary structure.
+ action: expand_template
+ template:
+ version: "0.1"
+ templateId: BoundMetric
+ parameters:
+ label:
+ type: string
+ valueBinding:
+ type: object
+ layout:
+ component: Text
+ text: ${valueBinding}
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: BoundMetric
+ instance_id: bound_txt
+ template_id: BoundMetric
+ args:
+ label: CPU
+ valueBinding:
+ path: /system/cpu/usage
+ expect:
+ - id: bound_txt
+ component: Text
+ text:
+ path: /system/cpu/usage
+- name: test_nested_template_invocation
+ description: Verifies a parent template layout referencing a child template expanding
+ recursively.
+ action: expand_template
+ templates:
+ - version: "0.1"
+ templateId: Badge
+ parameters:
+ text:
+ type: string
+ layout:
+ component: Text
+ text: "[${text}]"
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: Badge
+ - version: "0.1"
+ templateId: BadgeCard
+ parameters:
+ tag:
+ type: string
+ layout:
+ component: Card
+ child:
+ component: Badge
+ text: ${tag}
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: BadgeCard
+ instance_id: parent_inst
+ template_id: BadgeCard
+ args:
+ tag: PRO
+ expect:
+ - id: parent_inst
+ component: Card
+ child: parent_inst_child_badge
+ - id: parent_inst_child_badge
+ component: Text
+ text: "[PRO]"
diff --git a/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/03_loop_unrolling.yaml b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/03_loop_unrolling.yaml
new file mode 100644
index 0000000000..b8c353925e
--- /dev/null
+++ b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/03_loop_unrolling.yaml
@@ -0,0 +1,208 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+- name: test_inline_item_loop_unrolling
+ description: Verifies inline component layout unrolling for each element of an array.
+ action: expand_template
+ template:
+ version: "0.1"
+ templateId: MemberList
+ parameters:
+ members:
+ type: array
+ layout:
+ component: Column
+ children:
+ loop:
+ param: members
+ as: m
+ item:
+ component: Row
+ children:
+ - component: Text
+ text: ${m.name}
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: MemberList
+ instance_id: team_col
+ template_id: MemberList
+ args:
+ members:
+ - name: Alice
+ - name: Bob
+ expect:
+ - id: team_col
+ component: Column
+ children:
+ - team_col_item_0
+ - team_col_item_1
+ - id: team_col_item_0
+ component: Row
+ children:
+ - team_col_item_0_child_0_text
+ - id: team_col_item_0_child_0_text
+ component: Text
+ text: Alice
+ - id: team_col_item_1
+ component: Row
+ children:
+ - team_col_item_1_child_0_text
+ - id: team_col_item_1_child_0_text
+ component: Text
+ text: Bob
+- name: test_named_template_loop_unrolling
+ description: Verifies unrolling an array by invoking another registered template
+ for each element.
+ action: expand_template
+ templates:
+ - version: "0.1"
+ templateId: TagBadge
+ parameters:
+ label:
+ type: string
+ layout:
+ component: Text
+ text: "#${label}"
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: TagBadge
+ - version: "0.1"
+ templateId: TagContainer
+ parameters:
+ tags:
+ type: array
+ layout:
+ component: Row
+ children:
+ loop:
+ param: tags
+ template: TagBadge
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: TagContainer
+ instance_id: row_tags
+ template_id: TagContainer
+ args:
+ tags:
+ - label: alpha
+ - label: beta
+ expect:
+ - id: row_tags
+ component: Row
+ children:
+ - row_tags_item_0
+ - row_tags_item_1
+ - id: row_tags_item_0
+ component: Text
+ text: "#alpha"
+ - id: row_tags_item_1
+ component: Text
+ text: "#beta"
+- name: test_empty_loop_array_emits_empty_children
+ description: Verifies that an empty array parameter unrolls cleanly to empty children
+ list.
+ action: expand_template
+ template:
+ version: "0.1"
+ templateId: EmptyListChecker
+ parameters:
+ items:
+ type: array
+ layout:
+ component: Column
+ children:
+ loop:
+ param: items
+ item:
+ component: Text
+ text: Item
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: EmptyListChecker
+ instance_id: empty_col
+ template_id: EmptyListChecker
+ args:
+ items: []
+ expect:
+ - id: empty_col
+ component: Column
+ children: []
+- name: test_primitive_list_iteration
+ description: Verifies iterating over primitive strings in an array using item.value
+ fallback.
+ action: expand_template
+ template:
+ version: "0.1"
+ templateId: ColorChips
+ parameters:
+ colors:
+ type: array
+ layout:
+ component: Row
+ children:
+ loop:
+ param: colors
+ as: c
+ item:
+ component: Text
+ text: ${c.value}
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: ColorChips
+ instance_id: chip_row
+ template_id: ColorChips
+ args:
+ colors:
+ - Crimson
+ - Azure
+ expect:
+ - id: chip_row
+ component: Row
+ children:
+ - chip_row_item_0
+ - chip_row_item_1
+ - id: chip_row_item_0
+ component: Text
+ text: Crimson
+ - id: chip_row_item_1
+ component: Text
+ text: Azure
+- name: test_non_array_loop_parameter_raises_error
+ description: Verifies that passing a non-array string value to a loop raises a clear
+ ValidationError.
+ action: expand_template
+ template:
+ version: "0.1"
+ templateId: FailingLoop
+ parameters:
+ items:
+ type: array
+ layout:
+ component: Column
+ children:
+ loop:
+ param: items
+ item:
+ component: Text
+ text: Fail
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: FailingLoop
+ instance_id: fail_inst
+ template_id: FailingLoop
+ args:
+ items: not_an_array
+ expect_error:
+ category: ValidationError
+ message: failed validation
diff --git a/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/04_parameter_validation.yaml b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/04_parameter_validation.yaml
new file mode 100644
index 0000000000..8b309e4375
--- /dev/null
+++ b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/04_parameter_validation.yaml
@@ -0,0 +1,116 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+- name: test_parameter_type_validation_string_to_integer_fails
+ description: Verifies that passing a string to an integer parameter raises a validation
+ error.
+ action: expand_template
+ template:
+ version: "0.1"
+ templateId: IntegerParamCheck
+ parameters:
+ count:
+ type: integer
+ layout:
+ component: Text
+ text: "Count: ${count}"
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: IntegerParamCheck
+ instance_id: int_fail
+ template_id: IntegerParamCheck
+ args:
+ count: non_integer_string
+ expect_error:
+ category: ValidationError
+ message: failed validation
+- name: test_parameter_enum_validation_invalid_value_fails
+ description: Verifies that passing an unexpected value to an enum parameter raises
+ validation error.
+ action: expand_template
+ template:
+ version: "0.1"
+ templateId: EnumParamCheck
+ parameters:
+ status:
+ type: enum
+ values:
+ - ACTIVE
+ - SUSPENDED
+ - PENDING
+ layout:
+ component: Text
+ text: "Status: ${status}"
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: EnumParamCheck
+ instance_id: enum_fail
+ template_id: EnumParamCheck
+ args:
+ status: DELETED
+ expect_error:
+ category: ValidationError
+ message: failed validation
+- name: test_missing_required_parameter_raises_error
+ description: Verifies that omitting a required parameter with no default raises
+ an error.
+ action: expand_template
+ template:
+ version: "0.1"
+ templateId: RequiredParamCheck
+ parameters:
+ mandatory:
+ type: string
+ layout:
+ component: Text
+ text: ${mandatory}
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: RequiredParamCheck
+ instance_id: req_fail
+ template_id: RequiredParamCheck
+ args: {}
+ expect_error:
+ category: ValidationError
+ message: Missing required parameter 'mandatory'
+- name: test_unsupported_template_version_raises_error
+ description: Verifies that loading a template with unsupported version format raises
+ error.
+ action: validate_template
+ template:
+ version: "0.2"
+ templateId: FutureVersionTemplate
+ parameters: {}
+ layout:
+ component: Text
+ text: Future
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: FutureVersionTemplate
+ expect_error:
+ category: ValidationError
+ message: Unsupported template version '0.2'
+- name: test_missing_template_version_raises_error
+ description: Verifies that omitting version attribute completely raises error.
+ action: validate_template
+ template:
+ templateId: MissingVersionTemplate
+ parameters: {}
+ layout:
+ component: Text
+ text: No Version
+ name: MissingVersionTemplate
+ expect_error:
+ category: ValidationError
+ message: missing required 'version' attribute
diff --git a/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/05_message_interception.yaml b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/05_message_interception.yaml
new file mode 100644
index 0000000000..23fe2d0e44
--- /dev/null
+++ b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/05_message_interception.yaml
@@ -0,0 +1,170 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+- name: test_create_surface_envelope_unwrapping
+ description: Verifies that createSurface message wraps template instance and unwraps
+ into primitive components.
+ action: process_message
+ template:
+ version: "0.1"
+ templateId: SimpleCard
+ parameters:
+ title:
+ type: string
+ layout:
+ component: Card
+ child:
+ component: Text
+ text: ${title}
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: SimpleCard
+ message:
+ createSurface:
+ surfaceId: main
+ catalogId: https://a2ui.org/custom.json
+ components:
+ - id: root
+ component: SimpleCard
+ title: Unwrapped
+ expect:
+ createSurface:
+ surfaceId: main
+ catalogId: https://a2ui.org/custom.json
+ components:
+ - id: root
+ component: Card
+ child: root_child_text
+ - id: root_child_text
+ component: Text
+ text: Unwrapped
+- name: test_update_components_envelope_unwrapping
+ description: Verifies that updateComponents message with template instance expands
+ correctly.
+ action: process_message
+ template:
+ version: "0.1"
+ templateId: SimpleCard
+ parameters:
+ title:
+ type: string
+ layout:
+ component: Card
+ child:
+ component: Text
+ text: ${title}
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: SimpleCard
+ message:
+ updateComponents:
+ surfaceId: main
+ components:
+ - id: card_2
+ component: SimpleCard
+ title: Updated
+ expect:
+ updateComponents:
+ surfaceId: main
+ components:
+ - id: card_2
+ component: Card
+ child: card_2_child_text
+ - id: card_2_child_text
+ component: Text
+ text: Updated
+- name: test_mixed_primitives_and_templates_in_message
+ description: Verifies that non-template primitive components pass through untouched
+ alongside expanded templates.
+ action: process_message
+ template:
+ version: "0.1"
+ templateId: SimpleCard
+ parameters:
+ title:
+ type: string
+ layout:
+ component: Card
+ child:
+ component: Text
+ text: ${title}
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: SimpleCard
+ message:
+ updateComponents:
+ surfaceId: main
+ components:
+ - id: div_1
+ component: Divider
+ axis: horizontal
+ - id: card_mixed
+ component: SimpleCard
+ title: Mixed Content
+ expect:
+ updateComponents:
+ surfaceId: main
+ components:
+ - id: div_1
+ component: Divider
+ axis: horizontal
+ - id: card_mixed
+ component: Card
+ child: card_mixed_child_text
+ - id: card_mixed_child_text
+ component: Text
+ text: Mixed Content
+- name: test_batch_messages_stream_passthrough
+ description: Verifies processing a list of messages passing dataModel updates through
+ unaltered.
+ action: process_message
+ template:
+ version: "0.1"
+ templateId: SimpleCard
+ parameters:
+ title:
+ type: string
+ layout:
+ component: Card
+ child:
+ component: Text
+ text: ${title}
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: SimpleCard
+ message:
+ - updateDataModel:
+ path: /session/user
+ value:
+ name: Alice
+ - updateComponents:
+ surfaceId: main
+ components:
+ - id: batch_c
+ component: SimpleCard
+ title: Batch
+ expect:
+ - updateDataModel:
+ path: /session/user
+ value:
+ name: Alice
+ - updateComponents:
+ surfaceId: main
+ components:
+ - id: batch_c
+ component: Card
+ child: batch_c_child_text
+ - id: batch_c_child_text
+ component: Text
+ text: Batch
diff --git a/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/06_error_invariants.yaml b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/06_error_invariants.yaml
new file mode 100644
index 0000000000..c8bb843bec
--- /dev/null
+++ b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/conformance/suites/06_error_invariants.yaml
@@ -0,0 +1,70 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+- name: test_unregistered_template_raises_error
+ description: Verifies expanding an unregistered template ID raises a clear ValueError.
+ action: expand_template
+ templates: []
+ instance_id: inst_1
+ template_id: UnknownTemplate
+ args: {}
+ expect_error:
+ category: ValidationError
+ message: Template 'UnknownTemplate' is not registered
+- name: test_circular_reference_a_b_a
+ description: Verifies immediate detection of circular template references A -> B
+ -> A.
+ action: expand_template
+ templates:
+ - version: "0.1"
+ templateId: NodeA
+ parameters: {}
+ layout:
+ component: NodeB
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: NodeA
+ - version: "0.1"
+ templateId: NodeB
+ parameters: {}
+ layout:
+ component: NodeA
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: NodeB
+ instance_id: root_circ
+ template_id: NodeA
+ args: {}
+ expect_error:
+ category: ValidationError
+ message: Circular template reference detected
+- name: test_circular_reference_self
+ description: Verifies that a template referencing itself is immediately caught by
+ the cycle guard.
+ action: expand_template
+ templates:
+ - version: "0.1"
+ templateId: SelfLoop
+ parameters: {}
+ layout:
+ component: SelfLoop
+ catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+ name: SelfLoop
+ instance_id: root_self
+ template_id: SelfLoop
+ args: {}
+ expect_error:
+ category: ValidationError
+ message: Circular template reference detected
diff --git a/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/test_format.py b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/test_format.py
new file mode 100644
index 0000000000..e0d7c63c4a
--- /dev/null
+++ b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/test_format.py
@@ -0,0 +1,64 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Unit tests for A2UI Template Inference Format (format.py) focusing on ADK framework integration."""
+
+from a2ui.inference_formats.experimental.template import (
+ StaticTemplate,
+ TemplateInferenceFormat,
+)
+
+
+def test_template_inference_format_end_to_end():
+ """Verifies that TemplateInferenceFormat wraps ExpressFormat, generates prompts, and unrolls streaming chunks."""
+ yaml_tmpl = """
+version: "0.1"
+name: UserProfile
+catalogs:
+ - "https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json"
+parameters:
+ userId: {type: string}
+ userName: {type: string}
+ role: {type: string}
+layout:
+ component: Card
+ child:
+ component: Text
+ text: ${userName}
+"""
+ tmpl = StaticTemplate.from_yaml(yaml_tmpl)
+ manager = TemplateInferenceFormat(
+ templates=[tmpl],
+ surface_id="main_surface",
+ version="0.9.1",
+ )
+
+ # 1. Check prompt generation includes UserProfile signature when include_schema=True
+ prompt = manager.prompt_generator.generate(
+ role_description="Test Agent", include_schema=True
+ )
+ assert "UserProfile" in prompt
+
+ # 2. Check parsing and expansion of Express DSL response
+ llm_output = """
+ Here is your profile card:
+
+ root = UserProfile("usr_99", "Sarah Jenkins", "Lead Designer")
+
+ """
+
+ parts = manager.parser.parse_response(llm_output)
+ assert len(parts) == 1
+ assert "Here is your profile card:" in parts[0].text
+ assert parts[0].a2ui_json is not None
diff --git a/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/test_models.py b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/test_models.py
new file mode 100644
index 0000000000..cba1466cb7
--- /dev/null
+++ b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/test_models.py
@@ -0,0 +1,129 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Unit tests for A2UI Template Models (models.py) focusing on Python runtime integration."""
+
+from dataclasses import dataclass
+
+from a2ui.inference_formats.experimental.template.models import (
+ DynamicTemplate,
+ dynamic_template,
+ ParamType,
+ normalize_node,
+)
+
+
+def test_normalize_node_dataclass_support():
+ """Verifies that Python dataclass instances are normalized to plain dictionaries."""
+
+ @dataclass
+ class TextComponent:
+ component: str
+ text: str
+
+ node = TextComponent(component="Text", text="Hello Dataclass")
+ normalized = normalize_node(node)
+ assert isinstance(normalized, dict)
+ assert normalized == {"component": "Text", "text": "Hello Dataclass"}
+
+
+def test_normalize_node_duck_typing():
+ """Verifies that objects implementing to_dict() are properly normalized."""
+
+ class CustomNode:
+
+ def to_dict(self):
+ return {"component": "CustomCard", "score": 99}
+
+ node = CustomNode()
+ normalized = normalize_node(node)
+ assert isinstance(normalized, dict)
+ assert normalized == {"component": "CustomCard", "score": 99}
+
+
+def test_dynamic_template_signature_inference():
+ """Verifies that DynamicTemplate infers typed parameters and defaults from Python callable annotations."""
+
+ def my_resolver(userId: str, count: int = 5, active: bool = True) -> dict:
+ return {}
+
+ tmpl = DynamicTemplate(template_id="InferredTmpl", resolver=my_resolver)
+ params = tmpl.parameters
+
+ assert "userId" in params
+ assert params["userId"].type == ParamType.STRING
+ assert params["userId"].default is None
+
+ assert "count" in params
+ assert params["count"].type == ParamType.INTEGER
+ assert params["count"].default == 5
+
+ assert "active" in params
+ assert params["active"].type == ParamType.BOOLEAN
+ assert params["active"].default is True
+
+
+def test_dynamic_template_decorator_and_callability():
+ """Verifies that @dynamic_template decorates a function, infers metadata, and preserves callability."""
+
+ @dynamic_template(
+ catalogs=["https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"],
+ description="Generates a user badge with custom status.",
+ )
+ def user_badge(user_name: str, status: str = "Active", score: int = 100):
+ """Generates a user badge."""
+ return {
+ "component": "Card",
+ "child": {
+ "component": "Text",
+ "text": f"{user_name}: {status} ({score})",
+ },
+ }
+
+ # 1. Verify it acts as a DynamicTemplate instance
+ assert isinstance(user_badge, DynamicTemplate)
+ assert user_badge.name == "UserBadge"
+ assert user_badge.description == "Generates a user badge with custom status."
+ assert user_badge.catalogs == [
+ "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+ ]
+ assert "user_name" in user_badge.parameters
+ assert user_badge.parameters["user_name"].type == ParamType.STRING
+ assert user_badge.parameters["status"].default == "Active"
+ assert user_badge.parameters["score"].type == ParamType.INTEGER
+ assert user_badge.parameters["score"].default == 100
+
+ # 2. Verify it remains directly callable as a standard Python function
+ rendered = user_badge("Alice", status="Online", score=150)
+ assert isinstance(rendered, dict)
+ assert rendered["component"] == "Card"
+ assert rendered["child"]["text"] == "Alice: Online (150)"
+
+
+def test_dynamic_template_decorator_no_args():
+ """Verifies @dynamic_template works without parenthesis, extracting docstring and PascalCase name."""
+
+ @dynamic_template
+ def metric_tile(label: str, value: float = 0.0):
+ """KPI metric display tile."""
+ return {"component": "Text", "text": f"{label}: {value}"}
+
+ assert isinstance(metric_tile, DynamicTemplate)
+ assert metric_tile.name == "MetricTile"
+ assert metric_tile.description == "KPI metric display tile."
+ assert "label" in metric_tile.parameters
+ assert metric_tile.parameters["value"].type == ParamType.NUMBER
+
+ res = metric_tile("CPU", 99.4)
+ assert res == {"component": "Text", "text": "CPU: 99.4"}
diff --git a/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/test_processor.py b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/test_processor.py
new file mode 100644
index 0000000000..0b5668a1c5
--- /dev/null
+++ b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/test_processor.py
@@ -0,0 +1,495 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Unit tests for A2UI Template Processor (processor.py) focusing on Python runtime execution and typing."""
+
+import asyncio
+import json
+from pathlib import Path
+from typing import Any, Dict
+import pytest
+
+from a2ui.inference_formats.experimental.template import (
+ DynamicTemplate,
+ dynamic_template,
+ StaticTemplate,
+ TemplateProcessor,
+ TemplateId,
+ InstanceId,
+ ComponentId,
+ ParamPath,
+ TemplateParams,
+)
+from a2ui.inference_formats.experimental.template.processor import (
+ _resolve_param_path,
+ _substitute_params,
+)
+
+BASIC_CATALOG_PATH = (
+ Path(__file__).resolve().parents[7]
+ / "specification"
+ / "v0_9_1"
+ / "catalogs"
+ / "basic"
+ / "catalog.json"
+)
+BASIC_CATALOG: Dict[str, Any] = {}
+if BASIC_CATALOG_PATH.is_file():
+ with open(BASIC_CATALOG_PATH, "r", encoding="utf-8") as f:
+ BASIC_CATALOG = json.load(f)
+
+
+def test_dynamic_template_with_resolver():
+ """Verifies Mode B dynamic template where a native Python resolver fetches data and binds it to a static layout."""
+ layout_yaml = """
+version: "0.1"
+name: LiveStockCard
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+parameters:
+ ticker: {type: string}
+ price: {type: number, required: false}
+ changePct: {type: string, required: false}
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Text
+ text: "Stock: ${ticker}"
+ - component: Text
+ text: "Price: $${price}"
+ - component: Text
+ text: "Change: ${changePct}%"
+"""
+
+ mock_db = {
+ "GOOG": {"price": 175.50, "changePct": "+1.8"},
+ "AAPL": {"price": 220.10, "changePct": "-0.4"},
+ }
+
+ async def fetch_stock_data(ticker: str) -> Dict[str, Any]:
+ await asyncio.sleep(0.01)
+ return mock_db.get(ticker, {"price": 0.0, "changePct": "0.0"})
+
+ tmpl = DynamicTemplate(
+ name="LiveStockCard",
+ template_id="LiveStockCard",
+ catalogs=["https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"],
+ layout=layout_yaml,
+ resolver=fetch_stock_data,
+ description="Displays live stock pricing.",
+ )
+
+ processor = TemplateProcessor(templates=[tmpl], catalogs=BASIC_CATALOG)
+ expanded = processor.expand_template(
+ "stock_goog", "LiveStockCard", {"ticker": "GOOG"}
+ )
+
+ assert len(expanded) == 5
+ price_comp = next((c for c in expanded if c.get("text") == "Price: $175.5"), None)
+ assert price_comp is not None
+
+
+def test_programmatic_dynamic_template_render():
+ """Verifies Mode A dynamic template where a native Python callable directly constructs the component tree."""
+
+ def render_payroll(department: str = "Engineering", includeBonus: bool = True):
+ employees = [
+ {"name": "Alice", "salary": 150000, "bonus": 20000},
+ {"name": "Bob", "salary": 140000, "bonus": 15000},
+ ]
+ rows = []
+ for emp in employees:
+ cols = [{"component": "Text", "text": emp["name"]}]
+ if includeBonus:
+ cols.append({"component": "Text", "text": f"Bonus: ${emp['bonus']}"})
+ rows.append({"component": "Row", "children": cols})
+
+ return {
+ "component": "Card",
+ "child": {
+ "component": "Column",
+ "children": [
+ {"component": "Text", "text": f"Payroll: {department}"},
+ *rows,
+ ],
+ },
+ }
+
+ tmpl = DynamicTemplate(
+ name="PayrollSummary",
+ template_id="PayrollSummary",
+ catalogs=["https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"],
+ render=render_payroll,
+ description="Dynamic payroll summary calculation.",
+ )
+
+ processor = TemplateProcessor(templates=[tmpl], catalogs=BASIC_CATALOG)
+ expanded = processor.expand_template(
+ "payroll_root", "PayrollSummary", {"department": "AI Research"}
+ )
+
+ assert any(c.get("text") == "Payroll: AI Research" for c in expanded)
+ assert any(c.get("text") == "Bonus: $20000" for c in expanded)
+
+
+def test_programmatic_dynamic_template_extra_params_filtered():
+ """Verifies that dynamic render functions with explicit signatures do not break when receiving unexpected kwargs."""
+
+ def render_card(title: str):
+ return {"component": "Text", "text": title}
+
+ tmpl = DynamicTemplate(
+ name="SimpleCard",
+ template_id="SimpleCard",
+ catalogs=["https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"],
+ render=render_card,
+ )
+ processor = TemplateProcessor(templates=[tmpl], catalogs=BASIC_CATALOG)
+
+ expanded = processor.expand_template(
+ "inst",
+ "SimpleCard",
+ {"title": "Filtered", "extra1": "drop_me", "extra2": 42},
+ )
+ assert len(expanded) == 1
+ assert expanded[0]["text"] == "Filtered"
+
+
+def test_dynamic_template_resolve_non_dict_fallback():
+ """Verifies graceful fallback when a resolver returns a non-dict value."""
+ layout_yaml = """
+version: "0.1"
+name: NonDictLayout
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+parameters:
+ paramA: {type: string}
+layout:
+ component: Text
+ text: ${paramA}
+"""
+
+ def bad_resolver(paramA: str):
+ return "not a dict"
+
+ tmpl = DynamicTemplate(
+ name="NonDictLayout",
+ template_id="NonDictLayout",
+ catalogs=["https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"],
+ layout=layout_yaml,
+ resolver=bad_resolver,
+ )
+ processor = TemplateProcessor(templates=[tmpl], catalogs=BASIC_CATALOG)
+ expanded = processor.expand_template("root", "NonDictLayout", {"paramA": "safe"})
+ assert len(expanded) == 1
+ assert expanded[0]["text"] == "safe"
+
+
+def test_dynamic_template_loop_custom_as_variable():
+ """Verifies dynamic template expansion utilizing custom loop variable naming."""
+ layout_yaml = """
+version: "0.1"
+name: CustomAsList
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+parameters:
+ items: {type: array}
+layout:
+ component: Column
+ children:
+ loop:
+ param: items
+ as: item_var
+ item:
+ component: Text
+ text: ${item_var.label}
+"""
+ tmpl = StaticTemplate.from_yaml(layout_yaml)
+ processor = TemplateProcessor(templates=[tmpl], catalogs=BASIC_CATALOG)
+ expanded = processor.expand_template(
+ "root",
+ "CustomAsList",
+ {"items": [{"label": "First"}, {"label": "Second"}]},
+ )
+ texts = [c["text"] for c in expanded if c.get("component") == "Text"]
+ assert "First" in texts
+ assert "Second" in texts
+
+
+def test_template_processor_requires_catalogs():
+ """Verifies that TemplateProcessor requires explicit catalogs and rejects default assumptions."""
+ t = StaticTemplate(
+ name="StandaloneTemplate",
+ template_id="StandaloneTemplate",
+ catalogs=["https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"],
+ parameters={},
+ components=[],
+ )
+ with pytest.raises(ValueError, match="TemplateProcessor requires explicit catalog"):
+ TemplateProcessor(templates=[t])
+
+
+def test_template_processor_with_custom_domain_catalog():
+ """Verifies TemplateProcessor when initialized with a custom domain catalog."""
+ custom_catalog = {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://company.org/custom_medical_catalog.json",
+ "title": "Medical Component Catalog",
+ "components": {
+ "PatientChart": {"type": "object"},
+ "VitalsGauge": {"type": "object"},
+ },
+ "functions": {},
+ }
+
+ layout_yaml = """
+version: "0.1"
+name: MedicalReport
+catalogs:
+ - "https://company.org/custom_medical_catalog.json"
+parameters:
+ patientName: {type: string}
+layout:
+ component: PatientChart
+ properties:
+ name: ${patientName}
+"""
+ tmpl = StaticTemplate.from_yaml(layout_yaml)
+ processor = TemplateProcessor(templates=[tmpl], catalogs=custom_catalog)
+
+ assert (
+ processor.base_catalog_id == "https://company.org/custom_medical_catalog.json"
+ )
+
+ cat = processor.generate_inference_catalog()
+ assert "PatientChart" in cat["components"]
+ assert "VitalsGauge" in cat["components"]
+ assert "MedicalReport" in cat["components"]
+ assert "Card" not in cat["components"]
+ assert "Button" not in cat["components"]
+
+
+def test_multi_catalog_resolution_and_disambiguation():
+ """Verifies multi-catalog resolution, collision detection, and explicit catalogId disambiguation."""
+ catalog_a = {
+ "$id": "https://a2ui.org/cat_a.json",
+ "catalogId": "https://a2ui.org/cat_a.json",
+ "components": {
+ "SharedBox": {"type": "object"},
+ "CompA": {"type": "object"},
+ },
+ }
+ catalog_b = {
+ "$id": "https://a2ui.org/cat_b.json",
+ "catalogId": "https://a2ui.org/cat_b.json",
+ "components": {
+ "SharedBox": {"type": "object"},
+ "CompB": {"type": "object"},
+ },
+ }
+
+ # Case 1: Ambiguous component without disambiguation raises ValueError
+ ambiguous_yaml = """
+version: "0.1"
+name: AmbiguousTemplate
+catalogs:
+ - "https://a2ui.org/cat_a.json"
+ - "https://a2ui.org/cat_b.json"
+parameters: {}
+layout:
+ component: SharedBox
+"""
+ tmpl_ambiguous = StaticTemplate.from_yaml(ambiguous_yaml)
+ with pytest.raises(ValueError, match="ambiguous across multiple declared catalogs"):
+ TemplateProcessor(
+ templates=[tmpl_ambiguous],
+ catalogs=[catalog_a, catalog_b],
+ version="v1.0",
+ )
+
+ # Case 2: Disambiguated component with catalogId resolves successfully
+ disambiguated_yaml = """
+version: "0.1"
+name: DisambiguatedTemplate
+catalogs:
+ - "https://a2ui.org/cat_a.json"
+ - "https://a2ui.org/cat_b.json"
+parameters: {}
+layout:
+ component: SharedBox
+ catalogId: "https://a2ui.org/cat_b.json"
+"""
+ tmpl_ok = StaticTemplate.from_yaml(disambiguated_yaml)
+ proc = TemplateProcessor(
+ templates=[tmpl_ok],
+ catalogs=[catalog_a, catalog_b],
+ version="v1.0",
+ )
+ expanded = proc.expand_template("inst_1", "DisambiguatedTemplate", {})
+ assert len(expanded) == 1
+ assert expanded[0]["component"] == "SharedBox"
+ assert expanded[0]["catalogId"] == "https://a2ui.org/cat_b.json"
+
+
+def test_v09_rejects_multi_catalog_template():
+ """Verifies that A2UI v0.9 strictly rejects templates declaring multiple catalogs."""
+ catalog_a = {
+ "$id": "https://a2ui.org/cat_a.json",
+ "components": {"CompA": {}},
+ }
+ catalog_b = {
+ "$id": "https://a2ui.org/cat_b.json",
+ "components": {"CompB": {}},
+ }
+ multi_yaml = """
+version: "0.1"
+name: MultiCatTemplate
+catalogs:
+ - "https://a2ui.org/cat_a.json"
+ - "https://a2ui.org/cat_b.json"
+parameters: {}
+layout:
+ component: CompA
+"""
+ tmpl = StaticTemplate.from_yaml(multi_yaml)
+ with pytest.raises(ValueError, match="only supports a single catalog"):
+ TemplateProcessor(
+ templates=[tmpl],
+ catalogs=[catalog_a, catalog_b],
+ version="v0.9.1",
+ )
+
+
+def test_type_aliases_and_private_helpers():
+ """Verifies that semantic type aliases and backwards-compatible private functions are available."""
+ assert TemplateId is str
+ assert InstanceId is str
+ assert ComponentId is str
+ assert ParamPath is str
+
+ params: TemplateParams = {"user": {"profile": {"tier": "Pro"}}}
+ found, val = _resolve_param_path("user.profile.tier", params)
+ assert found is True
+ assert val == "Pro"
+
+ sub = _substitute_params("${user.profile.tier}", params)
+ assert sub == "Pro"
+
+ t = StaticTemplate(
+ name="Dummy",
+ template_id="Dummy",
+ catalogs=["https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"],
+ version="0.1",
+ parameters={},
+ components=[],
+ )
+ p = TemplateProcessor(templates=[t], catalogs=BASIC_CATALOG)
+ p._validate_templates()
+ p.validate_templates()
+
+
+def test_dynamic_template_decorator_processor_expansion():
+ """Verifies that @dynamic_template can be directly registered and expanded by TemplateProcessor."""
+
+ @dynamic_template(
+ catalogs=["https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"],
+ description="Renders a KPI metric display.",
+ )
+ def kpi_metric(label: str, value: str, change: str = "+0.0%"):
+ return {
+ "component": "Card",
+ "child": {
+ "component": "Column",
+ "children": [
+ {"component": "Text", "text": f"{label}: {value}"},
+ {"component": "Text", "text": f"Change: {change}"},
+ ],
+ },
+ }
+
+ processor = TemplateProcessor(templates=[kpi_metric], catalogs=BASIC_CATALOG)
+ expanded = processor.expand_template(
+ "inst_kpi",
+ "KpiMetric",
+ {"label": "Revenue", "value": "$1.2M", "change": "+12%"},
+ )
+ assert len(expanded) == 4
+ assert any(c.get("text") == "Revenue: $1.2M" for c in expanded)
+ assert any(c.get("text") == "Change: +12%" for c in expanded)
+
+
+def test_mustache_substitution_syntax():
+ """Verifies that double-curly Mustache syntax {{ param }} is supported for substitutions,
+ preserves exact types, allows whitespace, and leaves client ${/data/path} bindings intact.
+ """
+ layout_yaml = """
+version: "0.1"
+name: MustacheCard
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+parameters:
+ count: {type: integer}
+ isActive: {type: boolean}
+ user: {type: object}
+ tags: {type: array}
+ dept: {type: string}
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Text
+ text: "{{ count }}"
+ - component: Text
+ text: "{{ isActive }}"
+ - component: Text
+ text: "Hello, {{ user.profile.name }}! Dept: {{ dept }}"
+ - component: Text
+ text: "Literal: \\\\{{ escaped }}"
+ - component: Text
+ text:
+ call: formatString
+ args:
+ value: "Live: ${/metrics/cpu}, Dept: {{ dept }}"
+"""
+ tmpl = StaticTemplate.from_yaml(layout_yaml)
+ processor = TemplateProcessor(templates=[tmpl], catalogs=BASIC_CATALOG)
+ expanded = processor.expand_template(
+ "inst_1",
+ "MustacheCard",
+ {
+ "count": 42,
+ "isActive": True,
+ "user": {"profile": {"name": "Alice"}},
+ "tags": ["a", "b"],
+ "dept": "Engineering",
+ },
+ )
+
+ texts = [c for c in expanded if c.get("component") == "Text"]
+ # 1. Exact match integer type preserved
+ assert texts[0]["text"] == 42
+ # 2. Exact match boolean with whitespace preserved
+ assert texts[1]["text"] is True
+ # 3. Embedded interpolation with dot-notation
+ assert texts[2]["text"] == "Hello, Alice! Dept: Engineering"
+ # 4. Escaped literal unescaped
+ assert texts[3]["text"] == "Literal: {{ escaped }}"
+ # 5. Client data-model path ${/metrics/cpu} preserved untouched while {{ dept }} substituted
+ assert texts[4]["text"] == {
+ "call": "formatString",
+ "args": {"value": "Live: ${/metrics/cpu}, Dept: Engineering"},
+ }
diff --git a/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/test_template_conformance.py b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/test_template_conformance.py
new file mode 100644
index 0000000000..e489852806
--- /dev/null
+++ b/agent_sdks/python/a2ui_agent/tests/inference_formats/experimental/template/test_template_conformance.py
@@ -0,0 +1,174 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Conformance test runner for A2UI Templates executing declarative YAML suites."""
+
+import json
+from pathlib import Path
+from typing import Any, Dict, List, Tuple
+import jsonschema
+import pytest
+import yaml
+
+from a2ui.inference_formats.experimental.template import (
+ StaticTemplate,
+ TemplateProcessor,
+)
+from a2ui.inference_formats.experimental.template.processor import (
+ _substitute_params,
+)
+
+
+BASIC_CATALOG_PATH = (
+ Path(__file__).resolve().parents[7]
+ / "specification"
+ / "v0_9_1"
+ / "catalogs"
+ / "basic"
+ / "catalog.json"
+)
+BASIC_CATALOG: Dict[str, Any] = {}
+if BASIC_CATALOG_PATH.is_file():
+ with open(BASIC_CATALOG_PATH, "r", encoding="utf-8") as f:
+ BASIC_CATALOG = json.load(f)
+
+
+def get_conformance_dir() -> Path:
+ """Dynamically resolves the conformance directory regardless of nesting."""
+ curr = Path(__file__).resolve().parent
+ return curr / "conformance"
+
+
+def load_conformance_schema() -> Dict[str, Any]:
+ schema_path = get_conformance_dir() / "schema" / "template_conformance_schema.json"
+ with open(schema_path, "r", encoding="utf-8") as f:
+ return json.load(f)
+
+
+def load_all_conformance_cases() -> List[Tuple[str, str, Dict[str, Any]]]:
+ """Loads and validates all test cases across conformance suite YAML files."""
+ schema = load_conformance_schema()
+ cases: List[Tuple[str, str, Dict[str, Any]]] = []
+ suites_dir = get_conformance_dir() / "suites"
+
+ for yaml_path in sorted(suites_dir.glob("*.yaml")):
+ suite_name = yaml_path.name
+ with open(yaml_path, "r", encoding="utf-8") as f:
+ raw_cases = yaml.safe_load(f) or []
+
+ # Validate the suite file against conformance JSON Schema
+ jsonschema.validate(instance=raw_cases, schema=schema)
+
+ for case in raw_cases:
+ cases.append((suite_name, case["name"], case))
+
+ return cases
+
+
+CONFORMANCE_CASES = load_all_conformance_cases()
+
+
+def _execute_case(case: Dict[str, Any]) -> Any:
+ action = case["action"]
+
+ if action == "substitute_params":
+ val = case["args"]["value"]
+ params = case["args"]["params"]
+ return _substitute_params(val, params)
+
+ elif action == "expand_template":
+ templates: List[StaticTemplate] = []
+ if "template" in case:
+ templates.append(StaticTemplate.from_dict(case["template"]))
+ elif "templates" in case:
+ for t_dict in case["templates"]:
+ templates.append(StaticTemplate.from_dict(t_dict))
+
+ base_catalog = case.get("base_catalog", None)
+ catalogs = case.get("catalogs", None) or base_catalog
+ if catalogs is None and BASIC_CATALOG:
+ catalogs = [BASIC_CATALOG]
+ processor = TemplateProcessor(templates=templates, catalogs=catalogs)
+
+ template_id = case.get(
+ "template_id",
+ templates[0].template_id if templates else "Unknown",
+ )
+ instance_id = case.get("instance_id", "root")
+ args = case.get("args", {})
+
+ return processor.expand_template(
+ instance_id=instance_id,
+ template_id=template_id,
+ passed_params=args,
+ )
+
+ elif action == "process_message":
+ templates = []
+ if "template" in case:
+ templates.append(StaticTemplate.from_dict(case["template"]))
+ elif "templates" in case:
+ for t_dict in case["templates"]:
+ templates.append(StaticTemplate.from_dict(t_dict))
+
+ base_catalog = case.get("base_catalog", None)
+ catalogs = case.get("catalogs", None) or base_catalog
+ if catalogs is None and BASIC_CATALOG:
+ catalogs = [BASIC_CATALOG]
+ processor = TemplateProcessor(templates=templates, catalogs=catalogs)
+
+ return processor.process_message(case["message"])
+
+ elif action == "validate_template":
+ return StaticTemplate.from_dict(case["template"])
+
+ raise ValueError(f"Unknown conformance test action: '{action}'")
+
+
+@pytest.mark.parametrize("suite_name,case_name,case", CONFORMANCE_CASES)
+def test_template_conformance(
+ suite_name: str, case_name: str, case: Dict[str, Any]
+) -> None:
+ """Executes a single declarative conformance test case."""
+ if "expect_error" in case:
+ expected_msg = case["expect_error"].get("message", "")
+ with pytest.raises(Exception) as excinfo:
+ _execute_case(case)
+ if expected_msg:
+ assert expected_msg.lower() in str(excinfo.value).lower(), (
+ f"[{suite_name}::{case_name}] Expected error containing"
+ f" '{expected_msg}', got: {str(excinfo.value)}"
+ )
+ else:
+ actual = _execute_case(case)
+ expected = case["expect"]
+ if (
+ isinstance(actual, list)
+ and isinstance(expected, list)
+ and all(isinstance(x, dict) and "id" in x for x in actual)
+ and all(isinstance(x, dict) and "id" in x for x in expected)
+ ):
+ actual_sorted = sorted(actual, key=lambda x: str(x["id"]))
+ expected_sorted = sorted(expected, key=lambda x: str(x["id"]))
+ assert actual_sorted == expected_sorted, (
+ f"[{suite_name}::{case_name}] Result mismatch:\n"
+ f"Expected: {expected_sorted}\n"
+ f"Actual: {actual_sorted}"
+ )
+ else:
+ assert actual == expected, (
+ f"[{suite_name}::{case_name}] Result mismatch:\n"
+ f"Expected: {expected}\n"
+ f"Actual: {actual}"
+ )
diff --git a/samples/community/package.json b/samples/community/package.json
index 8664559263..f71174a455 100644
--- a/samples/community/package.json
+++ b/samples/community/package.json
@@ -11,7 +11,8 @@
"mcp/*",
"mcp/*/client",
"mcp/*/apps/src",
- "mcp/a2ui-in-mcpapps/server/apps/*"
+ "mcp/a2ui-in-mcpapps/server/apps/*",
+ "templates/client"
],
"scripts": {
"build:web": "yarn workspace angular-a2ui run build && yarn workspace @a2ui/mcp-apps-in-a2ui-sample run build && yarn workspace personalized-learning-demo run build && yarn workspace a2ui-in-mcpapps-client run build && yarn workspace a2ui-in-mcpapps-client run build:sandbox && yarn workspace basic-mcp-app-angular run build:all && yarn workspace basic-mcp-app-angular-editor run build:all && yarn workspace a2ui-over-mcp-recipe-client run build && yarn workspace mcp-calculator-app run build"
diff --git a/samples/community/templates/README.md b/samples/community/templates/README.md
new file mode 100644
index 0000000000..a05f8146b0
--- /dev/null
+++ b/samples/community/templates/README.md
@@ -0,0 +1,50 @@
+# A2UI templates community demo
+
+This sample demonstrates server-side template expansion in the A2UI Python Agent SDK using the standard Basic Catalog and React client renderer.
+
+---
+
+## Overview
+
+- **Static declarative templates**: Parameterized layout subtrees (such as `UserProfile`, `TeamCard`, `TeamRoster`, `TeamGoalList`, `TeamFeedbackBoard`) defined in JSON and expanded into Basic Catalog primitives (`Card`, `Column`, `Row`, `Text`, `Divider`, `Icon`, `Button`).
+- **Dynamic server resolvers**: Programmatic templates (such as `EmployeeSalaryCard`) that run Python resolver callbacks to query internal databases. The model only receives and passes identifiers, while sensitive numbers are injected server-side.
+- **Express DSL & synchronous expansion**: The language model outputs concise Express DSL. The backend parser expands templates synchronously without requiring custom client components.
+- **Interactive studio & library**: The React client includes an Interactive Chat with suggested prompt chips and latency/token metrics, alongside a 3-Stage Dynamic Template Studio showing input arguments, underlying blueprint JSON, and live rendered output.
+
+---
+
+## Running the demo
+
+### 1. Start the backend server
+
+```bash
+cd samples/community/templates
+uv run uvicorn server:app --reload --port 8000
+```
+
+To test live Gemini generation in addition to the preset templates, set your API key and optional model:
+
+```bash
+export GEMINI_API_KEY="your-api-key"
+export GEMINI_MODEL="gemini-flash-latest" # Optional, defaults to gemini-flash-latest
+```
+
+### 2. Start the frontend client
+
+```bash
+cd samples/community/templates/client
+yarn install
+yarn dev
+```
+
+Open [http://localhost:5173](http://localhost:5173) in your browser.
+
+---
+
+## Testing
+
+Run the Playwright end-to-end integration test suite:
+
+```bash
+node samples/community/templates/test_e2e.mjs
+```
diff --git a/samples/community/templates/client/.prettierignore b/samples/community/templates/client/.prettierignore
new file mode 100644
index 0000000000..5e71162a6b
--- /dev/null
+++ b/samples/community/templates/client/.prettierignore
@@ -0,0 +1,2 @@
+dist/
+.wireit/
diff --git a/samples/community/templates/client/eslint.config.mjs b/samples/community/templates/client/eslint.config.mjs
new file mode 100644
index 0000000000..ba401290a5
--- /dev/null
+++ b/samples/community/templates/client/eslint.config.mjs
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import tseslint from 'typescript-eslint';
+import reactPlugin from 'eslint-plugin-react';
+import reactHooksPlugin from 'eslint-plugin-react-hooks';
+
+export default tseslint.config(
+ {
+ ignores: ['dist/**', 'vite.config.*', '**/node_modules/**', '**/.yarn/**'],
+ },
+ {
+ files: ['src/**/*.{ts,tsx}'],
+ extends: [tseslint.configs.recommended],
+ plugins: {
+ react: reactPlugin,
+ 'react-hooks': reactHooksPlugin,
+ },
+ rules: {
+ 'react/react-in-jsx-scope': 'off',
+ '@typescript-eslint/no-explicit-any': 'off',
+ },
+ },
+);
diff --git a/samples/community/templates/client/index.html b/samples/community/templates/client/index.html
new file mode 100644
index 0000000000..3570cc797f
--- /dev/null
+++ b/samples/community/templates/client/index.html
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+ A2UI Templates - Community Demo
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/community/templates/client/package.json b/samples/community/templates/client/package.json
new file mode 100644
index 0000000000..691df47443
--- /dev/null
+++ b/samples/community/templates/client/package.json
@@ -0,0 +1,51 @@
+{
+ "name": "@a2ui/templates-community-demo",
+ "private": true,
+ "version": "0.1.0",
+ "description": "A2UI Templates Community Demo Client",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "wireit",
+ "preview": "vite preview",
+ "lint": "eslint .",
+ "lint:fix": "eslint . --fix",
+ "format": "prettier --write .",
+ "format:check": "prettier --check .",
+ "test": "node -e 'console.log(\"Workspace has no tests.\");'"
+ },
+ "dependencies": {
+ "@a2ui/react": "^0.10.2",
+ "@a2ui/web_core": "^0.10.6",
+ "react": "^19.2.7",
+ "react-dom": "^19.2.7"
+ },
+ "devDependencies": {
+ "@types/node": "^25.9.3",
+ "@types/react": "^19.2.17",
+ "@types/react-dom": "^19.2.3",
+ "@vitejs/plugin-react": "^6.0.2",
+ "eslint": "^10.4.1",
+ "eslint-config-prettier": "^10.1.8",
+ "eslint-plugin-react": "^7.37.5",
+ "eslint-plugin-react-hooks": "^7.1.1",
+ "typescript": "5.9.3",
+ "typescript-eslint": "^8.61.0",
+ "vite": "^8.0.16",
+ "wireit": "^0.15.0-pre.2"
+ },
+ "wireit": {
+ "build": {
+ "command": "tsc -b && vite build",
+ "files": [
+ "src/**/*",
+ "index.html",
+ "tsconfig.json",
+ "vite.config.*"
+ ],
+ "output": [
+ "dist/"
+ ]
+ }
+ }
+}
diff --git a/samples/community/templates/client/src/App.tsx b/samples/community/templates/client/src/App.tsx
new file mode 100644
index 0000000000..e82f584c98
--- /dev/null
+++ b/samples/community/templates/client/src/App.tsx
@@ -0,0 +1,2027 @@
+/*
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React, {useState, useEffect, useRef} from 'react';
+import {MessageProcessor} from '@a2ui/web_core/v0_9';
+import {A2uiSurface, basicCatalog} from '@a2ui/react/v0_9';
+
+interface FeedItem {
+ id: string;
+ type: 'user' | 'assistant';
+ text?: string;
+ surfaceId?: string;
+ raw?: string;
+ messages?: any[];
+ metrics?: {
+ latency?: number;
+ thinkingTokens?: number;
+ outputTokens?: number;
+ promptTokens?: number;
+ totalTokens?: number;
+ isPreset?: boolean;
+ };
+}
+
+interface TemplateDefinition {
+ version?: string;
+ templateId: string;
+ parameters: Record;
+ components?: any[];
+ layout?: Record;
+ yamlContent?: string;
+ description?: string;
+ sampleData?: Record;
+ sampleMessages?: any[];
+ isDynamic?: boolean;
+ isProgrammatic?: boolean;
+ isDataBinding?: boolean;
+ renderSource?: string;
+ layoutTemplate?: Record;
+ layoutTemplateYaml?: string;
+ resolvedData?: Record;
+ availablePresets?: Array<{label: string; value: string}>;
+}
+
+const A2UI_THEME_VARS: React.CSSProperties = {
+ // Card & Container
+ ['--a2ui-card-border-radius' as any]: '16px',
+ ['--a2ui-card-background' as any]: '#ffffff',
+ ['--a2ui-card-border' as any]: '1px solid #e2e8f0',
+ ['--a2ui-card-box-shadow' as any]:
+ '0 4px 12px -2px rgba(15, 23, 42, 0.06), 0 2px 6px -1px rgba(15, 23, 42, 0.03)',
+ ['--a2ui-card-padding' as any]: '18px 22px',
+ ['--a2ui-card-margin' as any]: '8px 0',
+
+ // Primitives & General
+ ['--a2ui-border-radius' as any]: '12px',
+ ['--a2ui-color-border' as any]: '#e2e8f0',
+ ['--a2ui-color-surface' as any]: '#ffffff',
+ ['--a2ui-color-on-surface' as any]: '#0f172a',
+
+ // Primary Action & Button
+ ['--a2ui-color-primary' as any]: '#2563eb',
+ ['--a2ui-color-primary-hover' as any]: '#1d4ed8',
+ ['--a2ui-color-on-primary' as any]: '#ffffff',
+ ['--a2ui-button-border-radius' as any]: '10px',
+ ['--a2ui-button-background' as any]: '#2563eb',
+ ['--a2ui-button-padding' as any]: '8px 18px',
+ ['--a2ui-button-font-weight' as any]: '600',
+ ['--a2ui-button-box-shadow' as any]: '0 1px 2px rgba(37, 99, 235, 0.2)',
+
+ // Spacing & Icons
+ ['--a2ui-spacing-s' as any]: '6px',
+ ['--a2ui-spacing-m' as any]: '12px',
+ ['--a2ui-spacing-l' as any]: '20px',
+ ['--a2ui-icon-size' as any]: '22px',
+ ['--a2ui-icon-color' as any]: '#2563eb',
+
+ // Typography & Dividers
+ ['--a2ui-divider-color' as any]: '#f1f5f9',
+ ['--a2ui-text-caption-color' as any]: '#64748b',
+};
+
+export default function App() {
+ const [currentView, setCurrentView] = useState<'chat' | 'library'>('chat');
+
+ // Chat State
+ const [chatProcessor] = useState(() => new MessageProcessor([basicCatalog]));
+ const [, setChatTick] = useState(0);
+ const [feed, setFeed] = useState([]);
+ const [input, setInput] = useState('');
+ const [loading, setLoading] = useState(false);
+ const [activeInspector, setActiveInspector] = useState(null);
+ const [inspectorTab, setInspectorTab] = useState<'express' | 'json'>('express');
+ const [copiedTurn, setCopiedTurn] = useState(false);
+ const chatBottomRef = useRef(null);
+
+ // Library State
+ const [libraryProcessor] = useState(() => new MessageProcessor([basicCatalog]));
+ const [, setLibraryTick] = useState(0);
+ const [templates, setTemplates] = useState([]);
+ const [selectedTemplateId, setSelectedTemplateId] = useState('UserProfile');
+ const [libraryLoading, setLibraryLoading] = useState(false);
+ const [copiedTemplate, setCopiedTemplate] = useState(false);
+
+ // Dynamic Template Interactive State
+ const [selectedDynamicEmpId, setSelectedDynamicEmpId] = useState('emp_101');
+ const [payrollDept, setPayrollDept] = useState('Global Engineering');
+ const [payrollIncludeBonus, setPayrollIncludeBonus] = useState(true);
+ const [dynamicResolvedData, setDynamicResolvedData] = useState | null>(null);
+ const [dynamicTab, setDynamicTab] = useState<'input' | 'layout' | 'resolved'>('input');
+ const [dynamicResolving, setDynamicResolving] = useState(false);
+
+ // Subscriptions
+ useEffect(() => {
+ const forceUpdate = () => setChatTick(t => t + 1);
+ const subCreated = chatProcessor.onSurfaceCreated(forceUpdate);
+ const subDeleted = chatProcessor.onSurfaceDeleted(forceUpdate);
+ return () => {
+ subCreated.unsubscribe();
+ subDeleted.unsubscribe();
+ };
+ }, [chatProcessor]);
+
+ useEffect(() => {
+ const forceUpdate = () => setLibraryTick(t => t + 1);
+ const subCreated = libraryProcessor.onSurfaceCreated(forceUpdate);
+ const subDeleted = libraryProcessor.onSurfaceDeleted(forceUpdate);
+ return () => {
+ subCreated.unsubscribe();
+ subDeleted.unsubscribe();
+ };
+ }, [libraryProcessor]);
+
+ useEffect(() => {
+ if (currentView === 'chat') {
+ chatBottomRef.current?.scrollIntoView({behavior: 'smooth'});
+ }
+ }, [feed, loading, currentView]);
+
+ useEffect(() => {
+ const fetchTemplates = async () => {
+ setLibraryLoading(true);
+ try {
+ const res = await fetch('http://127.0.0.1:8000/templates');
+ if (res.ok) {
+ const list: TemplateDefinition[] = await res.json();
+ setTemplates(list);
+ if (list.length > 0) {
+ setSelectedTemplateId(prev =>
+ list.find(t => t.templateId === prev) ? prev : list[0].templateId,
+ );
+ for (const item of list) {
+ if (item.sampleMessages && item.sampleMessages.length > 0) {
+ libraryProcessor.processMessages(item.sampleMessages);
+ if (item.isDynamic) {
+ const empId = item.sampleData?.employeeId || 'emp_101';
+ const dynamicSurfaceId = `preview_${item.templateId}_${empId}`;
+ const dynamicMsgs = item.sampleMessages.map((m: any) => {
+ if (m.createSurface) {
+ return {
+ ...m,
+ createSurface: {
+ ...m.createSurface,
+ surfaceId: dynamicSurfaceId,
+ },
+ };
+ }
+ if (m.updateComponents) {
+ return {
+ ...m,
+ updateComponents: {
+ ...m.updateComponents,
+ surfaceId: dynamicSurfaceId,
+ },
+ };
+ }
+ return m;
+ });
+ libraryProcessor.processMessages(dynamicMsgs);
+ }
+ }
+ }
+ }
+ }
+ } catch (e) {
+ console.error('Failed to load templates list:', e);
+ } finally {
+ setLibraryLoading(false);
+ }
+ };
+ if (currentView === 'library' || templates.length === 0) {
+ fetchTemplates();
+ }
+ }, [libraryProcessor, currentView]);
+
+ const selectedTemplate = templates.find(t => t.templateId === selectedTemplateId);
+
+ // When dynamic template selection changes, sync initial state
+ useEffect(() => {
+ if (selectedTemplate?.isDynamic) {
+ if (selectedTemplate.resolvedData) {
+ setDynamicResolvedData(selectedTemplate.resolvedData);
+ }
+ if (selectedTemplate.sampleData?.employeeId) {
+ setSelectedDynamicEmpId(selectedTemplate.sampleData.employeeId);
+ }
+ if (selectedTemplate.sampleData?.department) {
+ setPayrollDept(selectedTemplate.sampleData.department);
+ }
+ if (selectedTemplate.sampleData?.includeBonus !== undefined) {
+ setPayrollIncludeBonus(selectedTemplate.sampleData.includeBonus);
+ }
+ }
+ }, [selectedTemplate]);
+
+ const handleResolveDynamicTemplate = async (paramInput?: any) => {
+ if (!selectedTemplate) return;
+ setDynamicResolving(true);
+ let sendParams: Record = {};
+ let surfaceSuffix = 'default';
+
+ if (selectedTemplate.templateId === 'PayrollSummary') {
+ const dept =
+ typeof paramInput === 'object' && paramInput.department !== undefined
+ ? paramInput.department
+ : payrollDept;
+ const bonus =
+ typeof paramInput === 'object' && paramInput.includeBonus !== undefined
+ ? paramInput.includeBonus
+ : payrollIncludeBonus;
+ sendParams = {department: dept, includeBonus: bonus};
+ surfaceSuffix = `${dept.replace(/\s+/g, '_')}_${bonus}`;
+ } else {
+ const empId = typeof paramInput === 'string' ? paramInput : selectedDynamicEmpId;
+ setSelectedDynamicEmpId(empId);
+ sendParams = {employeeId: empId};
+ surfaceSuffix = empId;
+ }
+
+ try {
+ const res = await fetch(
+ `http://127.0.0.1:8000/templates/${selectedTemplate.templateId}/resolve`,
+ {
+ method: 'POST',
+ headers: {'Content-Type': 'application/json'},
+ body: JSON.stringify({params: sendParams}),
+ },
+ );
+ if (!res.ok) {
+ throw new Error(`Server returned status ${res.status}`);
+ }
+ const data = await res.json();
+ setDynamicResolvedData(data.resolvedData);
+ if (data.sampleMessages) {
+ const dynamicSurfaceId = `preview_${selectedTemplate.templateId}_${surfaceSuffix}`;
+ const updatedMessages = data.sampleMessages.map((m: any) => {
+ if (m.createSurface) {
+ return {
+ ...m,
+ createSurface: {
+ ...m.createSurface,
+ surfaceId: dynamicSurfaceId,
+ },
+ };
+ }
+ if (m.updateComponents) {
+ return {
+ ...m,
+ updateComponents: {
+ ...m.updateComponents,
+ surfaceId: dynamicSurfaceId,
+ },
+ };
+ }
+ return m;
+ });
+ libraryProcessor.processMessages(updatedMessages);
+ setLibraryTick(t => t + 1);
+ }
+ } catch (err) {
+ console.error('Failed to resolve dynamic template:', err);
+ } finally {
+ setDynamicResolving(false);
+ }
+ };
+
+ const copyToClipboard = (text: string, isTemplate = false) => {
+ navigator.clipboard.writeText(text);
+ if (isTemplate) {
+ setCopiedTemplate(true);
+ setTimeout(() => setCopiedTemplate(false), 2000);
+ } else {
+ setCopiedTurn(true);
+ setTimeout(() => setCopiedTurn(false), 2000);
+ }
+ };
+
+ const sendPrompt = async (promptText: string) => {
+ const text = promptText.trim();
+ if (!text || loading) return;
+
+ setInput('');
+ const surfaceId = `surface_${Date.now()}`;
+ setFeed(prev => [...prev, {id: `user_${Date.now()}`, type: 'user', text}]);
+ setLoading(true);
+
+ try {
+ const res = await fetch('http://127.0.0.1:8000/interact', {
+ method: 'POST',
+ headers: {'Content-Type': 'application/json'},
+ body: JSON.stringify({
+ prompt: text,
+ surfaceId,
+ }),
+ });
+
+ if (!res.ok) {
+ throw new Error(`Server returned status ${res.status}`);
+ }
+
+ const data = await res.json();
+ if (data.messages && data.messages.length > 0) {
+ chatProcessor.processMessages(data.messages);
+ }
+
+ let actualSurfaceId = data.surfaceId || surfaceId;
+ if (data.messages && data.messages.length > 0) {
+ const found =
+ data.messages.find((m: any) => m.createSurface?.surfaceId)?.createSurface?.surfaceId ||
+ data.messages.find((m: any) => m.updateComponents?.surfaceId)?.updateComponents
+ ?.surfaceId;
+ if (found) {
+ actualSurfaceId = found;
+ }
+ }
+
+ setFeed(prev => [
+ ...prev,
+ {
+ id: `assistant_${Date.now()}`,
+ type: 'assistant',
+ text: data.text,
+ surfaceId: actualSurfaceId,
+ raw: data.raw,
+ messages: data.messages,
+ metrics: data.metrics,
+ },
+ ]);
+ } catch (err: any) {
+ setFeed(prev => [
+ ...prev,
+ {
+ id: `assistant_${Date.now()}`,
+ type: 'assistant',
+ text: `Error contacting server: ${err.message}. Make sure the FastAPI server is running on http://127.0.0.1:8000.`,
+ surfaceId,
+ },
+ ]);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ return (
+
+ {/* Top Header */}
+
+
+
+
+ dashboard_customize
+
+
+
+
+ A2UI Templates
+
+
+ Static & Dynamic Server Expansion · Basic Catalog
+
+
+
+
+ {/* View Switcher Tabs */}
+
+ setCurrentView('chat')}
+ style={{
+ display: 'flex',
+ alignItems: 'center',
+ gap: '6px',
+ padding: '6px 14px',
+ borderRadius: '8px',
+ border: 'none',
+ backgroundColor: currentView === 'chat' ? '#ffffff' : 'transparent',
+ color: currentView === 'chat' ? '#2563eb' : '#64748b',
+ fontWeight: 600,
+ fontSize: '13px',
+ cursor: 'pointer',
+ boxShadow: currentView === 'chat' ? '0 1px 3px rgba(0, 0, 0, 0.08)' : 'none',
+ transition: 'all 0.15s ease',
+ }}
+ >
+
+ chat
+
+ Interactive Chat
+
+ setCurrentView('library')}
+ style={{
+ display: 'flex',
+ alignItems: 'center',
+ gap: '6px',
+ padding: '6px 14px',
+ borderRadius: '8px',
+ border: 'none',
+ backgroundColor: currentView === 'library' ? '#ffffff' : 'transparent',
+ color: currentView === 'library' ? '#2563eb' : '#64748b',
+ fontWeight: 600,
+ fontSize: '13px',
+ cursor: 'pointer',
+ boxShadow: currentView === 'library' ? '0 1px 3px rgba(0, 0, 0, 0.08)' : 'none',
+ transition: 'all 0.15s ease',
+ }}
+ >
+
+ menu_book
+
+ Template Library
+
+
+
+
+ {/* Main Content View */}
+ {currentView === 'chat' ? (
+
+ {/* Presets Sidebar */}
+
+
+
+ Example Presets
+
+
+ {[
+ {
+ label: '🔒 Verified Salary',
+ prompt: 'show verified salary',
+ desc: 'Dynamic server-resolved compensation',
+ },
+ {
+ label: '💰 Payroll Summary',
+ prompt: 'show payroll summary',
+ desc: 'Programmatic dynamic template table',
+ },
+ {
+ label: '📊 User Evaluation',
+ prompt: 'show user evaluation',
+ desc: 'Composite review & goals dashboard',
+ },
+ {
+ label: '👤 User Profile',
+ prompt: 'show user profile',
+ desc: 'Single card profile',
+ },
+ {
+ label: '👥 Team Roster',
+ prompt: 'show team roster',
+ desc: 'Nested team member cards',
+ },
+ {
+ label: '🎯 Team Goals',
+ prompt: 'show team goals',
+ desc: 'Unrolled objectives list',
+ },
+ {
+ label: '💬 Feedback Board',
+ prompt: 'show feedback board',
+ desc: 'Review cards with ratings',
+ },
+ {
+ label: '⭐ Competency Panel',
+ prompt: 'show competency panel',
+ desc: 'Metrics & stats summary',
+ },
+ ].map(btn => (
+ sendPrompt(btn.prompt)}
+ disabled={loading}
+ style={{
+ textAlign: 'left',
+ padding: '12px 14px',
+ borderRadius: '12px',
+ border: '1px solid #e2e8f0',
+ backgroundColor: '#f8fafc',
+ color: '#1e293b',
+ fontSize: '13px',
+ fontWeight: 600,
+ cursor: loading ? 'not-allowed' : 'pointer',
+ transition: 'all 0.15s ease',
+ display: 'flex',
+ flexDirection: 'column',
+ gap: '2px',
+ }}
+ >
+ {btn.label}
+
+ {btn.desc}
+
+
+ ))}
+
+
+
+
+ Template Inference Format
+
+ Click the ℹ️ Inspect button
+ on any turn to view the raw LLM Express DSL and expanded JSON.
+
+
+
+ {/* Chat Feed */}
+
+
+ {feed.length === 0 && (
+
+
+
+ auto_awesome
+
+
+
+ A2UI Templates Explorer
+
+
+ Click a preset or select a suggested prompt below to observe static and dynamic
+ templates expanded server-side into standard A2UI primitives.
+
+
+
+
+ Suggested Prompts
+
+
+ {[
+ {
+ icon: 'lock',
+ text: 'Show verified salary for Marcus Vance',
+ badge: 'Dynamic',
+ },
+ {
+ icon: 'person',
+ text: 'Show user profile for Alice Smith',
+ badge: 'Template',
+ },
+ {
+ icon: 'flag',
+ text: 'Show team goals for Core Protocol Engineering',
+ badge: 'Template',
+ },
+ {
+ icon: 'reviews',
+ text: 'Show feedback board for Frontend Guild',
+ badge: 'Template',
+ },
+ {
+ icon: 'groups',
+ text: 'Show team roster with Core Architecture',
+ badge: 'Template',
+ },
+ {
+ icon: 'monitoring',
+ text: 'Show user evaluation for Alice Smith',
+ badge: 'Composite',
+ },
+ ].map(chip => (
+ sendPrompt(chip.text)}
+ disabled={loading}
+ style={{
+ display: 'flex',
+ alignItems: 'center',
+ gap: '10px',
+ padding: '10px 14px',
+ backgroundColor: '#f8fafc',
+ border: '1px solid #e2e8f0',
+ borderRadius: '12px',
+ color: '#1e293b',
+ fontSize: '12px',
+ fontWeight: 500,
+ cursor: 'pointer',
+ textAlign: 'left',
+ transition: 'all 0.15s ease',
+ }}
+ onMouseEnter={e => {
+ e.currentTarget.style.backgroundColor = '#eff6ff';
+ e.currentTarget.style.borderColor = '#93c5fd';
+ e.currentTarget.style.color = '#1d4ed8';
+ }}
+ onMouseLeave={e => {
+ e.currentTarget.style.backgroundColor = '#f8fafc';
+ e.currentTarget.style.borderColor = '#e2e8f0';
+ e.currentTarget.style.color = '#1e293b';
+ }}
+ >
+
+ {chip.icon}
+
+ {chip.text}
+
+ ))}
+
+
+
+ )}
+
+ {feed.map(item => {
+ const targetSurfaceId =
+ item.surfaceId ||
+ item.messages?.find((m: any) => m.createSurface?.surfaceId)?.createSurface
+ ?.surfaceId ||
+ item.messages?.find((m: any) => m.updateComponents?.surfaceId)?.updateComponents
+ ?.surfaceId;
+ const surface = targetSurfaceId
+ ? chatProcessor.model.getSurface(targetSurfaceId)
+ : undefined;
+ const isInspectorOpen = activeInspector === item.id;
+ const hasInspectionData = Boolean(
+ item.raw || (item.messages && item.messages.length > 0),
+ );
+
+ return (
+
+ {item.type === 'user' ? (
+
+ {item.text}
+
+ ) : (
+
+
+ {item.text && (
+
+ {item.text}
+
+ )}
+
+
+ {item.metrics && (
+
+
+ ⏱️
+ {item.metrics.latency}s
+
+
+ {item.metrics.thinkingTokens !== undefined &&
+ item.metrics.thinkingTokens > 0 && (
+ <>
+ •
+
+ 🧠
+ {item.metrics.thinkingTokens} think
+
+ >
+ )}
+
+ {item.metrics.outputTokens !== undefined &&
+ item.metrics.outputTokens > 0 && (
+ <>
+ •
+
+ 📝
+ {item.metrics.outputTokens} out
+
+ >
+ )}
+
+ )}
+
+ {hasInspectionData && (
+
+ setActiveInspector(curr => (curr === item.id ? null : item.id))
+ }
+ title="Inspect raw LLM Express DSL and expanded A2UI JSON"
+ style={{
+ display: 'inline-flex',
+ alignItems: 'center',
+ gap: '6px',
+ padding: '6px 12px',
+ borderRadius: '20px',
+ border: '1px solid #e2e8f0',
+ backgroundColor: isInspectorOpen ? '#eff6ff' : '#ffffff',
+ borderColor: isInspectorOpen ? '#93c5fd' : '#e2e8f0',
+ color: isInspectorOpen ? '#1d4ed8' : '#64748b',
+ fontSize: '12px',
+ fontWeight: 600,
+ cursor: 'pointer',
+ transition: 'all 0.15s ease',
+ boxShadow: '0 1px 2px rgba(0, 0, 0, 0.03)',
+ }}
+ >
+
+ data_object
+
+ {isInspectorOpen ? 'Hide Payload' : 'Inspect Format'}
+
+ )}
+
+
+
+ {/* Inspector Drawer */}
+ {isInspectorOpen && (
+
+
+
+ setInspectorTab('express')}
+ style={{
+ padding: '6px 12px',
+ borderRadius: '8px',
+ border: 'none',
+ backgroundColor:
+ inspectorTab === 'express' ? '#334155' : 'transparent',
+ color: inspectorTab === 'express' ? '#38bdf8' : '#94a3b8',
+ fontSize: '12px',
+ fontWeight: 600,
+ cursor: 'pointer',
+ }}
+ >
+ ⚡ Raw Express DSL
+
+ setInspectorTab('json')}
+ style={{
+ padding: '6px 12px',
+ borderRadius: '8px',
+ border: 'none',
+ backgroundColor:
+ inspectorTab === 'json' ? '#334155' : 'transparent',
+ color: inspectorTab === 'json' ? '#38bdf8' : '#94a3b8',
+ fontSize: '12px',
+ fontWeight: 600,
+ cursor: 'pointer',
+ }}
+ >
+ 📦 Expanded A2UI JSON
+
+
+
+
{
+ const textToCopy =
+ inspectorTab === 'express'
+ ? item.raw || ''
+ : JSON.stringify(item.messages || [], null, 2);
+ copyToClipboard(textToCopy);
+ }}
+ style={{
+ display: 'inline-flex',
+ alignItems: 'center',
+ gap: '4px',
+ padding: '4px 8px',
+ borderRadius: '6px',
+ border: '1px solid #475569',
+ backgroundColor: '#334155',
+ color: '#cbd5e1',
+ fontSize: '11px',
+ cursor: 'pointer',
+ }}
+ >
+
+ {copiedTurn ? 'check' : 'content_copy'}
+
+ {copiedTurn ? 'Copied!' : 'Copy'}
+
+
+
+
+ {inspectorTab === 'express' ? (
+
+ {item.raw || '// No raw Express DSL received'}
+
+ ) : (
+
+ {JSON.stringify(item.messages || [], null, 2)}
+
+ )}
+
+
+ )}
+
+ {/* Rendered A2UI Surface */}
+ {surface ? (
+
+ ) : null}
+
+ )}
+
+ );
+ })}
+
+ {loading && (
+
+
+ progress_activity
+
+ Expanding template...
+
+ )}
+
+
+
+ {/* Input Bar */}
+
+ setInput(e.target.value)}
+ onKeyDown={e => e.key === 'Enter' && sendPrompt(input)}
+ placeholder="Type a template prompt (e.g. 'Show verified salary' or 'Show user profile')..."
+ disabled={loading}
+ style={{
+ flex: 1,
+ padding: '14px 18px',
+ borderRadius: '12px',
+ border: '1px solid #cbd5e1',
+ fontSize: '14px',
+ outline: 'none',
+ transition: 'border-color 0.15s ease',
+ }}
+ onFocus={e => (e.target.style.borderColor = '#2563eb')}
+ onBlur={e => (e.target.style.borderColor = '#cbd5e1')}
+ />
+ sendPrompt(input)}
+ disabled={loading || !input.trim()}
+ style={{
+ padding: '0 24px',
+ backgroundColor: '#2563eb',
+ color: '#ffffff',
+ border: 'none',
+ borderRadius: '12px',
+ fontSize: '14px',
+ fontWeight: 600,
+ cursor: loading || !input.trim() ? 'not-allowed' : 'pointer',
+ opacity: loading || !input.trim() ? 0.6 : 1,
+ boxShadow: '0 2px 4px rgba(37, 99, 235, 0.2)',
+ transition: 'all 0.15s ease',
+ }}
+ >
+ Send
+
+
+
+
+ ) : (
+ /* Template Library View */
+
+ {/* Library Sidebar List */}
+
+
+
+ Registered Templates
+
+
+ Inspect static declarative templates and dynamic server resolvers.
+
+
+
+ {templates.map(tmpl => {
+ const isSelected = tmpl.templateId === selectedTemplateId;
+ const paramCount = Object.keys(tmpl.parameters || {}).length;
+ const compCount = (tmpl.components || []).length;
+
+ return (
+
setSelectedTemplateId(tmpl.templateId)}
+ style={{
+ textAlign: 'left',
+ padding: '12px 14px',
+ borderRadius: '12px',
+ border: isSelected ? '1px solid #93c5fd' : '1px solid #e2e8f0',
+ backgroundColor: isSelected ? '#eff6ff' : '#ffffff',
+ cursor: 'pointer',
+ transition: 'all 0.15s ease',
+ display: 'flex',
+ flexDirection: 'column',
+ gap: '4px',
+ }}
+ >
+
+
+ {tmpl.templateId}
+
+ {tmpl.isDynamic ? (
+
+ ⚡ Dynamic
+
+ ) : (
+
+ {paramCount} params
+
+ )}
+
+
+ {tmpl.isDynamic
+ ? 'Server database resolver callback'
+ : `${compCount} primitive components`}
+
+
+ );
+ })}
+
+
+ {/* Studio Content */}
+ {selectedTemplate ? (
+ selectedTemplate.isDynamic ? (
+ /* Dynamic Template 3-Stage Inspector Studio */
+
+ {/* Header Banner */}
+
+
+
+
+ {selectedTemplate.templateId}
+
+
+ ⚡ Dynamic Server Resolver
+
+
+
+ {selectedTemplate.description}
+
+
+
+ {/* Stage Switcher */}
+
+ {[
+ {id: 'input', label: '1. Input Interface'},
+ {
+ id: 'layout',
+ label: selectedTemplate.isProgrammatic
+ ? '2. Python AST Generator'
+ : '2. Static Blueprint',
+ },
+ {id: 'resolved', label: '3. Resolved Output'},
+ ].map(tab => (
+ setDynamicTab(tab.id as any)}
+ style={{
+ padding: '6px 14px',
+ borderRadius: '8px',
+ border: 'none',
+ backgroundColor: dynamicTab === tab.id ? '#ffffff' : 'transparent',
+ color: dynamicTab === tab.id ? '#2563eb' : '#64748b',
+ fontWeight: 600,
+ fontSize: '12px',
+ cursor: 'pointer',
+ boxShadow:
+ dynamicTab === tab.id ? '0 1px 3px rgba(0, 0, 0, 0.08)' : 'none',
+ }}
+ >
+ {tab.label}
+
+ ))}
+
+
+
+ {/* 3-Stage Body */}
+
+ {/* Left Column: Interactive Stages */}
+
+ {dynamicTab === 'input' && (
+
+
+
+ Step 1: Simple LLM Input Interface
+
+
+ The LLM generates only simple identifiers. Confidential figures are
+ never exposed in prompt context.
+
+
+
+ {/* Input Selector Form */}
+ {selectedTemplate.templateId === 'PayrollSummary' ? (
+
+
+
+ Department Name (`department`):
+
+ {
+ setPayrollDept(e.target.value);
+ handleResolveDynamicTemplate({department: e.target.value});
+ }}
+ style={{
+ width: '100%',
+ padding: '8px 12px',
+ borderRadius: '8px',
+ border: '1px solid #cbd5e1',
+ fontSize: '13px',
+ boxSizing: 'border-box',
+ }}
+ />
+
+
+
+ {
+ setPayrollIncludeBonus(e.target.checked);
+ handleResolveDynamicTemplate({includeBonus: e.target.checked});
+ }}
+ />
+ Include Annual Bonus Column (`includeBonus`)
+
+
+
+
+ Generated Express DSL by LLM:
+
+
+ {`\nroot = PayrollSummary("${payrollDept}", ${payrollIncludeBonus})\n `}
+
+
+
+ ) : (
+
+
+ Select Employee (Input Parameter `employeeId`):
+
+
handleResolveDynamicTemplate(e.target.value)}
+ style={{
+ padding: '10px 14px',
+ borderRadius: '8px',
+ border: '1px solid #cbd5e1',
+ fontSize: '14px',
+ fontWeight: 600,
+ color: '#0f172a',
+ backgroundColor: '#ffffff',
+ outline: 'none',
+ cursor: 'pointer',
+ }}
+ >
+ {(
+ selectedTemplate.availablePresets || [
+ {label: 'Dr. Elena Vance (emp_101)', value: 'emp_101'},
+ {label: 'Marcus Vance (emp_102)', value: 'emp_102'},
+ {label: 'Aria Chen (emp_103)', value: 'emp_103'},
+ {label: 'Liam Kjell (emp_104)', value: 'emp_104'},
+ ]
+ ).map(opt => (
+
+ {opt.label}
+
+ ))}
+
+
+
+
+ Generated Express DSL by LLM:
+
+
+ {`\nroot = EmployeeSalaryCard("${selectedDynamicEmpId}")\n `}
+
+
+
+ )}
+
+
+ handleResolveDynamicTemplate()}
+ disabled={dynamicResolving}
+ style={{
+ padding: '10px 20px',
+ borderRadius: '8px',
+ backgroundColor: '#2563eb',
+ color: '#ffffff',
+ border: 'none',
+ fontWeight: 600,
+ fontSize: '13px',
+ cursor: dynamicResolving ? 'not-allowed' : 'pointer',
+ display: 'inline-flex',
+ alignItems: 'center',
+ gap: '6px',
+ }}
+ >
+
+ sync
+
+
+ {dynamicResolving
+ ? 'Computing...'
+ : selectedTemplate.isProgrammatic
+ ? 'Run Python Render Function'
+ : 'Execute Server Resolver'}
+
+
+
+ {selectedTemplate.isProgrammatic
+ ? '✓ Python execution engine active'
+ : '✓ Server resolver connected'}
+
+
+
+ )}
+
+ {dynamicTab === 'layout' && (
+
+
+
+ {selectedTemplate.isProgrammatic
+ ? 'Step 2: Python Render Function (Programmatic AST Generator)'
+ : 'Step 2: Underlying Layout Template (Static Blueprint)'}
+
+
+ {selectedTemplate.isProgrammatic
+ ? 'This template is generated directly by a Python render function using loops, conditionals, and math to construct the component AST.'
+ : 'The visual layout is declared once in YAML (salary_card.yaml). Parameter placeholders like baseSalary and annualBonus are populated by the server callback.'}
+
+
+
+
+ {selectedTemplate.isProgrammatic
+ ? selectedTemplate.renderSource || '# Python render function'
+ : selectedTemplate.layoutTemplateYaml ||
+ selectedTemplate.yamlContent ||
+ ''}
+
+
+ )}
+
+ {dynamicTab === 'resolved' && (
+
+
+
+ Step 3: Server-Resolved Injected Data
+
+
+ Live record retrieved from the internal HR database for{' '}
+ {selectedDynamicEmpId}.
+
+
+
+
+ {JSON.stringify(dynamicResolvedData || {}, null, 2)}
+
+
+ )}
+
+
+ {/* Right Column: Live Inflated Preview */}
+
+
+
+ Inflated Output Preview
+
+
+ ✓ Live Inflated
+
+
+
+
+ {(() => {
+ const dynSurface =
+ libraryProcessor.model.getSurface(
+ `preview_${selectedTemplate.templateId}_${selectedDynamicEmpId}`,
+ ) ||
+ libraryProcessor.model.getSurface(
+ `preview_${selectedTemplate.templateId}`,
+ );
+ return dynSurface ? (
+
+ ) : (
+
+ No preview surface available for this template.
+
+ );
+ })()}
+
+
+
+
+ ) : (
+ /* Standard Static Template Studio */
+
+ {/* Left: Live Inflated Preview */}
+
+
+
+
+ Inflated UI Preview
+
+
+ Rendered via @a2ui/react using declared sampleData
+
+
+
+ ✓ Live Inflated
+
+
+
+
+ {libraryProcessor.model.getSurface(`preview_${selectedTemplate.templateId}`) ? (
+
+ ) : (
+
+ No preview surface available for this template.
+
+ )}
+
+
+ {selectedTemplate.sampleData && (
+
+
+ Sample Data Inputs
+
+
+ {JSON.stringify(selectedTemplate.sampleData, null, 2)}
+
+
+ )}
+
+
+ {/* Right: Code with Line Numbers & Monospace Font */}
+
+
+
+
+ Template Declaration (YAML)
+
+
+ Parameterized YAML layout definition
+
+
+
+
{
+ copyToClipboard(selectedTemplate.yamlContent || '', true);
+ }}
+ style={{
+ display: 'inline-flex',
+ alignItems: 'center',
+ gap: '6px',
+ padding: '6px 12px',
+ borderRadius: '8px',
+ border: '1px solid #cbd5e1',
+ backgroundColor: '#ffffff',
+ color: '#0f172a',
+ fontSize: '12px',
+ fontWeight: 600,
+ cursor: 'pointer',
+ boxShadow: '0 1px 2px rgba(0, 0, 0, 0.04)',
+ }}
+ >
+
+ {copiedTemplate ? 'check' : 'content_copy'}
+
+ {copiedTemplate ? 'Copied YAML!' : 'Copy Template YAML'}
+
+
+
+
+
+ {selectedTemplate.templateId.toLowerCase()}.yaml
+ YAML Schema draft 2020-12
+
+
+
+ {(() => {
+ const yamlText = selectedTemplate.yamlContent || '';
+ const lines = yamlText.split('\n');
+
+ return (
+ <>
+
+ {lines.map((_, idx) => (
+
{idx + 1}
+ ))}
+
+
+
+ {lines.map((line, idx) => (
+
{line || ' '}
+ ))}
+
+ >
+ );
+ })()}
+
+
+
+
+ )
+ ) : (
+
+ {libraryLoading ? 'Loading templates...' : 'No templates available.'}
+
+ )}
+
+ )}
+
+ );
+}
diff --git a/samples/community/templates/client/src/main.tsx b/samples/community/templates/client/src/main.tsx
new file mode 100644
index 0000000000..6d92e4f429
--- /dev/null
+++ b/samples/community/templates/client/src/main.tsx
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import App from './App';
+
+ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
+
+
+ ,
+);
diff --git a/samples/community/templates/client/tsconfig.json b/samples/community/templates/client/tsconfig.json
new file mode 100644
index 0000000000..0426f7bb8e
--- /dev/null
+++ b/samples/community/templates/client/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "useDefineForClassFields": true,
+ "lib": ["ES2022", "DOM", "DOM.Iterable"],
+ "module": "ESNext",
+ "skipLibCheck": true,
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx",
+ "strict": true,
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noFallthroughCasesInSwitch": true
+ },
+ "include": ["src"]
+}
diff --git a/samples/community/templates/client/vite.config.ts b/samples/community/templates/client/vite.config.ts
new file mode 100644
index 0000000000..95c8497c8d
--- /dev/null
+++ b/samples/community/templates/client/vite.config.ts
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2024 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {defineConfig} from 'vite';
+import react from '@vitejs/plugin-react';
+
+export default defineConfig({
+ plugins: [react()],
+ server: {
+ port: 5173,
+ open: false,
+ },
+});
diff --git a/agent_sdks/python/a2ui_agent/src/a2ui/template/__init__.py b/samples/community/templates/pyproject.toml
similarity index 50%
rename from agent_sdks/python/a2ui_agent/src/a2ui/template/__init__.py
rename to samples/community/templates/pyproject.toml
index 10c96753bb..c2dd8b8164 100644
--- a/agent_sdks/python/a2ui_agent/src/a2ui/template/__init__.py
+++ b/samples/community/templates/pyproject.toml
@@ -4,10 +4,27 @@
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
-# https://www.apache.org/licenses/LICENSE-2.0
+# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
+
+[project]
+name = "a2ui-templates-demo-server"
+version = "0.1.0"
+description = "A2UI Templates Community Demo Server"
+requires-python = ">=3.10"
+dependencies = [
+ "fastapi>=0.115.0",
+ "uvicorn>=0.30.0",
+ "google-genai>=1.0.0",
+ "a2ui-agent-sdk",
+ "a2ui-core"
+]
+
+[tool.uv.sources]
+a2ui-agent-sdk = { path = "../../../agent_sdks/python/a2ui_agent", editable = true }
+a2ui-core = { path = "../../../agent_sdks/python/a2ui_core", editable = true }
diff --git a/samples/community/templates/server.py b/samples/community/templates/server.py
new file mode 100644
index 0000000000..abd1d6c2a5
--- /dev/null
+++ b/samples/community/templates/server.py
@@ -0,0 +1,642 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Concise FastAPI server demonstrating A2UI Static and Dynamic Templates with Agent SDK."""
+
+from __future__ import annotations
+
+import glob
+import inspect
+import os
+from pathlib import Path
+import time
+from typing import Any, Dict, List
+from fastapi import FastAPI, HTTPException
+from fastapi.middleware.cors import CORSMiddleware
+from google import genai
+from google.genai import types
+from pydantic import BaseModel
+
+from a2ui.inference_formats.experimental.template import (
+ StaticTemplate,
+ DynamicTemplate,
+ dynamic_template,
+ TemplateInferenceFormat,
+)
+
+app = FastAPI(title="A2UI Templates Community Demo Server")
+
+app.add_middleware(
+ CORSMiddleware,
+ allow_origins=["*"],
+ allow_credentials=True,
+ allow_headers=["*"],
+ allow_methods=["*"],
+)
+
+MODEL_NAME = os.environ.get("GEMINI_MODEL", "gemini-flash-latest")
+BASIC_CATALOG_ID = "https://a2ui.org/specification/v0_9/catalogs/basic/catalog.json"
+
+# Mock Secure HR / Compensation Database
+EMPLOYEE_COMPENSATION_DB = {
+ "emp_101": {
+ "employeeName": "Dr. Elena Vance",
+ "role": "Principal Systems Architect",
+ "baseSalary": "$215,000",
+ "annualBonus": "$45,000",
+ "equity": "3,500 RSUs",
+ "clearanceLevel": "Level 5 - Confidential",
+ "verifiedAt": "2026-08-13",
+ },
+ "emp_102": {
+ "employeeName": "Marcus Vance",
+ "role": "Streaming & Protocols Lead",
+ "baseSalary": "$195,000",
+ "annualBonus": "$38,000",
+ "equity": "2,800 RSUs",
+ "clearanceLevel": "Level 4 - Confidential",
+ "verifiedAt": "2026-08-13",
+ },
+ "emp_103": {
+ "employeeName": "Aria Chen",
+ "role": "Head of Design Systems",
+ "baseSalary": "$205,000",
+ "annualBonus": "$42,000",
+ "equity": "3,100 RSUs",
+ "clearanceLevel": "Level 5 - Confidential",
+ "verifiedAt": "2026-08-13",
+ },
+ "emp_104": {
+ "employeeName": "Liam Kjell",
+ "role": "Senior Framework Engineer",
+ "baseSalary": "$180,000",
+ "annualBonus": "$32,000",
+ "equity": "2,200 RSUs",
+ "clearanceLevel": "Level 3 - Internal",
+ "verifiedAt": "2026-08-13",
+ },
+}
+
+
+def fetch_employee_compensation(employeeId: str) -> Dict[str, Any]:
+ """Fetches verified confidential compensation package from internal HR database."""
+ if employeeId not in EMPLOYEE_COMPENSATION_DB:
+ raise ValueError(
+ f"Employee ID '{employeeId}' not found in HR compensation records."
+ f" Available: {list(EMPLOYEE_COMPENSATION_DB.keys())}"
+ )
+ return EMPLOYEE_COMPENSATION_DB[employeeId]
+
+
+@dynamic_template(
+ name="PayrollSummary",
+ catalogs=["https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"],
+ description=(
+ "Programmatic dynamic template that aggregates company payroll, sums"
+ " employee base salaries and bonuses using server Python logic, and builds"
+ " an interactive summary table. Pass department (default 'Engineering') and"
+ " includeBonus (default True)."
+ ),
+ sample_data={"department": "Global Engineering", "includeBonus": True},
+)
+def render_payroll_summary(
+ department: str = "Global Engineering", includeBonus: bool = True
+) -> Dict[str, Any]:
+ """Programmatic dynamic template: performs Python math, loops, formatting, and builds an AST table."""
+ total_base = 0
+ total_bonus = 0
+ rows: List[Dict[str, Any]] = []
+
+ for emp_id, record in EMPLOYEE_COMPENSATION_DB.items():
+ base_int = int(record["baseSalary"].replace("$", "").replace(",", ""))
+ bonus_int = int(record["annualBonus"].replace("$", "").replace(",", ""))
+ total_base += base_int
+ total_bonus += bonus_int
+
+ cols = [
+ {"component": "Text", "text": record["employeeName"], "variant": "body"},
+ {"component": "Text", "text": record["role"], "variant": "caption"},
+ {"component": "Text", "text": record["baseSalary"], "variant": "body"},
+ ]
+ if includeBonus:
+ cols.append(
+ {"component": "Text", "text": record["annualBonus"], "variant": "body"}
+ )
+
+ rows.append({
+ "component": "Row",
+ "justify": "spaceBetween",
+ "align": "center",
+ "children": cols,
+ })
+ rows.append({"component": "Divider", "axis": "horizontal"})
+
+ # Header Row
+ header_cols = [
+ {"component": "Text", "text": "Employee", "variant": "caption"},
+ {"component": "Text", "text": "Role", "variant": "caption"},
+ {"component": "Text", "text": "Base Salary", "variant": "caption"},
+ ]
+ if includeBonus:
+ header_cols.append(
+ {"component": "Text", "text": "Annual Bonus", "variant": "caption"}
+ )
+
+ # Total Row
+ total_cols = [
+ {"component": "Text", "text": "TOTAL PAYROLL", "variant": "h4"},
+ {
+ "component": "Text",
+ "text": f"{len(EMPLOYEE_COMPENSATION_DB)} Employees",
+ "variant": "caption",
+ },
+ {"component": "Text", "text": f"${total_base:,}", "variant": "h4"},
+ ]
+ if includeBonus:
+ total_cols.append(
+ {"component": "Text", "text": f"${total_bonus:,}", "variant": "h4"}
+ )
+
+ total_budget = total_base + (total_bonus if includeBonus else 0)
+
+ return {
+ "component": "Card",
+ "child": {
+ "component": "Column",
+ "children": [
+ {
+ "component": "Row",
+ "justify": "spaceBetween",
+ "align": "center",
+ "children": [
+ {
+ "component": "Row",
+ "align": "center",
+ "children": [
+ {"component": "Icon", "name": "lock"},
+ {
+ "component": "Text",
+ "text": (
+ f"Payroll & Compensation Summary: {department}"
+ ),
+ "variant": "h3",
+ },
+ ],
+ },
+ {
+ "component": "Text",
+ "text": "Confidential HR Record",
+ "variant": "caption",
+ },
+ ],
+ },
+ {"component": "Divider", "axis": "horizontal"},
+ {
+ "component": "Row",
+ "justify": "spaceBetween",
+ "align": "center",
+ "children": header_cols,
+ },
+ {"component": "Divider", "axis": "horizontal"},
+ *rows,
+ {
+ "component": "Row",
+ "justify": "spaceBetween",
+ "align": "center",
+ "children": total_cols,
+ },
+ {"component": "Divider", "axis": "horizontal"},
+ {
+ "component": "Row",
+ "justify": "spaceBetween",
+ "align": "center",
+ "children": [
+ {
+ "component": "Text",
+ "text": (
+ "🔒 Computed live by server Python execution engine"
+ ),
+ "variant": "caption",
+ },
+ {
+ "component": "Text",
+ "text": f"Total Budget: ${total_budget:,}",
+ "variant": "caption",
+ },
+ ],
+ },
+ ],
+ },
+ }
+
+
+def load_templates() -> List[Any]:
+ """Loads all static templates and registers dynamic resolver templates."""
+ current_file = Path(__file__).resolve()
+ templates_dir = current_file.parent / "templates"
+ templates_pattern = str(templates_dir / "*.yaml")
+
+ templates_list = []
+ salary_layout = None
+
+ for path in glob.glob(templates_pattern):
+ loaded_templates = StaticTemplate.from_yaml_file(path)
+ for tmpl in loaded_templates:
+ if tmpl.name == "SalaryCard" or tmpl.template_id == "SalaryCard":
+ salary_layout = tmpl
+ else:
+ templates_list.append(tmpl)
+
+ if salary_layout is not None:
+ # Register DynamicTemplate for EmployeeSalaryCard (Data Binding Mode)
+ dynamic_salary = DynamicTemplate(
+ version="0.1",
+ name="EmployeeSalaryCard",
+ template_id="EmployeeSalaryCard",
+ catalogs=[
+ "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+ ],
+ resolver=fetch_employee_compensation,
+ layout=salary_layout,
+ description=(
+ "Secure verified employee compensation card. Pass only the"
+ " employeeId ('emp_101', 'emp_102', 'emp_103', 'emp_104');"
+ " compensation data is securely fetched server-side from the"
+ " HR database."
+ ),
+ sample_data={"employeeId": "emp_101"},
+ )
+ templates_list.append(dynamic_salary)
+
+ # Register DynamicTemplate for PayrollSummary (Programmatic Render Mode via decorator)
+ templates_list.append(render_payroll_summary)
+
+ return templates_list
+
+
+templates = load_templates()
+format_instance = TemplateInferenceFormat(
+ templates=templates,
+ surface_id="main",
+ version="0.9.1",
+)
+
+ROLE_DESCRIPTION = """You are an A2UI interface assistant. When helpful, respond with visual UI using the compact A2UI Express DSL inside `` tags.
+
+Select and present only the UI components that are directly relevant to the user's request. Depending on the query, this may be a single template, a standard primitive, or a custom composed layout that you invent to address the query.
+
+You can compose high-level templates and primitive components together:
+- Layout & Containers: `Column`, `Row`, `Card`, `SectionCard(title, description, headerAction, children)`, `TwoColumnLayout(headerChild, leftChildren, rightChildren)`.
+- Reusable & Dynamic Templates:
+ - `UserProfile(userId, userName, role)` for individual identity cards.
+ - `EmployeeSalaryCard(employeeId)` for verified employee compensation. Pass only the employeeId (e.g. "emp_101" for Dr. Elena Vance, "emp_102" for Marcus Vance, "emp_103" for Aria Chen, "emp_104" for Liam Kjell). Confidential compensation data is securely resolved server-side from the HR database.
+ - `TeamMemberKnowledgePanel(userName, role, experienceYears, completedTasks)` for stats and skill summaries.
+ - `TeamGoalList(teamName, goals)` or `GoalItem(title, priority, targetDate)` for objective tracking.
+ - `TeamFeedbackBoard(teamName, feedbacks)` or `FeedbackItem(author, note, rating)` for reviews and retrospectives.
+ - `TeamCard(teamName, members)` and `TeamRoster(directoryTitle, children)` for organizational hierarchies.
+
+For complex queries requiring multiple sections (such as a performance review or project status), you can invent appropriate composite layouts—for instance, grouping a `TeamMemberKnowledgePanel`, `TeamFeedbackBoard`, and `TeamGoalList` within a `Column` or `TwoColumnLayout`."""
+
+SYSTEM_PROMPT = format_instance.prompt_generator.generate(
+ role_description=ROLE_DESCRIPTION,
+ include_schema=True,
+)
+
+
+class ChatRequest(BaseModel):
+ prompt: str
+ surfaceId: str = "surface_1"
+ conversationId: str = "default_conv"
+
+
+class DynamicResolveRequest(BaseModel):
+ params: Dict[str, Any]
+
+
+PRESET_RESPONSES = {
+ "show user profile": (
+ """
+
+ root = UserProfile("usr_101", "Alice Smith", "Lead Architect")
+
+ """
+ ),
+ "show verified salary": (
+ """
+
+ root = EmployeeSalaryCard("emp_102")
+
+ """
+ ),
+ "show payroll summary": (
+ """
+
+ root = PayrollSummary("Global Engineering", true)
+
+ """
+ ),
+ "show user evaluation": (
+ """
+
+ knowledge = TeamMemberKnowledgePanel("Alice Smith", "Lead Systems Architect", 9, 142)
+ feedbacks = TeamFeedbackBoard("Peer Reviews & Feedback", [
+ {author: "Dr. Elena Vance", note: "Exceptional architecture design and synchronous template engine.", rating: 5},
+ {author: "Marcus Vance", note: "Great mentor on A2UI streaming and component catalogs.", rating: 5}
+ ])
+ goals = TeamGoalList("2026 Objectives", [
+ {title: "Finalize A2UI Protocol Specification", priority: "High", targetDate: "2026-09-30"},
+ {title: "Publish Community Template Studio", priority: "High", targetDate: "2026-10-15"}
+ ])
+ root = Column([knowledge, feedbacks, goals])
+
+ """
+ ),
+ "show team roster": (
+ """
+
+ team1 = TeamCard("Core Architecture", [
+ {userId: "u1", userName: "Dr. Elena Vance", role: "Principal Architect"},
+ {userId: "u2", userName: "Marcus Vance", role: "Streaming Lead"}
+ ])
+ team2 = TeamCard("Design Systems", [
+ {userId: "u3", userName: "Aria Chen", role: "Head of Design"},
+ {userId: "u4", userName: "Liam Kjell", role: "Senior Engineer"}
+ ])
+ root = TeamRoster("Organization Directory", [team1, team2])
+
+ """
+ ),
+ "show team goals": (
+ """
+
+ root = TeamGoalList("Core Protocol Engineering", [
+ {title: "Deliver synchronous template expansion engine", priority: "High", targetDate: "2026-08-30"},
+ {title: "Redesign templates for Basic Catalog", priority: "High", targetDate: "2026-08-15"},
+ {title: "Simplify community demo architectures", priority: "Medium", targetDate: "2026-09-01"}
+ ])
+
+ """
+ ),
+ "show feedback board": (
+ """
+
+ root = TeamFeedbackBoard("Frontend & Protocols Guild", [
+ {author: "Dr. Elena Vance", note: "Synchronous template expansion eliminated all streaming race conditions.", rating: 5},
+ {author: "Marcus Vance", note: "Standard Basic Catalog components ensure 100% cross-renderer compatibility.", rating: 5}
+ ])
+
+ """
+ ),
+ "show competency panel": (
+ """
+
+ root = TeamMemberKnowledgePanel("Alice Smith", "Lead Systems Architect", 9, 142)
+
+ """
+ ),
+}
+
+
+@app.get("/templates")
+@app.get("/api/templates")
+def list_templates():
+ res = []
+ for t in templates:
+ t_dict = t.to_dict()
+ t_dict["yamlContent"] = t.to_yaml()
+ sample_params = t.sample_data or {}
+ try:
+ expanded_components = format_instance.processor.expand_template(
+ "root", t.template_id, sample_params
+ )
+ sample_messages = [
+ {
+ "version": "v0.9.1",
+ "createSurface": {
+ "surfaceId": f"preview_{t.template_id}",
+ "catalogId": BASIC_CATALOG_ID,
+ },
+ },
+ {
+ "version": "v0.9.1",
+ "updateComponents": {
+ "surfaceId": f"preview_{t.template_id}",
+ "components": expanded_components,
+ },
+ },
+ ]
+ except Exception:
+ sample_messages = []
+ t_dict["sampleMessages"] = sample_messages
+
+ if getattr(t, "is_dynamic", False):
+ dynamic_tmpl: DynamicTemplate = t # type: ignore
+ t_dict["isDynamic"] = True
+ if getattr(dynamic_tmpl, "render_fn", None) is not None:
+ t_dict["isProgrammatic"] = True
+ try:
+ t_dict["renderSource"] = inspect.getsource(dynamic_tmpl.render_fn)
+ except Exception:
+ t_dict["renderSource"] = ""
+ if dynamic_tmpl.layout is not None:
+ t_dict["isDataBinding"] = True
+ t_dict["layoutTemplate"] = dynamic_tmpl.layout.to_dict()
+ t_dict["layoutTemplateYaml"] = dynamic_tmpl.layout.to_yaml()
+ # Run resolver on sampleData to show resolved state
+ try:
+ t_dict["resolvedData"] = dynamic_tmpl.resolve(sample_params)
+ except Exception:
+ t_dict["resolvedData"] = {}
+ if dynamic_tmpl.template_id == "EmployeeSalaryCard":
+ t_dict["availablePresets"] = [
+ {"label": f"{v['employeeName']} ({k})", "value": k}
+ for k, v in EMPLOYEE_COMPENSATION_DB.items()
+ ]
+
+ res.append(t_dict)
+ return res
+
+
+@app.post("/templates/{template_id}/resolve")
+@app.post("/api/templates/{template_id}/resolve")
+def resolve_template(template_id: str, req: DynamicResolveRequest):
+ tmpl = format_instance.processor.templates.get(template_id)
+ if not tmpl:
+ raise HTTPException(status_code=404, detail="Template not found")
+
+ try:
+ expanded_components = format_instance.processor.expand_template(
+ "root", template_id, req.params
+ )
+ sample_messages = [
+ {
+ "version": "v0.9.1",
+ "createSurface": {
+ "surfaceId": f"preview_{template_id}",
+ "catalogId": BASIC_CATALOG_ID,
+ },
+ },
+ {
+ "version": "v0.9.1",
+ "updateComponents": {
+ "surfaceId": f"preview_{template_id}",
+ "components": expanded_components,
+ },
+ },
+ ]
+ resolved_data = {}
+ if getattr(tmpl, "is_dynamic", False):
+ if getattr(tmpl, "render_fn", None) is not None:
+ resolved_data = {
+ "execution": "Python Programmatic Render Function",
+ "generatedComponentCount": len(expanded_components),
+ "appliedParams": req.params,
+ }
+ else:
+ resolved_data = tmpl.resolve(req.params) # type: ignore
+
+ return {
+ "expandedComponents": expanded_components,
+ "sampleMessages": sample_messages,
+ "resolvedData": resolved_data,
+ }
+ except Exception as e:
+ raise HTTPException(status_code=400, detail=str(e))
+
+
+@app.post("/interact")
+@app.post("/api/chat")
+async def chat(req: ChatRequest):
+ start_time = time.perf_counter()
+ prompt_lower = req.prompt.strip().lower()
+
+ # 1. Preset shortcut responses for instant offline evaluation
+ if prompt_lower in PRESET_RESPONSES:
+ dsl = PRESET_RESPONSES[prompt_lower]
+ target_format = TemplateInferenceFormat(
+ templates=templates,
+ surface_id=req.surfaceId,
+ version="0.9.1",
+ )
+ parts = target_format.parser.parse_response(dsl)
+ messages = parts[0].a2ui_json if parts and parts[0].a2ui_json else []
+ latency = round(time.perf_counter() - start_time, 3)
+ return {
+ "messages": messages,
+ "raw": dsl.strip(),
+ "text": f"Here is the rendered {req.prompt}:",
+ "surfaceId": req.surfaceId,
+ "metrics": {
+ "latency": latency,
+ "thinkingTokens": 0,
+ "outputTokens": len(dsl.split()),
+ "isPreset": True,
+ },
+ }
+
+ # 2. Live Gemini inference if API key is provided
+ api_key = os.environ.get("GEMINI_API_KEY") or os.environ.get("GOOGLE_API_KEY")
+ if api_key:
+ try:
+ client = genai.Client(api_key=api_key)
+ response = await client.aio.models.generate_content(
+ model=MODEL_NAME,
+ contents=[req.prompt],
+ config=types.GenerateContentConfig(
+ system_instruction=SYSTEM_PROMPT,
+ response_mime_type="text/plain",
+ ),
+ )
+ latency = round(time.perf_counter() - start_time, 2)
+ raw_text = response.text or ""
+ target_format = TemplateInferenceFormat(
+ templates=templates,
+ surface_id=req.surfaceId,
+ version="0.9.1",
+ )
+ parts = target_format.parser.parse_response(raw_text)
+
+ messages = []
+ text_parts = []
+ for part in parts:
+ if part.text:
+ text_parts.append(part.text)
+ if part.a2ui_json:
+ messages.extend(part.a2ui_json)
+
+ thinking_tokens = 0
+ candidates_tokens = 0
+ if response.usage_metadata:
+ thinking_tokens = (
+ getattr(response.usage_metadata, "thoughts_token_count", 0) or 0
+ )
+ candidates_tokens = (
+ getattr(response.usage_metadata, "candidates_token_count", 0) or 0
+ )
+
+ actual_surface_id = req.surfaceId
+ for msg in messages:
+ if isinstance(msg, dict):
+ if "createSurface" in msg and "surfaceId" in msg["createSurface"]:
+ actual_surface_id = msg["createSurface"]["surfaceId"]
+ break
+ elif (
+ "updateComponents" in msg
+ and "surfaceId" in msg["updateComponents"]
+ ):
+ actual_surface_id = msg["updateComponents"]["surfaceId"]
+ break
+
+ return {
+ "messages": messages,
+ "raw": raw_text.strip(),
+ "text": "\n".join(text_parts).strip() or "UI generated successfully.",
+ "surfaceId": actual_surface_id,
+ "metrics": {
+ "latency": latency,
+ "thinkingTokens": thinking_tokens,
+ "outputTokens": candidates_tokens,
+ "isPreset": False,
+ },
+ }
+ except Exception as e:
+ return {
+ "messages": [],
+ "raw": f"Error: {str(e)}",
+ "text": f"Error generating template UI: {str(e)}",
+ "surfaceId": req.surfaceId,
+ "metrics": {
+ "latency": round(time.perf_counter() - start_time, 2),
+ "thinkingTokens": 0,
+ "outputTokens": 0,
+ "isPreset": False,
+ },
+ }
+
+ # 3. Fallback when no Gemini API key is configured
+ return {
+ "messages": [],
+ "raw": "",
+ "text": (
+ "Gemini API key is not configured on the server. Please click one of the"
+ " preset buttons above or set the GEMINI_API_KEY environment variable."
+ ),
+ "surfaceId": req.surfaceId,
+ "metrics": {
+ "latency": 0.0,
+ "thinkingTokens": 0,
+ "outputTokens": 0,
+ "isPreset": True,
+ },
+ }
diff --git a/samples/community/templates/templates/feedback_item.yaml b/samples/community/templates/templates/feedback_item.yaml
new file mode 100644
index 0000000000..a68544221a
--- /dev/null
+++ b/samples/community/templates/templates/feedback_item.yaml
@@ -0,0 +1,62 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+templateId: FeedbackItem
+description: Card showing feedback note, author, and rating.
+parameters:
+ author:
+ type: string
+ title: Author Name
+ description: The name of the colleague or customer providing feedback.
+ note:
+ type: string
+ title: Feedback Note
+ description: The written feedback or retrospective comment.
+ rating:
+ type: number
+ title: Feedback Rating
+ description: Score from 1 to 5.
+ minimum: 1
+ maximum: 5
+ default: 5
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Text
+ text: "{{ note }}"
+
+ variant: body
+ - component: Divider
+ axis: horizontal
+ - component: Row
+ justify: spaceBetween
+ align: center
+ children:
+ - component: Text
+ text: "{{ author }}"
+
+ variant: caption
+ - component: Text
+ text: "Rating: {{ rating }}/5"
+ variant: caption
+sampleData:
+ author: Dr. Elena Vance
+ note: A2UI templates are fast and easy to compose.
+ rating: 5
+catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+name: FeedbackItem
diff --git a/samples/community/templates/templates/goal_item.yaml b/samples/community/templates/templates/goal_item.yaml
new file mode 100644
index 0000000000..c04b39a99d
--- /dev/null
+++ b/samples/community/templates/templates/goal_item.yaml
@@ -0,0 +1,75 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+templateId: GoalItem
+description: Card showing an individual objective with priority, title, target date,
+ and action button.
+parameters:
+ title:
+ type: string
+ title: Goal Title
+ description: Summary title of the objective.
+ priority:
+ type: enum
+ title: Priority Level
+ description: Urgency rating for the objective.
+ values:
+ - High
+ - Medium
+ - Low
+ default: Medium
+ targetDate:
+ type: string
+ title: Target Date
+ description: Target completion date in YYYY-MM-DD format.
+ default: "2026-12-31"
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Row
+ justify: spaceBetween
+ align: center
+ children:
+ - component: Text
+ text: "Priority: {{ priority }}"
+ variant: caption
+ - component: Icon
+ name: star
+ - component: Text
+ text: "{{ title }}"
+
+ variant: h4
+ - component: Divider
+ axis: horizontal
+ - component: Row
+ justify: spaceBetween
+ align: center
+ children:
+ - component: Text
+ text: "Due: {{ targetDate }}"
+ variant: caption
+ - component: Button
+ child:
+ component: Text
+ text: View Details
+sampleData:
+ title: Launch A2UI SDK v1.0
+ priority: High
+ targetDate: "2026-09-30"
+catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+name: GoalItem
diff --git a/samples/community/templates/templates/salary_card.yaml b/samples/community/templates/templates/salary_card.yaml
new file mode 100644
index 0000000000..7add7d2838
--- /dev/null
+++ b/samples/community/templates/templates/salary_card.yaml
@@ -0,0 +1,137 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+templateId: SalaryCard
+description: Layout card for employee compensation package with security verification
+ badge.
+parameters:
+ employeeName:
+ type: string
+ title: Employee Full Name
+ description: Full name of the verified employee.
+ role:
+ type: string
+ title: Job Title
+ description: Official company role.
+ baseSalary:
+ type: string
+ title: Base Salary
+ description: Annual base compensation.
+ annualBonus:
+ type: string
+ title: Annual Bonus
+ description: Target annual incentive bonus.
+ equity:
+ type: string
+ title: Equity Grants
+ description: Stock units or RSU package.
+ clearanceLevel:
+ type: string
+ title: Security Clearance
+ description: Confidentiality level.
+ default: Level 4 - Confidential
+ verifiedAt:
+ type: string
+ title: Verification Date
+ description: Timestamp of record retrieval.
+ default: "2026-08-13"
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Row
+ justify: spaceBetween
+ align: center
+ children:
+ - component: Row
+ align: center
+ children:
+ - component: Icon
+ name: lock
+ - component: Text
+ text: Verified Compensation
+ variant: caption
+ - component: Text
+ text: "{{ clearanceLevel }}"
+
+ variant: caption
+ - component: Column
+ children:
+ - component: Text
+ text: "{{ employeeName }}"
+
+ variant: h3
+ id: name_txt
+ - component: Text
+ text: "{{ role }}"
+
+ variant: body
+ - component: Divider
+ axis: horizontal
+ - component: Row
+ justify: spaceBetween
+ children:
+ - component: Column
+ children:
+ - component: Text
+ text: Base Salary
+ variant: caption
+ - component: Text
+ text: "{{ baseSalary }}"
+
+ variant: h4
+ id: sal_val
+ - component: Column
+ children:
+ - component: Text
+ text: Annual Bonus
+ variant: caption
+ - component: Text
+ text: "{{ annualBonus }}"
+
+ variant: h4
+ - component: Column
+ children:
+ - component: Text
+ text: Equity Grants
+ variant: caption
+ - component: Text
+ text: "{{ equity }}"
+
+ variant: h4
+ - component: Divider
+ axis: horizontal
+ - component: Row
+ justify: spaceBetween
+ align: center
+ children:
+ - component: Text
+ text: "\U0001F512 Fetched live from secure HR database"
+ variant: caption
+ - component: Text
+ text: "Verified: {{ verifiedAt }}"
+ variant: caption
+sampleData:
+ employeeName: Dr. Elena Vance
+ role: Principal Systems Architect
+ baseSalary: $215,000
+ annualBonus: $45,000
+ equity: 3,500 RSUs
+ clearanceLevel: Level 5 - Confidential
+ verifiedAt: "2026-08-13"
+catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+name: SalaryCard
diff --git a/samples/community/templates/templates/section_card.yaml b/samples/community/templates/templates/section_card.yaml
new file mode 100644
index 0000000000..6083919f7a
--- /dev/null
+++ b/samples/community/templates/templates/section_card.yaml
@@ -0,0 +1,71 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+templateId: SectionCard
+description: Standard container card with title, description, optional action, and
+ child components.
+parameters:
+ title:
+ type: string
+ title: Section Title
+ description: Heading text displayed at the top of the section card.
+ description:
+ type: string
+ title: Section Description
+ description: Subordinate descriptive text beneath the title.
+ default: ""
+ headerAction:
+ type: child
+ title: Header Action Component
+ description: Single child component placed in the right side of the header.
+ children:
+ type: children
+ title: Section Children
+ description: Child component IDs rendered in the section body.
+ default: []
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Row
+ justify: spaceBetween
+ align: center
+ children:
+ - component: Text
+ text: "{{ title }}"
+
+ variant: h3
+ - component: Column
+ id: action_slot
+ children: "{{ headerAction }}"
+
+ - component: Text
+ text: "{{ description }}"
+
+ variant: caption
+ - component: Divider
+ axis: horizontal
+ - component: Column
+ id: body_container
+ children: "{{ children }}"
+
+sampleData:
+ title: Protocol Overview
+ description: High-level summary of the streaming architecture.
+ children: []
+catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+name: SectionCard
diff --git a/samples/community/templates/templates/team_card.yaml b/samples/community/templates/templates/team_card.yaml
new file mode 100644
index 0000000000..31811857a0
--- /dev/null
+++ b/samples/community/templates/templates/team_card.yaml
@@ -0,0 +1,83 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+templateId: TeamCard
+description: Card showing team header and unrolled member cards.
+parameters:
+ teamName:
+ type: string
+ title: Team Name
+ description: The display name of the team.
+ members:
+ type: array
+ title: Team Members List
+ description: Array of team member objects.
+ items:
+ type: object
+ title: Team Member
+ properties:
+ userId:
+ type: string
+ title: User ID
+ description: Unique identifier of the user.
+ userName:
+ type: string
+ title: User Name
+ description: Full name of the user.
+ role:
+ type: string
+ title: Role Name
+ description: Role or title of the user.
+ default: Member
+ required:
+ - userId
+ - userName
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Row
+ justify: spaceBetween
+ align: center
+ children:
+ - component: Text
+ text: "{{ teamName }}"
+
+ variant: h3
+ - component: Icon
+ name: person
+ - component: Divider
+ axis: horizontal
+ - component: Column
+ children:
+ loop:
+ param: members
+ template: UserProfile
+sampleData:
+ teamName: Antigravity Devs
+ members:
+ - userId: usr_101
+ userName: Alice Smith
+ role: Lead Architect
+ - userId: usr_102
+ userName: Bob Jones
+ role: Senior Engineer
+ - userId: usr_103
+ userName: Charlie Brown
+ role: Product Manager
+catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+name: TeamCard
diff --git a/samples/community/templates/templates/team_feedback_board.yaml b/samples/community/templates/templates/team_feedback_board.yaml
new file mode 100644
index 0000000000..75e4b5d6ca
--- /dev/null
+++ b/samples/community/templates/templates/team_feedback_board.yaml
@@ -0,0 +1,80 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+templateId: TeamFeedbackBoard
+description: Feedback board showing team header and feedback items.
+parameters:
+ teamName:
+ type: string
+ title: Team Name
+ description: The display name of the team whose feedback board is being rendered.
+ feedbacks:
+ type: array
+ title: Feedbacks List
+ description: Array of feedback objects with author, note, and rating.
+ items:
+ type: object
+ title: Feedback Review
+ properties:
+ author:
+ type: string
+ title: Author Name
+ description: Full name of the person giving feedback.
+ note:
+ type: string
+ title: Feedback Note
+ description: Textual comment or recommendation.
+ rating:
+ type: number
+ title: Rating Score
+ minimum: 1
+ maximum: 5
+ default: 5
+ required:
+ - author
+ - note
+layout:
+ component: Column
+ children:
+ - component: Card
+ child:
+ component: Row
+ align: center
+ children:
+ - component: Icon
+ name: mail
+ - component: Text
+ text: "Feedback & Retrospective: {{ teamName }}"
+ variant: h2
+ - component: Column
+ id: feedbacks_container
+ children:
+ loop:
+ param: feedbacks
+ template: FeedbackItem
+sampleData:
+ teamName: Streaming & Protocols Guild
+ feedbacks:
+ - author: Dr. Elena Vance
+ note: Splitting createSurface and updateComponents cleanly unblocked sequential
+ stream processing.
+ rating: 5
+ - author: Marcus Vance
+ note: Unrolling nested lists statically in Python enables instant frontend mounting
+ with zero runtime recursion.
+ rating: 5
+catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+name: TeamFeedbackBoard
diff --git a/samples/community/templates/templates/team_goal_list.yaml b/samples/community/templates/templates/team_goal_list.yaml
new file mode 100644
index 0000000000..dc652ce577
--- /dev/null
+++ b/samples/community/templates/templates/team_goal_list.yaml
@@ -0,0 +1,79 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+templateId: TeamGoalList
+description: List of team goals with header banner.
+parameters:
+ teamName:
+ type: string
+ title: Team Name
+ description: The display name of the team whose goals are being listed.
+ goals:
+ type: array
+ title: Goals List
+ description: Array of goal objects with title, priority, and targetDate.
+ items:
+ type: object
+ title: Goal Definition
+ properties:
+ title:
+ type: string
+ title: Goal Title
+ description: Summary title of the objective
+ priority:
+ type: enum
+ title: Priority Level
+ values:
+ - High
+ - Medium
+ - Low
+ default: Medium
+ targetDate:
+ type: string
+ title: Target Date
+ description: Target completion date (YYYY-MM-DD)
+ required:
+ - title
+layout:
+ component: Column
+ children:
+ - component: Card
+ child:
+ component: Row
+ align: center
+ children:
+ - component: Icon
+ name: star
+ - component: Text
+ text: "Strategic Objectives: {{ teamName }}"
+ variant: h2
+ - component: Column
+ id: goals_container
+ children:
+ loop:
+ param: goals
+ template: GoalItem
+sampleData:
+ teamName: A2UI Core Team
+ goals:
+ - title: Implement bidirectional child/children container resolution
+ priority: High
+ targetDate: "2026-07-15"
+ - title: Upgrade all templates to standard Basic Catalog components
+ priority: High
+ targetDate: "2026-07-10"
+catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+name: TeamGoalList
diff --git a/samples/community/templates/templates/team_member_knowledge_panel.yaml b/samples/community/templates/templates/team_member_knowledge_panel.yaml
new file mode 100644
index 0000000000..bbc4ca7e1f
--- /dev/null
+++ b/samples/community/templates/templates/team_member_knowledge_panel.yaml
@@ -0,0 +1,96 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+templateId: TeamMemberKnowledgePanel
+description: Card showing competency panel with user experience years and completed
+ task count.
+parameters:
+ userName:
+ type: string
+ title: User Display Name
+ description: The full name of the team member.
+ role:
+ type: string
+ title: Role Name
+ description: The operational role of the team member.
+ experienceYears:
+ type: integer
+ title: Years of Experience
+ description: The number of years of professional experience.
+ minimum: 0
+ completedTasks:
+ type: integer
+ title: Completed Tasks Count
+ description: The count of completed tasks or tickets.
+ minimum: 0
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Row
+ align: center
+ children:
+ - component: Icon
+ name: check
+ - component: Text
+ text: "Competency: {{ userName }}"
+ variant: h4
+ - component: Divider
+ axis: horizontal
+ - component: Row
+ justify: spaceBetween
+ children:
+ - component: Column
+ align: center
+ children:
+ - component: Text
+ text: Role
+ variant: caption
+ - component: Text
+ text: "{{ role }}"
+
+ variant: body
+ - component: Column
+ align: center
+ children:
+ - component: Text
+ text: Experience
+ variant: caption
+ - component: Text
+ text: "{{ experienceYears }} Yrs"
+
+ variant: body
+ - component: Column
+ align: center
+ children:
+ - component: Text
+ text: Tasks
+ variant: caption
+ - component: Text
+ text: "{{ completedTasks }} Done"
+
+ variant: body
+ - component: Text
+ text: Verified Core Contributor
+ variant: caption
+sampleData:
+ userName: Alice Smith
+ role: Systems Architect
+ experienceYears: 9
+ completedTasks: 142
+catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+name: TeamMemberKnowledgePanel
diff --git a/samples/community/templates/templates/team_roster.yaml b/samples/community/templates/templates/team_roster.yaml
new file mode 100644
index 0000000000..3bf023c3a3
--- /dev/null
+++ b/samples/community/templates/templates/team_roster.yaml
@@ -0,0 +1,45 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+templateId: TeamRoster
+description: Team directory roster with styled header banner and nested team lists.
+parameters:
+ directoryTitle:
+ type: string
+ title: Directory Title
+ description: Title text for the team directory.
+ children:
+ type: children
+ title: Team Cards List
+ description: List of child TeamCard components.
+ default: []
+layout:
+ component: Column
+ children:
+ - component: Text
+ text: "{{ directoryTitle }}"
+
+ variant: h1
+ - component: Divider
+ axis: horizontal
+ - component: Column
+ children: "{{ children }}"
+
+sampleData:
+ directoryTitle: Global Engineering Directory
+ children: []
+catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+name: TeamRoster
diff --git a/samples/community/templates/templates/two_column_layout.yaml b/samples/community/templates/templates/two_column_layout.yaml
new file mode 100644
index 0000000000..45aa31700f
--- /dev/null
+++ b/samples/community/templates/templates/two_column_layout.yaml
@@ -0,0 +1,58 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+templateId: TwoColumnLayout
+description: Responsive two-column dashboard layout with banner header and split content
+ regions.
+parameters:
+ headerChild:
+ type: child
+ title: Header Component Slot
+ description: Single child component ID mounted at the top banner.
+ leftChildren:
+ type: children
+ title: Left Column Children
+ description: Child components placed in the left primary region.
+ default: []
+ rightChildren:
+ type: children
+ title: Right Column Children
+ description: Child components placed in the right secondary region.
+ default: []
+layout:
+ component: Column
+ children:
+ - component: Column
+ children: "{{ headerChild }}"
+
+ - component: Divider
+ axis: horizontal
+ - component: Row
+ children:
+ - component: Column
+ children: "{{ leftChildren }}"
+
+ - component: Column
+ children: "{{ rightChildren }}"
+
+sampleData:
+ headerChild:
+ component: Text
+ text: Header Title
+ leftChildren: []
+ rightChildren: []
+catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+name: TwoColumnLayout
diff --git a/samples/community/templates/templates/user_profile.yaml b/samples/community/templates/templates/user_profile.yaml
new file mode 100644
index 0000000000..038c47f65c
--- /dev/null
+++ b/samples/community/templates/templates/user_profile.yaml
@@ -0,0 +1,54 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+templateId: UserProfile
+description: User profile card displaying avatar, full name, and role.
+parameters:
+ userId:
+ type: string
+ title: User ID
+ description: Unique user account ID.
+ userName:
+ type: string
+ title: User Name
+ description: Full name of the user.
+ role:
+ type: string
+ title: Role
+ description: Job title or role.
+ default: Member
+layout:
+ component: Card
+ child:
+ component: Column
+ align: center
+ children:
+ - component: Icon
+ name: person
+ - component: Text
+ text: "{{ userName }}"
+
+ variant: h3
+ - component: Text
+ text: "{{ role }}"
+
+ variant: caption
+sampleData:
+ userId: usr_101
+ userName: Alice Smith
+ role: Lead Architect
+catalogs:
+ - https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json
+name: UserProfile
diff --git a/samples/community/templates/test_e2e.mjs b/samples/community/templates/test_e2e.mjs
new file mode 100644
index 0000000000..ec364cb3ab
--- /dev/null
+++ b/samples/community/templates/test_e2e.mjs
@@ -0,0 +1,256 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import {chromium} from 'playwright';
+
+async function runE2ETest() {
+ console.log(
+ '🚀 Starting A2UI Templates End-to-End Test (Presets + Inspector + Template Library + Live LLM)...',
+ );
+
+ const browser = await chromium.launch({headless: true});
+ const page = await browser.newPage();
+
+ const pageErrors = [];
+ page.on('pageerror', err => {
+ console.error('❌ Page Error:', err.message);
+ pageErrors.push(err.message);
+ });
+
+ try {
+ // 1. Navigate to client
+ console.log('🌐 Navigating to http://localhost:5173...');
+ await page.goto('http://localhost:5173', {waitUntil: 'networkidle', timeout: 15000});
+
+ const title = await page.textContent('h1');
+ console.log(`✅ Loaded application: "${title?.trim()}"`);
+
+ // Helper to verify a preset button
+ async function testPreset(buttonText, expectedContents) {
+ console.log(`\n👉 Clicking preset: "${buttonText}"...`);
+ const btn = page.locator(`button:has-text("${buttonText}")`);
+ await btn.click();
+
+ // Wait for assistant response and surface to render
+ await page.waitForTimeout(1000);
+
+ const bodyText = await page.textContent('body');
+ if (
+ bodyText.includes('Error contacting server:') ||
+ bodyText.includes('Validation failed') ||
+ bodyText.includes('Catalog not found')
+ ) {
+ throw new Error(`Client reported error after clicking "${buttonText}":\n${bodyText}`);
+ }
+
+ for (const expected of expectedContents) {
+ if (!bodyText.includes(expected)) {
+ throw new Error(
+ `Expected text "${expected}" not found in rendered DOM for preset "${buttonText}".`,
+ );
+ }
+ console.log(` ✓ Found rendered text: "${expected}"`);
+ }
+ console.log(`✅ Preset "${buttonText}" passed!`);
+ }
+
+ // 2. Test Presets
+ await testPreset('🔒 Verified Salary', [
+ 'Verified Compensation',
+ 'Marcus Vance',
+ '$195,000',
+ '$38,000',
+ '2,800 RSUs',
+ ]);
+ await testPreset('💰 Payroll Summary', [
+ 'Payroll & Compensation Summary',
+ 'TOTAL PAYROLL',
+ '$795,000',
+ 'Total Budget: $952,000',
+ ]);
+ await testPreset('👤 User Profile', ['Alice Smith', 'Lead Architect']);
+ await testPreset('👥 Team Roster', [
+ 'Organization Directory',
+ 'Core Architecture',
+ 'Dr. Elena Vance',
+ 'Design Systems',
+ 'Aria Chen',
+ ]);
+ await testPreset('🎯 Team Goals', [
+ 'Strategic Objectives: Core Protocol Engineering',
+ 'Deliver synchronous template expansion engine',
+ 'High',
+ ]);
+ await testPreset('💬 Feedback Board', [
+ 'Feedback & Retrospective: Frontend & Protocols Guild',
+ 'Dr. Elena Vance',
+ 'Marcus Vance',
+ ]);
+ await testPreset('⭐ Competency Panel', [
+ 'Competency: Alice Smith',
+ 'Lead Systems Architect',
+ '9 Yrs',
+ '142 Done',
+ ]);
+
+ // 3. Test Inspector UI on Turn
+ console.log('\n👉 Testing Format & JSON Inspector Drawer...');
+ const inspectBtn = page.locator('button:has-text("Inspect Format")').last();
+ await inspectBtn.click();
+ await page.waitForTimeout(500);
+
+ // Verify Express DSL is visible
+ let inspectorContent = await page.textContent('body');
+ if (
+ !inspectorContent.includes('') &&
+ !inspectorContent.includes('UserProfile') &&
+ !inspectorContent.includes('EmployeeSalaryCard')
+ ) {
+ throw new Error(`Expected Express DSL content in inspector drawer:\n${inspectorContent}`);
+ }
+ console.log(' ✓ Raw Express DSL displayed in inspector drawer');
+
+ // Switch to Expanded JSON Tab
+ const jsonTabBtn = page.locator('button:has-text("Expanded A2UI JSON")');
+ await jsonTabBtn.click();
+ await page.waitForTimeout(500);
+
+ inspectorContent = await page.textContent('body');
+ if (
+ !inspectorContent.includes('createSurface') ||
+ !inspectorContent.includes('updateComponents')
+ ) {
+ throw new Error(`Expected expanded JSON messages in inspector drawer:\n${inspectorContent}`);
+ }
+ console.log(' ✓ Expanded A2UI JSON displayed in inspector drawer');
+ console.log('✅ Inspector Drawer Test Passed!');
+
+ // 4. Test Template Library Screen
+ console.log('\n👉 Testing Template Library Studio...');
+ const libraryTabBtn = page.locator('button:has-text("Template Library")');
+ await libraryTabBtn.click();
+ await page.waitForTimeout(1000);
+
+ let libraryBody = await page.textContent('body');
+ if (
+ !libraryBody.includes('Registered Templates') ||
+ (!libraryBody.includes('Inflated UI Preview') &&
+ !libraryBody.includes('Inflated Output Preview'))
+ ) {
+ throw new Error(`Template Library studio failed to load:\n${libraryBody}`);
+ }
+ console.log(' ✓ Template Library screen mounted');
+
+ // Click EmployeeSalaryCard dynamic template in library list
+ console.log('\n👉 Testing Dynamic Template 3-Stage Studio...');
+ const salaryCardBtn = page.locator('button:has-text("EmployeeSalaryCard")').first();
+ await salaryCardBtn.click();
+ await page.waitForTimeout(600);
+
+ libraryBody = await page.textContent('body');
+ if (
+ !libraryBody.includes('Dynamic Server Resolver') ||
+ !libraryBody.includes('Step 1: Simple LLM Input Interface')
+ ) {
+ throw new Error(`Dynamic template studio failed to mount:\n${libraryBody}`);
+ }
+ console.log(' ✓ Dynamic Template 3-Stage Studio mounted');
+
+ // Test dropdown selection to Marcus Vance
+ const empSelect = page.locator('select');
+ await Promise.all([
+ page.waitForResponse(resp => resp.url().includes('/resolve') && resp.status() === 200),
+ empSelect.selectOption('emp_102'),
+ ]);
+ await page.waitForTimeout(800);
+
+ libraryBody = await page.textContent('body');
+ if (!libraryBody.includes('Marcus Vance') || !libraryBody.includes('$195,000')) {
+ throw new Error(`Dynamic resolver execution for emp_102 failed:\n${libraryBody}`);
+ }
+ console.log(' ✓ Dynamic server resolver executed and updated preview for Marcus Vance');
+
+ // Test Stage 2: Static Blueprint Tab
+ const layoutTabBtn = page.locator('button:has-text("2. Static Blueprint")');
+ await layoutTabBtn.click();
+ await page.waitForTimeout(400);
+
+ libraryBody = await page.textContent('body');
+ if (!libraryBody.includes('salary_card.yaml') && !libraryBody.includes('baseSalary')) {
+ throw new Error(`Static Blueprint stage failed to display:\n${libraryBody}`);
+ }
+ console.log(' ✓ Static Blueprint stage displayed underlying salary_card.yaml layout');
+
+ // Test Stage 3: Resolved Output Tab
+ const resolvedTabBtn = page.locator('button:has-text("3. Resolved Output")');
+ await resolvedTabBtn.click();
+ await page.waitForTimeout(400);
+
+ libraryBody = await page.textContent('body');
+ if (!libraryBody.includes('$195,000') || !libraryBody.includes('$38,000')) {
+ throw new Error(`Resolved Output stage failed to display injected record:\n${libraryBody}`);
+ }
+ console.log(' ✓ Resolved Output stage displayed live injected database figures');
+ console.log('✅ Dynamic Template 3-Stage Studio Passed!');
+
+ // Switch back to Interactive Chat
+ const chatTabBtn = page.locator('button:has-text("Interactive Chat")');
+ await chatTabBtn.click();
+ await page.waitForTimeout(500);
+
+ // 5. Test Live LLM Request
+ console.log('\n👉 Testing Live Gemini LLM Generation...');
+ const input = page.locator('input[type="text"]');
+ await input.fill('Create a team goal list for Cloud Platform team with 2 goals');
+ const sendBtn = page.locator('button:has-text("Send")');
+ await sendBtn.click();
+
+ // Wait for LLM generation and client mounting
+ console.log(' Waiting for live Gemini inference & template expansion...');
+ await page.waitForTimeout(6000);
+
+ const liveBodyText = await page.textContent('body');
+ if (
+ liveBodyText.includes('Error contacting server:') ||
+ liveBodyText.includes('Validation failed') ||
+ liveBodyText.includes('Catalog not found')
+ ) {
+ throw new Error(`Live LLM request failed with error in client:\n${liveBodyText}`);
+ }
+
+ if (
+ !liveBodyText.includes('Cloud Platform') &&
+ !liveBodyText.includes('Strategic Objectives')
+ ) {
+ throw new Error(
+ `Expected live generated goal card not found in rendered DOM:\n${liveBodyText}`,
+ );
+ }
+ console.log(' ✓ Live LLM generated card rendered cleanly in DOM!');
+ console.log('✅ Live LLM Request Passed!');
+
+ if (pageErrors.length > 0) {
+ throw new Error(`Encountered ${pageErrors.length} unhandled page errors during test run.`);
+ }
+
+ console.log('\n🎉 ALL PRESETS, INSPECTOR, TEMPLATE LIBRARY, AND LIVE LLM TESTS PASSED! 🎉\n');
+ } finally {
+ await browser.close();
+ }
+}
+
+runE2ETest().catch(err => {
+ console.error('\n❌ E2E TEST FAILED:', err);
+ process.exit(1);
+});
diff --git a/samples/community/templates/uv.lock b/samples/community/templates/uv.lock
new file mode 100644
index 0000000000..4c605565f3
--- /dev/null
+++ b/samples/community/templates/uv.lock
@@ -0,0 +1,2231 @@
+version = 1
+revision = 3
+requires-python = ">=3.10"
+resolution-markers = [
+ "python_full_version >= '3.14'",
+ "python_full_version >= '3.11' and python_full_version < '3.14'",
+ "python_full_version < '3.11'",
+]
+
+[[package]]
+name = "a2a-sdk"
+version = "0.3.26"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "google-api-core" },
+ { name = "httpx" },
+ { name = "httpx-sse" },
+ { name = "protobuf" },
+ { name = "pydantic" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/a2a-sdk/a2a_sdk-0.3.26.tar.gz", hash = "sha256:44068e2d037afbb07ab899267439e9bc7eaa7ac2af94f1e8b239933c993ad52d" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/a2a-sdk/a2a_sdk-0.3.26-py3-none-any.whl", hash = "sha256:754e0573f6d33b225c1d8d51f640efa69cbbed7bdfb06ce9c3540ea9f58d4a91" },
+]
+
+[[package]]
+name = "a2ui-agent-sdk"
+source = { editable = "../../../agent_sdks/python/a2ui_agent" }
+dependencies = [
+ { name = "a2a-sdk" },
+ { name = "a2ui-core" },
+ { name = "antlr4-python3-runtime" },
+ { name = "google-adk" },
+ { name = "google-genai" },
+ { name = "jsonschema" },
+ { name = "pyyaml" },
+]
+
+[package.metadata]
+requires-dist = [
+ { name = "a2a-sdk", specifier = ">=0.3.0,<0.4.0" },
+ { name = "a2ui-core", editable = "../../../agent_sdks/python/a2ui_core" },
+ { name = "antlr4-python3-runtime", specifier = ">=4.13.0,<4.14.0" },
+ { name = "google-adk", specifier = ">=1.28.1" },
+ { name = "google-genai", specifier = ">=1.27.0" },
+ { name = "jsonschema", specifier = ">=4.0.0" },
+ { name = "pyyaml", specifier = ">=6.0" },
+]
+
+[package.metadata.requires-dev]
+dev = [
+ { name = "antlr4-tools", specifier = ">=0.2.1" },
+ { name = "hatchling", specifier = ">=1.30.1" },
+ { name = "types-jsonschema" },
+ { name = "types-pyyaml" },
+]
+
+[[package]]
+name = "a2ui-core"
+source = { editable = "../../../agent_sdks/python/a2ui_core" }
+dependencies = [
+ { name = "jsonschema" },
+ { name = "pydantic" },
+ { name = "referencing" },
+]
+
+[package.metadata]
+requires-dist = [
+ { name = "jsonschema", specifier = ">=4.26.0" },
+ { name = "pydantic", specifier = ">=2.10.0" },
+ { name = "referencing", specifier = ">=0.37.0" },
+]
+
+[package.metadata.requires-dev]
+dev = [{ name = "pyyaml", specifier = ">=6.0.3" }]
+
+[[package]]
+name = "a2ui-templates-demo-server"
+version = "0.1.0"
+source = { virtual = "." }
+dependencies = [
+ { name = "a2ui-agent-sdk" },
+ { name = "a2ui-core" },
+ { name = "fastapi" },
+ { name = "google-genai" },
+ { name = "uvicorn" },
+]
+
+[package.metadata]
+requires-dist = [
+ { name = "a2ui-agent-sdk", editable = "../../../agent_sdks/python/a2ui_agent" },
+ { name = "a2ui-core", editable = "../../../agent_sdks/python/a2ui_core" },
+ { name = "fastapi", specifier = ">=0.115.0" },
+ { name = "google-genai", specifier = ">=1.0.0" },
+ { name = "uvicorn", specifier = ">=0.30.0" },
+]
+
+[[package]]
+name = "aiohappyeyeballs"
+version = "2.7.1"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohappyeyeballs/aiohappyeyeballs-2.7.1.tar.gz", hash = "sha256:065665c041c42a5938ed220bdcd7230f22527fbec085e1853d2402c8a3615d9d" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohappyeyeballs/aiohappyeyeballs-2.7.1-py3-none-any.whl", hash = "sha256:9243213661e29250eb41368e5daa826fc017156c3b8a11440826b2e3ed376472" },
+]
+
+[[package]]
+name = "aiohttp"
+version = "3.14.3"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "aiohappyeyeballs" },
+ { name = "aiosignal" },
+ { name = "async-timeout", marker = "python_full_version < '3.11'" },
+ { name = "attrs" },
+ { name = "frozenlist" },
+ { name = "multidict" },
+ { name = "propcache" },
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
+ { name = "yarl" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3.tar.gz", hash = "sha256:9491196535a88924a60afd5b5f434b5b203b6cc616250878dbdb223a8f7844bc" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:eb0495d778817619273c108784292be161a924b9f5ae5cbbc70a2caa6838250b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c3c200cf9757edd785051dc699c7ecbec22110dbfcb3fefc7a9f9695eda8ea7a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd51ebf9d3a00c074df4ede271023f4d2dba289bcc740b88191872716014e3c5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:134ac5ddcf61c6fad984b9a5727d83492ada43d63471db20fb73042c13fca62f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:70c987b27534f9ae1a723f47ae921571d616da21d3208282bf4c52af5164ac43" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1b59533861b70a2185c8f4f350f791f39d64358ef6944ce71c5240c9ec0982c9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1c5281acc88b92396f88c7e1e2748f8466689df22b80170e4f51efa712fb47a8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48d67b87db6279c044760787eb01f6413032c2e6f3ba1cafaa492b1c8e578479" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f53bcd52f585e1ac3e590d61434eb61f9a88c38df041b4ea126d97144344a77b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0fdea2281997af69da84c77ffa6f5938a0285f21fb3887c249d67419ca865b3d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:cda5fd5c95ad7a125a2e8464acc78b98b94c475a3780d6aa0aa157c93f470f4d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:6debfa7312ff9d4c124dc71d72e9a0a4b9e0879e48ba6fcb42bef5c3300289e2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f4e05329faa0ea1a404b37de4f034fd2c2defcca06a68dc6745e4e56c88e8a48" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a3a8296e7ab5c295f53f1041487cb088e1480775aafbf7fe545d93b770a0f96f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5373dc80ad1aa2fb9ad95c83f24eef418bbda3a61375f128e5b0192e4f3f9b32" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-win32.whl", hash = "sha256:a3e22975f905b89a55a488c2a08f2fdb2186175349e917d48985cc468a3d4c6e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdd0e2834dce1a26c1bbe26464861e16bbe217042cbff619247c11594472518c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp310-cp310-win_arm64.whl", hash = "sha256:eac645b09bcfdf73df7536331f0678c1086ea250981118ddb5199e17ccef72bb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e568e14940c09955aa51f4e645b6daa18a581c5dcfcd73744dcc86a856e3ced3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54cfcdee2770dac994417cbb0ee1f3eb0e7cb6b30c79bf44f2c02ff79ec5124a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:21c016079415ed3fd676963e9793700a566d85dbbd6bfc564b9b2d209147dcc8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d6088ec9894113802bddb3c09e974929aed2c7b3a8c456219b8aab4481f1a239" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:16ea7e24c309fb7c0bbd505d149abe4fe4dccfb8db911db7dbec0921bc889a6f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56f355e79f71aef2a85c80305cc915f894b170dba76de5fe84f6351939b83c06" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:18c441d0a8fca6de8d1f546849b9f0ab20d435993e2c5b59562b2fae6be2f929" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53e7b4ce82b54a8bcc71b3b67a5cbd177ca1d7f592cbc92cd38b7349f73482db" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f55119f7bf25f49ed210f6096090715da24f2943c62102448915fde3c62877ce" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9aa6e61fdf20105c4144e755bd586008ff450791d67b1c8146fdc15959c4d51c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ccd4893707b3e2a13e39c90d43cf80edf2e4d0457935bcc103bf2346214c3f15" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b2466434105a4e03113c36ec775cc2ebe6676b62eae326fa670bb607ef788c1c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:ba59d59aba08ac02fc03b0c8983ccd5ee39a199d0552ce9e6d2b4845b34d59ae" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ed099d105449c4f9e84f24af203cd131349d4761d8813fa7e02c32e7128cd910" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:152516815ef926786a0b6ae2b8f1fd2e0c71582dee0b435636865316fd4891b7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-win32.whl", hash = "sha256:a4af35c443e0b1a1bd6a8af3f3485d7fda15c142751a00f3ff8090f0b93346fa" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-win_amd64.whl", hash = "sha256:e1e74298bab6ee0d6e749ed4fd1901c7e604bdda32c03d787a2cc71c46d0433d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp311-cp311-win_arm64.whl", hash = "sha256:03cd2bde3d7f085b64e549c985f4bb928cad7e8ecf5323bfca320db548d81b39" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:39aded8c7f3b935b54aab1d8d73c70ec0ee2d3ec3b943e0e86611bc150ba47f5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5bcb6ff3fdab1258a192679ff1a05d44f59626430aa05cd1a9d2447423599228" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:617105e2c3018ee38d0c8ce5ee3c84f621a6d8b9f723202aacaff28449ca91ee" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f631fe87a6f30df5fbe6d79640b25e4cffb38c31c7fb6f10871517b84b0f8c1a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a94dbaae5ae27bd849c93570669bff91e0510f33a80805738e3de72a7be0447b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8f2f1c4c032c7cedd7d8da6f54c97b70266c6570c3108d3fdffee7188bb70529" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ea05e1f97ceea523942d9b2a7d7c0359d781d683d6b043f5943a602b14da4787" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:543906c127fb1d929b95076db19b83fa2d46751006ff1e23b093aa5ac4d8db42" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0a5ff2dfbb9ce645fa5b8ef3e02c6c0b9cc3f6030ff863d0c51fffc50cb5541b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:041badb8f84396357c4d3ad26de6afd7a32b112f43d3c63045c0c8278cfd2043" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:530125ee1163c4219af35dc3aa1206e541e7b31b6efc1a3f93b70a136f65d427" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c8653fd547c93a61aadc612007790f5555cdd18946fa48cf45e26d8ea4ea473d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:89176250f686cb9853c0fb7ead90e639e915b84a6f43eedc2a4e7ec21f1037f0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3a26434dafe408229ff3403458ca58de24fb51936504decac49ce6755f77e59d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d1558173930a5a8d3069cee5c92fc91c87c4dbcb099debbb3622053717145a19" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-win32.whl", hash = "sha256:16100ad3ab8d649fdfbee87602d9d2dcdca9df0b9eda8a1b5fdc0d41f96da559" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:33a2d7c28d33797a2e99923dffa63f83d908a19b6bf26cfe80fa790aa5e1a75a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:362a3fd481769cac1a824514bcd86fda51c65e8fe6e051099e008fddde6db17c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-android_21_arm64_v8a.whl", hash = "sha256:2e9878ae68e4a5f1c0abe4dd497dbc3d51946f5837b56759e2a02e78fa90ef86" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-android_21_x86_64.whl", hash = "sha256:f3d2669fe7dec7fc359ecdb5984b29b50d85d5d00f8c1cb61de4f4a24ee42627" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:cc7cb243a68167172f48c1fd43cee91ec4b1d40cefd190edd43369d1a6bc9c82" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:78253b573e6ffab5028924fc98bc281aae05445969982a10864bc360dea2016c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7041d52c3a7fa20c9e8c182b534704abb19502c8bdcbde7ab23bfda6f642394f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ac74facc01463f138b0da5580329cfcc82818dea5656e83ddcd11268fc12ff80" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d6218d92e450824e9b4881f44e8c09f1853b490f9a64130801024a4793b1b3b0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:11fb37ef075669eee52ab1928fbf6e1741fada40409fa309ebde9607a962aebf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55bdcc472aafe2de4a253045cc128007a64f1e0264fb675791e132ea5edaa3bd" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c39846c3aad97a8530c89d7a3869a8f8e9e3762c6ac0504481e5c80948f7e807" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5895ef58c4620afe02fa16044f023dc4dafec08158f9d08874a46a7dbc0341b8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa9467a8113aa69d3d7c55a70ef0b7c636010a40993f3df9d9d0d73b3eb7ef24" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d7d2deec16eeedf55f2c7cf75b521ea3856a5177e123844f8fd0f114ce252cb5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dd54d0e8717de95939766febac482ac0474d8ac3b048115f9f2b1d23a16e7db4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:df82f3787c940c94986b34222d59c9e38843fba85139f36e85255a82ad5355a9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:42a67efc36300d052fb4508a53e8b6901b9284b599ae63945c377569c5fcc1e1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7a75aa63cbf9b21cfaf60dc2657e19df2c2867d91707d653fee171ffeedd1371" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:e92eb8acc45eb6a9f4935071a77edf5b85cc6f8dfad5cd99e97653c26593cdde" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b014a6ed7cf912e787149fdc529166d3ceabac23f26efeea3158c9aba2354e7e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3d4f72af88ac2474bb5bca640030320e3d38a0163a1d7533500e87be458eef71" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-win32.whl", hash = "sha256:5f08ec777f35ee70720233b8b9811d3bb5d728137f30ac91b7457709c3261ac0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-win_amd64.whl", hash = "sha256:dff9461ec275f22135650d5ba4b4931a11f3958df7dfbb8db630000d4dee0883" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp313-cp313-win_arm64.whl", hash = "sha256:ddcac3c6b382e81f1dd0499199d4136b877beb4cb5ef770bbbfba56c4b8f55d2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:49f7325beb0f85ef4aef5f48f490269575f83e6e2acad00a1d80b807eb027062" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-android_24_x86_64.whl", hash = "sha256:e3be98a7c30b8c25d573dafba7171d66dfb05ee6a9070fc46535464ff97700a6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:614c61d478b83953e261d02bb2df750f17227cd33ef8002945bf5aebbde21919" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:1caa7b0d05f3e3a36f87788c59e970a7ee1cefcfcbb924a9f138c4a6551c9cb7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:dfa68deb2a443bdaa3ea5297b0699c1464f08aef3812b486d1348eee61b07dc0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:e72ee89e28d907a18f46959b4eb0bb06701cc7f8cf4366e00029e2ccfaaf5924" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ad4c8b7488d745d2ca4838ebd8ae5ba9b56341d30b1da43640e4ce87f9f49646" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:db332af25642007330fca8be5c4d194caf2bea7a7fc84415aff3497af5dfee6b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25bd2708db6bdf6a6630dd37bdcdfcb47c4434d22ac69c64665b802910140b30" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:cef89a58e628c4efcac3275c2d68083f82426dcdc89c1492a6f654f9f7ea6ab9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c23ec8ee9d5ab2f5421f9c7fffce208435607af27fd46d4a44e031954352838f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e2667f0bbe7eb6c74eae5e9691441ad186e5845ca3cff63230fc09c4e7514f5d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18cb43369747b2ae007bd2655fb8e63a099c2ff1d207962943636dac989b3147" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d77640cc618c1d99fc4f8589c0f24a730adfa54eb1e57ef7bf0c8dfb78da898c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:53e5179d8abb5710f8e83ba207c41c8d1261fcffd4616500e15ca2b7a33be10a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:cd817772b2fcf2b8c0905795318485f9ec16eae60b29feb7f4c77085311637f0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:4e3ac92d90e92773b2362d506068e9a948192bd553e743c5b2429e28527c8661" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3f42e9b78301f11c8f861746175d8b9c1ccef713fcad9eab396e2f6db8ed4a22" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:9d9edccfe496b476db5f398d97b865e9a6752bcf8aec4eef8390ce20fb64bb41" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1c5ec8fb1bcc31a8466f74aaf26c345d5c386fa4bd08a3f0eb9c7a4a3fe8b5bf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-win32.whl", hash = "sha256:38901a84da3ce22249f6e860bf8f90d141bcab7da090cc398f8bb58c0e44b7da" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:8b3b60de05f3dcb6f6a00f818bb2ec781cee4de0645f59ccaf99b1d1823b6100" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:1576145bdceeb92382d899751e12743a3a5b8e460a841e3e50543859e54864dc" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:8800c996b01c2772a783e3e46f3e1abd5823029adca0df54231960de9bfefa5b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ebe8e504f058fe91223351cecd2d9d6946c9d241bb0250d898ffbdf584cc72b0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:30402d03a7c0ff52bce290b57e564e9079fd9d0cb545c8aba73f86a103162d2e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9fc7b5bfec6573f3ae844f457fdde5adeb713f8b8e4a81ad64fc207b49383716" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8a5fd34f7f7410d1730d5c2ba873cacb2eed3fede366feb268a70ba22581ed8f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:270d3dace9ca2f10f0da5d8ebe519b7a310fc6112ed916e32df5866df0888553" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3ae5b3a59436d089b5395d910121a390feed4d00578eb95a0fd1a329fe963100" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2498f0fe69ead802f9675beca44a7c21c62fdaa4ec5145ea1c3ad6edbee29f85" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a0dc483c00da8b673abbb367eb6f8d8f4bcec30eb58529ea13cb42e7fd2dfa33" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c7d3a97c678d34fc5b59da671ee9cd630096ddc643e7b5a30d54a2a6f3574d3f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:f8fb78a83c9e5f741ca3a68cfb455c1f5bb83b4e7249a3848b3cd78d0a8563b0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:74ab5b6a9fb13e873e5a90946588baecaf488745e1db1a4a5c433f971f035098" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:bd52f811e65f6fb634b1047159657c98f52b407f8efec907bcfc09da9a4c0a25" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f0f177d1b195b9e06376cfd7d308d8a1b920909a609d03ac82a8c73bbb16d3b9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:498c6c623134f8e09a3c4e60bcd607a0b4590dd7dbf08dd40851b27cbb520ccb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-win32.whl", hash = "sha256:b304db572b4368edd8dda8a2274f73156fe15558fca4a917cb8a09fc47af5963" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:b20032766aedf6261c7a566585a40867d092ac03a0d81592d5370ef9b054f99b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiohttp/aiohttp-3.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:2e1161602f45a54de2ce0905243a95f58cb42dcd378402f3697f5e0b21e9d2e7" },
+]
+
+[[package]]
+name = "aiosignal"
+version = "1.4.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "frozenlist" },
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiosignal/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiosignal/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e" },
+]
+
+[[package]]
+name = "aiosqlite"
+version = "0.22.1"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiosqlite/aiosqlite-0.22.1.tar.gz", hash = "sha256:043e0bd78d32888c0a9ca90fc788b38796843360c855a7262a532813133a0650" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/aiosqlite/aiosqlite-0.22.1-py3-none-any.whl", hash = "sha256:21c002eb13823fad740196c5a2e9d8e62f6243bd9e7e4a1f87fb5e44ecb4fceb" },
+]
+
+[[package]]
+name = "annotated-doc"
+version = "0.0.5"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/annotated-doc/annotated_doc-0.0.5.tar.gz", hash = "sha256:c7e58ce09192557605d8bbd92836d7e1d520ac9580096042c0bfd197efacf1bb" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/annotated-doc/annotated_doc-0.0.5-py3-none-any.whl", hash = "sha256:117bac03a25ede5df5440e855b32d556049ca169ead221505badf432fed4b101" },
+]
+
+[[package]]
+name = "annotated-types"
+version = "0.8.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/annotated-types/annotated_types-0.8.0.tar.gz", hash = "sha256:13b2beaad985e05e2d6407ee4c4f35590b11f8d693a258a561055cac8f64cab7" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/annotated-types/annotated_types-0.8.0-py3-none-any.whl", hash = "sha256:f072f4d804ea359e4eaf198b1af7a8b0943881a87f31bb764f8bf219bb9419e0" },
+]
+
+[[package]]
+name = "antlr4-python3-runtime"
+version = "4.13.2"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/antlr4-python3-runtime/antlr4_python3_runtime-4.13.2.tar.gz", hash = "sha256:909b647e1d2fc2b70180ac586df3933e38919c85f98ccc656a96cd3f25ef3916" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/antlr4-python3-runtime/antlr4_python3_runtime-4.13.2-py3-none-any.whl", hash = "sha256:fe3835eb8d33daece0e799090eda89719dbccee7aa39ef94eed3818cafa5a7e8" },
+]
+
+[[package]]
+name = "anyio"
+version = "4.14.2"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "exceptiongroup", marker = "python_full_version < '3.11'" },
+ { name = "idna" },
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/anyio/anyio-4.14.2.tar.gz", hash = "sha256:cfa139f3ed1a23ee8f88a145ddb5ac7605b8bbfd8592baacd7ce3d8bb4313c7f" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/anyio/anyio-4.14.2-py3-none-any.whl", hash = "sha256:9f505dda5ac9f0c8309b5e8bd445a8c2bf7246f3ce950121e45ea15bc41d1494" },
+]
+
+[[package]]
+name = "async-timeout"
+version = "5.0.1"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/async-timeout/async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/async-timeout/async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c" },
+]
+
+[[package]]
+name = "attrs"
+version = "26.1.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/attrs/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/attrs/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309" },
+]
+
+[[package]]
+name = "authlib"
+version = "1.7.2"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "cryptography" },
+ { name = "joserfc" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/authlib/authlib-1.7.2.tar.gz", hash = "sha256:2cea25fefcd4e7173bdf1372c0afc265c8034b23a8cd5dcb6a9164b826c64231" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/authlib/authlib-1.7.2-py2.py3-none-any.whl", hash = "sha256:3e1faedc9d87e7d56a164eca3ccb6ace0d61b94abe83e92242f8dc8bba9b4a9f" },
+]
+
+[[package]]
+name = "certifi"
+version = "2026.7.22"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/certifi/certifi-2026.7.22.tar.gz", hash = "sha256:741e2c3b351ddf169a738da9f2c048608ff7f2c5cc02f1ebc6b118bb090d5d55" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/certifi/certifi-2026.7.22-py3-none-any.whl", hash = "sha256:62f22742b58a1a33014a2b6b706588a8d7e2a88ae7bd1a6ebe8c992928483775" },
+]
+
+[[package]]
+name = "cffi"
+version = "2.1.1"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "pycparser", marker = "implementation_name != 'PyPy'" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1.tar.gz", hash = "sha256:dd31f52ea1086513bb9df30f8fcee9b8918323ae067a3d5b78bc826a000712be" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:baed1e86cc735622097354b9d1281406caf42ff42a886d29faa8e8d1630333be" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ca82be1a1d406ecfe1d25dc16cb33488e5a16bf4438c9fb590484ea29d92478b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:42e2f76b9455f5a9a844f770bf3e200ed3da0e15f5df3db9c31fe80b04b3d004" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5a59cc1c4442bc3d5c703bf720b51138d0bfc173618807c9ee2490a7541dd3d9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:9f8d177621de5cb38ee3e731eda45d421db093ec0739f46a5594babda7987a98" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:75f80557d1389eddbd0de2681f6a390a0c5338c31ddaa821381c203fc3fd50d9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:194cffa889098ced9976c3fc6340305e43f6303657d298da55366907c05c22d6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5bb4e7ea95dcd6a014a6fef62e62467d67d8e582326443f3d68e71d6320a9fcf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3d22a20b1fb1632cc72c22f95f7b0d2961c3e1c235f245ba4c606c4771035659" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1dea0e4d7d4f11f619fe8c1d76caf49e24405b4b5743c0e3be16a500ecd930c9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp310-cp310-win32.whl", hash = "sha256:7ce713ace7c0e4520535b42b77eaa742c16dab813978064913e5a3cf82973b41" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:a48d62ab9d6f4f98c983223a547af44be6ca3691074c31cecced6facd3ba2dc1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:c8d2c9fd1f2d16f780d15127abb050d13d1a76c03a4bd87d7e4980e45e511e12" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:398aff33cee2767e3e781d2554c54bd0dff386bb437581e0d8011fde1a942ec1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:154852545011f779917b11c78db2358d095da62a9a172b78ad0a583ee5adc0d0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3311ed60d36f83378794e1009ac6258bafbf81f7888b4caa7b35a521e3f95813" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6e192623c49c94421616a5778fba35cf0d5a8d000650c1967ef4448ee5cdd990" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a6e721d4b0e45d5b65e87534470e67b18dcd092c83f68fba09f152b9cbc061af" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:34e261f78cb6ceaaa36f42f2613f4380d94d9c759a9c73c769ee6e0247364632" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7225e4514edb64eb6740324353e0da0711954fd8d7da4576755b1c6e09b697cd" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df913725b79db7bcf03448f36b7bf8815363417d5b58deecf9305e3e30f0f21a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f5cfbc5fe74540d335175b656c725d74d90e3730c626d92575eea35029d9afaa" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp311-cp311-win32.whl", hash = "sha256:f8ec5e643a9a937f64e1999eb9f75d072263751912dc5cd06d3c85f8f44be7c3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:42f6930c31dc7f50732c9ae793c2786c7b6b044195967bbdde40bb9be81c4cc0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:c7659f22557c5a0bc4855cd635f55edec690cc008a40768527762cb9fb263455" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:c8c69575568085ba0b1b10c0249d779a214aea6f6522e949a0fc9fb0fcb449d0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f81b3b8f3d4e343550fa4baa0e479bba9f2d29ce9c2e9b51d1ce1718d7442fcf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:811bd1e21d32de12efca32393a0ab3f5133b54fce9bd44b8bd77ab07da14bf6a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:68e62fe11f30d5ca8289242866f0a5291402d8529ca2178ab8afc5c9694ae890" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:4a7c934f7360e8cd64fe9efadcbd10c7c6364f531e432b9a4bf5ccbc9e0e8b50" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:3143d81e29e1e20a9ce10901ec369012947876596f75a222235965f2b7ae832e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c1453022f490d2459a11819d83ad1d586e9ff65a12ac3e705ffebd46d3685dcf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:208f941bb9d18e768138677f0a6d2ce01f590df56043dda1df1535ac57c88517" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:210019b6c7cf07f081b4c54635c8cf744377001350e29cc0f81c4377b4797735" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp312-cp312-win32.whl", hash = "sha256:046bfc24911b37851ee1b51aab8bffe713d89c68c6a057b09484ce9fd5f69b4e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:f53e442b08449d42821fa4a4fba000095af9f62742a500f978a9f557ec44339a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:7bde5e4cc5c10140859842b9d383af292b22639a4dffb725314baf45968cef80" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:b5bdfd1c873d4e093aabc0ca84c4ca6dbc4f752afb5c86f146d9742580c9da2e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:31348097ff5bbe827ccc41795d4dd099d9f0625e7def00ee653c137a490c2a6c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:9d2055050ea716bd38b7f7f1579c275386646b4894c155a3e2f3cd62ed41b7c6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19ee6127ee34de7d83ce3d371ebc5ed91addbdcc39f9ab15ce4eb35a4e534971" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:6a8dddef476fab96d066d578fc88526767b836ab5ab21754e1d5bf3879c31c7c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f16c709686a78c727bbbf059f92b0bf41c6fc60deec706d2dc19f529175a6125" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:fcd22650c908d7b7da162bbfaab594a1227a15d1643a98c68b122ac642fa2264" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:aa9511c62d14da7aacc9b4bf51f3f697a621e83b2d6919008243c3aad168eea3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a931079504ecc49efed7744c476a5c343a92fabf66dec2db95edb1b2fdc770e2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a2d7755bef5a12ed488f4ef1f1b69ee9191d7396083b755a5d2295f6edb4768b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0bcb7e0f677f543555d2adff3bf19c05f66cdb4796e5ff602442ab2fe3c4ef7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp313-cp313-win32.whl", hash = "sha256:334644fbac4eff73d985a17a91226df55d0f394160c4cfb880e084c8f7161cac" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:1aa5645c30469b09530c4ebca77ebf8f17618293c58f8549cb1a543a50236e7d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:63bbfd5ded17c4840ac07cd8f1c21ba9d9708141f840b324f422f41b207e3973" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:7dbb61fe3a7699468030f71bbe5f8a0e326a151daa91beb11a6fc1f980c55e1c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:f24fb43132a4c6b4cb4eb029492919b2db645be6808d738f244fd146c03c32cb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d28630f5854ab07ab1fd4aba756de52326c82e6be15d414b12793f1975048b54" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:661c298b4821edebead0c91edd2b00374d67ad7c5a1f7a91d4442633b79d6a72" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58acb8ab8e295e6c5ea12f888cbb13cf21511ef2a3303a23f4325c29d17fe5c1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:456a61fa52d579ebf9df2e9552ead5129855dbaff6c1e5a9b1bc408809bdc062" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a4f00aa42f75d6e4595e8866e748cc1705adc0cddfeb2ca86d0d03993d63ba03" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b0431303acaea1089ad4b3e9ce4e6518193def1118d4073ca848635ee4ea2e96" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:64faea20f4e2613363a1a9b9c7dd73058f3ecd00133a511e72ad7c511658f527" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5c58fe613dc5e5336357eff555824a314d8e43282600435c8d1cb6a7a2fedd13" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314-win32.whl", hash = "sha256:1a18a57b58cfb21fc28d72e876acf10eaed67a1ed96226f92af4df681d571c4c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:3222ba5d678f80a030e6afbcc33dc1ae5cb45facabb61cee2c7016b8432fde48" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:ab36d55f9ed2d067327667c2fea18dda018eb628dd6347aa01dda6cf1f5d3836" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7750c6449dff7864bb9bb27ddfb0267756189201a3afc911d82b3caacd70dfc3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0beceaabe56af686895136a2de78db54ecd8e4046b236b8fd6d6cb61389e9bf2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:49cbc70e6542d4ccccb936558d1064a8012541e78f821f955cff24e357776c94" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e2d65b31f36619cda3999b78b2aa9632e76b78448e7a56fc4240824200e7c4fc" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:28907ab9bfb6aa13184cfc17c6b8e1023c5ab6fd7076d8c20a35e59fe04f8f29" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:51b31d1c98274844cfd7838ce00bfc27c7423a4dc00fc0772fc3331c2cc90676" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e7cecbaadb83884793e05828cee59b210b24583b9c7425d0ba6a754fe22eb4e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:25792eac27877609e7bb06d42ff88278a6624fff2ba9bbb523c09616b117e80f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314t-win32.whl", hash = "sha256:8ef53b2de9bcb9197d31854256575d59dbac0cba72ac627bb291ef5eceb74be4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:616f097f2fe415bc92a247f02e11f634e1f9e9a83d327e3c915c15089c87869e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ad2c86c495b899d862ea0f4b42891b8713a3bd45dd4105c7fd51c2a72f39f3a5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:dddad92b554513a31f272570678ba307fb9f618f05e3d4a5eacafff9eae03e1d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:da0e573f9f97159390c89d9f1a9e41908b66d408cc5b58d08cf3847d844c531b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:fb92203a88b3d3053034db775110081c49d28be6551923805e039924093761e4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2ae64be792b8966f2c69538199728b290e34726562896df1e5dc8ffd8d8188e8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:507a24c282e0f42f8ed737cf048572cbf580468da5555764a8331735e9c736b6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:246fa40ce8645a614ff682e0b70f37134e460eaf93a775e0cbe3cca585a67a80" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:471cee653ae88de62096552e6d24ccb4a5adb8c8c9f10b5054d0122c15bf2779" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aeae0e330c9f6acd681f647d46cefd30c29f93e3392882e792e82080c9691399" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:42a494cee34437f05546455144f2b5d9ac09b1face62bcfce597d2e521066688" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:cc572dace3f60ef98d7b12ff411d20f5362feb31a0439eab0085bbfd349982d7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315-win32.whl", hash = "sha256:4f42141fc14250de6dde5ee7ea4432be017252d91f19c5ad043c084cea629cac" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315-win_amd64.whl", hash = "sha256:e6e8cff14d6fb0be70a09c0bdc58096f501952d04624ebf867e0e56da2df8960" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315-win_arm64.whl", hash = "sha256:27350daa11d4f10c540e6e89dada4c54feb7256ad03e9a4dc075ebad7ba360d1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:c26608d2222fb1e94487e4a387d85f13eb55d5ed725cb25a0c589ac4ee60e7bc" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:4be96343e422f2dfcd12ab5c9f5aebe03f82f737c6bffeca6830b3875cb44aab" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:937c0052c05a31ca1daf18de3158eed4dbfcb9cc107adbea227728d647be701e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:df423d40ee8654634421812bc3b196da3f9bd7d32929da813f8394c4348a5358" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:a730a083190634c65cca36ba5f489531576ebd79bcd5c8e172130f6453127231" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:363e05fa78e15116c3c32c210ee36884fd6b9afa6d440e47112c3bd511d64cb6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:770de9db11e84213beec501cfcaa013b019820ca881e03344dea5844f7876d94" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:7da0c5eff80f0197f3b3d1232ec5a682a9325f4ae9016a78f5f5ca35f9ced1f5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315t-win32.whl", hash = "sha256:06c72bb76605a4b0cd0aad6930b69d4baf7dd5d806cfc409b824191099700e66" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315t-win_amd64.whl", hash = "sha256:d9c275eaacd24aa73f94ffd6de08fc3f932424d8b6c376f4bed7cde376fe7bc3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cffi/cffi-2.1.1-cp315-cp315t-win_arm64.whl", hash = "sha256:d18e5ac0f2f03f4f518d3e23db0f0cad7faa1da8620e9c09461d443bbf6e6692" },
+]
+
+[[package]]
+name = "charset-normalizer"
+version = "3.5.1"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1.tar.gz", hash = "sha256:6117b84ea48435e5356dc737f5121485c30920ba43375fa7b434fd753df0eac3" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1ee1e296209fdce05b81b663250eefa02213a2da7b41bf26f7829b8ba3545aa" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9fbdce1e47394b09bc9f26ab117dfc8d6491977a11d86f592bb42c779db2fda" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:00668ebb0609751758682eb0b5857e7c35b9f00e84dfdef062e103244ec94d45" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba2f37ee79e6338845261a3c5b1784e5d1acdff2c0785b284f1b633033d136ab" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ce854f5f478050ade5a238731c4ca985a7d3b3cb53ff600a9b5c3b689b5f0a7a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:96eefc178f8636b9c760c5829345307fd81cfae9ab1e80997dbddeb0f54ee9a3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:366ec70f5547c640d3ce1985722490f23faf4eb5216a7eeba78277490e78dacb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:950f23cb393f85543777b0433f082cddd25b51ab398eac7971146495679efe5f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1dcc36dcb96abc02236e182d17e0f71430152a6c2c7447421da2d2dc144edea" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:07ffd07412fc5d5e84cd8952acf9ff7e4ed7a708e69d1bada19d8ba91711353f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:f5542f9b941279d82d41eb0aa9f98eba36fe4df5c7086c651df7944935b37182" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a545775cfe815855ea32d7c27731d79da358ef2055b4a25830231b1622dd18aa" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:494b70049a4d69aec6e8137c13af4cf8db8c9f9820a1392ac293b0dd2987a818" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp310-cp310-win32.whl", hash = "sha256:94fbf1c0c6cc0d3d5e50f9a9313a8cdca90dd696d34b381cd1704f8c9e939f20" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:be47f99644b208bff7766314013f9acf57b056b04191d570d68ad14022cf5b1d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp310-cp310-win_arm64.whl", hash = "sha256:a6d095662e73e74f0a49988e0593373e243e3a52e27bfeea0a859e88acf4a0f5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:eda059b6bc8bc0812d626fd91a7ce01bf583df0a61296eff390fd94141a34e30" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa2bb0b37202dca27175591f761108b5d34096ade1191ffe4808bdf6b1571488" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0b2b1b3fa5670c127b246df1d0c059defd41f689a868a3b9d79df9b1cac42d22" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6e5e4d73d588ca5ed09df1b7dcd1b203d1df3c542e3f50d126c947d432b10731" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b54e7e13267d49ffbfe68e25b3cbd774dab38fa37238f71265e91b36146eb21c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7b742bf31c88566b4bb6335a7f393bb322e580b6bb98df7bd0c25e6e3519ce8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6ba32c4d2abf1d2fe7cf27d280f4cca5664233b0f885549c7761719eb977f486" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0722590aabf9dc6a6c0343d523c05458fa2b5047dbe6302fd526bb570600753f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:aa1099b956fb795e686d073568f6dc002a0bb89765ea6d5b055dd7d9bf1b116c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:bd6c173f04743d483881bffa1478d5a4624475b8cd1d2194956a75548e191c18" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:f298e218441525d3794428b4c8b8fb8662c6d3ea79925d4807ee6b9a96a3bca5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:6e2912d4babbc65196ac13c2f53468dc57fb8b9c25ef913e8c59ddf7c6dc0e1b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3d27167433c0d5f18dc850f07d0b3816221984fecdc405d6c157a6f0b8f8e9e6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp311-cp311-win32.whl", hash = "sha256:ac00177c4831ffa650f8609e4bdddd5fe09c03b1c0c47acece7e6ea20421598b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:f9b1e28d0e8dbfa858abdba91d6b547beaf2df1a59bec6da6faae7b96a4991a9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp311-cp311-win_arm64.whl", hash = "sha256:ae31a1a1db2ee6cc2942fccaf695c934bc7f3db9f2133a3fef1f367cf1a4ab10" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:5b6d1386bf0096d26d3a863dc0a487a5b4eb9aa93cf5ba69683d29dde6b9d60f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4582c27e8c889d64811987b5967fbd3ae0c823fe1fd933b543d55ac20bb475fa" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1d1c7a53a6c2103925cdd6d7229f8c567379f211c869793df679f2e9f738c369" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e6621fb2a4988d6e53eedc455e5903e2679f3967b8acb3d639f1b63c14a2e893" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7c0c10730342b0c9b35dd1d619beb8214e520bd96a1f870f452680b238aab3e0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b9af956078716df40d985fb0dfeb2c2120c5ca92ba4ff4b388acfd01cdc14d08" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f9f8405c2c758532c74fed975dbee57be1f31a6e865c031870c79a6ed3212ada" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:96fef3e886d6a9874b14f27fc193fbdc69d5d8035783d86aa4e1cea594e695f9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:5d8531a6569d025f68e2321e7638fb7978f23db58e5f69f56913837aae03816e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:aae2ee51122d3ae968a3837d97dc24a0aeebb0dea23694422cd172bd30017cd6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:7235dc28fc6dd9d832ac7c7bce95367dedb85929f17368a0c2bee1e080b9acbf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4abdc5f9ad448c1ecbfae2974b820535d6bc6e7eef63babbab3d81cf46968c71" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ba501e667c17d8411f98e67a022d9604ef179aff0e459b7e292c796837c13573" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp312-cp312-win32.whl", hash = "sha256:cfa1c0cc3a8f9f53f1243a5a99ac36fd003880199383b37672e86ddda9cb07e2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:3617ac3cfd8b9888f145ad89dd6e692285834b0201c6074a5eeaad3fd4d668c2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp312-cp312-win_arm64.whl", hash = "sha256:88e85ab89cb822c1e635f51d6d32e488f94e002e70e2f492bdb8b945543f345a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:4f298bdadb8f0b9e5672877f647d1be9373ef5320c9e2f049795e26cad28b6a9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-android_24_x86_64.whl", hash = "sha256:88ca277405c2d3b71c4e1c2ee0e7966e807bcba86a69d11e19ba199d18ae4491" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:9362dd90aa7dab48c0054a21187791ccf05473f7dba5d92b8033ae62164675e7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:977cdbd483a9cff38179bea4fd754289a6f2195c7abd414aba85410b3e66cc5e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e90251c0c7bdd54a100a0dce3c07b7e637278c93af29dbf78ebb89a58c4bac7d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94d78ecec2605a8d0398b0f365d5f12a63248438516f5dac536a5eff7337df4a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d59b75732e9b6f27388e10c14b0259cc5f2e48c78627d185e6a177b58ad3cffe" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0d929fc574b4d6fd9e7c0f5c2ede8716a41911923aa7fa5fce38e0818aa4a1ac" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:394fea06235c8543390050ed5f529187074b029fb027213f6c46ac11ab5d950e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:62b55f6722735a6c472f88361cde6640608773d9443cebdbb51abf436a1fcdd3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa48b1b63d639f9483e0633e092f5851e2348c352f1f9bb6c8182f87884ef876" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c71fb0d56c920c269cd3e2e3fe7c610e3f1fdb21a6ce60efa6430ff63676cea6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:485a0d363cafefcd2538a73c7c838daa2035f09b2c9f9b5e3133f80c6aeb84c2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5c0ea61a470e070686aa30892fed79e297d2c8d0ab46b8bcdf027d38c51da591" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:90b7481fb62fbe172c558bc6fd1c4c98d82004a54a7551f20e11ac9bf0b8708c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:35fe081843b35aad20ffeccec3eeffbe637b15d14f3fb22cc1b59cd8ec17e93c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fd0350afdc3aabd5576f60ea109228bd5538139713c7b094c5cd27c73a98bc6f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:9d9a0dc7cbe9bec24c3f767c9122c41fe5a1bc43f47cd099d00d393e09769de4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-win32.whl", hash = "sha256:d63600d620ad0064c3a748b950ac5ea38a80190e5498532efefa4b7b3f1da1f3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-win_amd64.whl", hash = "sha256:aea996a6aba25260827c9ea511d1addfde2da9eb686ac961838509086188b7e6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp313-cp313-win_arm64.whl", hash = "sha256:fd0a274c0e5f9a21565cd9d3dd749b61f96b7aa1e20a93aa1ba4029518f2e5c0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-android_24_arm64_v8a.whl", hash = "sha256:774d157f112367ff4abd29019f38f023c24e00e56edc7829c20e358a5a913ad8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-android_24_x86_64.whl", hash = "sha256:26422d45fd13551cf564c58932f7d72b4f58b93b0fcf18c35ba6be12b46bb102" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:09a7bba9f739468c8e78c36a75c33768e53cb1959fc638f510454c14683f00d5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:4c9548dc78002099910abaebc0a72ac58b7d30931869e0351c09b507dff4ece3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c428c6c31eb5f4277d7f8eccaf767fbd548ddd5ce3c8b4f4cbbfab3d96b5904c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f06b7eae9dbe77fe1d644ca244dad508de8d302870a43f3c559b521270938a0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6b7430cf5728e68f6c462254009a6ef4086e1bea43cf2f57aa9c55fb4f50ff96" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab743e9bc90c1f73552ec33e10e3331315acd2c397b36065b591b0181de533cc" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6f7deae3feb4edfa2efaf7c574fe88cbf055038a6abdb40188e4fff66d5699f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15f024313246a4ed976c60f440bb8d257815513a681d212ff74fd46f7d715a90" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:823f82903d189af463d7df250ef1f7f696f3cee08cc8d91deb565e8d425f6506" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:01e93745f7f219b703b60ba7afead36cfc4242782be5af484673fc500df12da5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:329fc3ccb63ad22d867d84c2adea759a64079a37ba4a343433b02c7a2816871e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:bb57753e36e4855b8ca375069482250a6246372331a3e4f3407eaebb007443f5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:fce8cbd4997efeb450bd298b54f755dcdff18d496f7a5ddbb4867c6d7c88fdc3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:6c9cdde8becb25a7fde49924511aa2644d6f8081cc8df8e9452724303348d8e3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9ac4444d8d4fd4c4bd08bf451ed3167aa9e7ec6cdb41b648794f1d1103652e36" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:f03ac127268b43ef4fe9e6ab6794a6794b49485a0cc0c1db79876d2f33f75bc7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-win32.whl", hash = "sha256:1f5883d77fd409a261abb5dc8ccbe335720d798b1de4abb3b1d47ccbbc76b53b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-win_amd64.whl", hash = "sha256:c658c50ac0c98cd755a2dd50b7977d3bca7df401dcc47fbdfa87db53ef7d4e8b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314-win_arm64.whl", hash = "sha256:4bea7f8ebe90bbd7f0e4a2de42ca6924ba23e3e76418c408ff82f1d46fabd687" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:fbc597639158fd7c14d55e808718848319540f51b0e6746e3eefa59723a4a348" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e71c909f353863b2b89c83de2ebed71ea6d0df8a6ef65a128193c5e650766bef" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7ac76cf9afd34929d76eb7fcb63be476a4853d8a96f0dcf2d0db68a0cbdf9885" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a3a370082ce34d0612f421e15fe011c53bb1feff21a26d06ad4fb244dab5a375" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:256dd4d85d9e4dc595e2bc983c980e73f62ddeb3165c58b4c3dfe78c5c8548c1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:58d4aa13a59c969dbfdf9e6a9560e242cbfd9e8a8f50c2747714df1a423adf65" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0c6dfb5ca6723eeed15aa8e564a014d69fcb8812f94eef11fe3631e0508199f5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c010f5581d9c612804cc59fcf7b524b707fbcb72828551237ab545bb5c7034af" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:52ec005752a56ae79547a05c0139ca2501a0c866390b6115008456b9f0e7cde1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:2bced4061f000f7187254a02ad3433ae17eaf991747ceea2f478422590a5bba9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:9eea3ab2597a5e65fe65296e2d6a84570845a6b55532d90333d740d48bbc850a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:496846868fea80e479324862fa877f02411f2fd0f83b79ccee2607aa68b2a032" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:85d5855daafc240cc045c026d7a15fd198a09b0fc8ff6f5ecbb5297b509cb11e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314t-win32.whl", hash = "sha256:58d3e12c88e0950bca850ae1f7c256055c097639c2edb9eb123af9807d8b15e4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314t-win_amd64.whl", hash = "sha256:acaf604462bf330b0d07e7a07c1d6e4adac79e5fb13e9c5140590542cafacc00" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp314-cp314t-win_arm64.whl", hash = "sha256:fdb8a068947befafba9952162645dc2fecaeb400e64584829ed5e9b2fbe21a7f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315-macosx_10_15_universal2.whl", hash = "sha256:9085f87b0e38a2b92b8923059b4e8789fe40d9279712d15dcc670048d77079af" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2679de311c7946dde5d3b6f44941844133ff5c7cb86099c0061ab1e8901c20a8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:baf3775a2635e5a11fbd5e4e64ee69c7e86875d224a5c72aca4c141064589a90" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ac8c94b6539074e0f40899301273ac8402b9b3e01c7b7ba269ff30340aaaf20" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8fe532b3c966d1fb794e0698e4589d0444017ae77fc0b31edea13c0e35bcc449" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5c84bec0ab5ae0c64bfe73a7d2adcb5ce73b467523fc27fd6a28ab2aa6cbe35a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:854066be00447fa8de2ccbbe893e2ffc4b123ef16d897af794c1e18bd4a714b0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:21b82d8082f6f5e7f456ef0bd16323d08de1266efbfeb476e64b2a91d1471a4e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_armv7l.whl", hash = "sha256:838648accb3a7fd9803fd45c87bce8509648eb0c11bc34e216141300977244f2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:195ce897c6153c0700078142cf8efe3e6454ca4cf4357499e4078dfd83396626" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:978eab16f55b4ab2c2a745be9a0a840bf8f09a7f227d9c76eb30214d078865a5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_s390x.whl", hash = "sha256:cc0329df4caaceb950d2f580b5ac716a377f7059624a0bafaeaf8a218c6ed774" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:687c9ca3035544b113bea2055e180af96fb63c0c476e22a9180f51925186e7b7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315-win32.whl", hash = "sha256:706bfd38730a5ac7a365793269a00f4e988178cec121391f4248d84ad8c972e9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315-win_amd64.whl", hash = "sha256:92caef967d287a407085d61176fce4012b1dd62daed4eb6d5ceb26d3d2538712" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315-win_arm64.whl", hash = "sha256:5fc45d653ea8c9a20479167e11d4a0f8cb2fa3470737ab6f9c827532313187b7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315t-macosx_10_15_universal2.whl", hash = "sha256:59171c6e45bf07d0d5cab3b0bf81d945035530f6873398b3b531c31184d46663" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9dbdd9205662134957cf0c324f639bdc5031c0ca056e2369e238db75187c0f11" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e4b018dc5a0eee4676e38fe84a47a427816c590b93b55d9025274ec4d6ffc2dc" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ced3fdd71aaa83ce593746c2edb42b7a59cb4c19c8b5c407781c72e493aae55a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:19a3dd5aa73cef1c99687c4fc57db016a9c17104ae1185da88ba566a5d3bebe4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cc5d36d96478aa9c60654bd932525bf32964c62a7281eafdf16d85003a8d6004" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:04368edf83514385ffc3e1cfd4546e595f4f1272dd23ba437a93a9cc3741d47b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:9b5db6052055d34d41230fb78d7c439c23dc536a9896f6cb039e8dd92cfc1263" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_armv7l.whl", hash = "sha256:252d099029bcbea642f2a06c4ed5046bdf8b5a8150b64afa5e027e88b106e5ee" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:6199d5606e2bbf2b096cf64d03f8b6790c91081d5ac866b8e7bb6422738cc60c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:77efcff2b23071c349402ac1066667a3d011f62398d81408c9b88ad991747c9e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_s390x.whl", hash = "sha256:a5cbd90ecf0fc62e64726917ad083b73001f0563657a87ec3c0b504e277dc90d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:4d26f14f041e83dd8edfd61f4cd4fa7285d31798b5bf1f28e70c367ba6c41d61" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315t-win32.whl", hash = "sha256:ac13b004224fb341e1e25a1ed5e19d32f57cdb2a403e01f003b46f051a550f6f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315t-win_amd64.whl", hash = "sha256:35aea775dc2bd5f54cd84a1cd2696cc3207c479cb9cf0bd346f0d343e4300ddb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp315-cp315t-win_arm64.whl", hash = "sha256:fb78f6e7fcd8ad785d28cd577168bc1aaee827b25bb8755638f694794ea98f0a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:41876ee62a3dddf48ff1121ad8f0798032aa03f2fd35f21f34a4cab14f18d8d2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp37-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a6dac12ff6b846103483683f60c5f8fee205121adc58ffd87e90a90a3af69e99" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cee5dd7c6fb5dd52a0fe2a740f9bc6e3593f5f8b1788bde49de02086f30182b2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp37-abi3-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:343fb4f2821043bd87095f7b08a1a181febc8e36ac64212143bbfd0a0e1bc235" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp37-abi3-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ae4a097991662cd4fff0ddc74e0fe7874f82e00042fa0ea00855645ed0c79598" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp37-abi3-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4b599739b93b2cbeded49645ae3c8d1405c29ddfbceac1545c87a3f9580a9e96" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp37-abi3-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b39b69b347e5e47a3b5b8cfc005c68c1ba347474e3960236c4944a8ecd174962" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:a2028475ba855475b8b4d3cfeb4994269c967aea8b9892dfba907f4263a863a3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:36047af20e17097c3bb9476c2b7655f2f7aa51322c0ba58c07695bedf755a950" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_ppc64le.whl", hash = "sha256:4c4fb141a727957c93edfe5c32a26ceb6b5f6461d67146e2d39f51e16170bea8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_riscv64.whl", hash = "sha256:2f293479cce755c75f1697e87c409b7ae4c555c7dfecb6e988ad13abba943031" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_s390x.whl", hash = "sha256:3588e376b3ea2eea84976f67273d679f229e24c66dce7b82ae45aef04ff6e072" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e199fb99720074809a7720f1c0b4d919eea8b87e88713e0f8f602f7bef543d9d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp37-abi3-win32.whl", hash = "sha256:dd732602a7009217f658d5863d12d79d373a4de0eebc111094bcdd3bb8e0a6cc" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp37-abi3-win_amd64.whl", hash = "sha256:70055ff39b97c99e7ae40ea3e393fb62aa2e44dbd9b29f8d14f42fb0025c3959" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-cp37-abi3-win_arm64.whl", hash = "sha256:87e4f41d375c0b9be2fb5251aee4b8a689169e134535aed81bf085c3b647451e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/charset-normalizer/charset_normalizer-3.5.1-py3-none-any.whl", hash = "sha256:6df0ec430f9a831772c23ca5a224cba36517a58a84bb32c32bb59a9fa67c47f6" },
+]
+
+[[package]]
+name = "click"
+version = "8.4.2"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "colorama", marker = "sys_platform == 'win32'" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/click/click-8.4.2.tar.gz", hash = "sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/click/click-8.4.2-py3-none-any.whl", hash = "sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76" },
+]
+
+[[package]]
+name = "colorama"
+version = "0.4.6"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/colorama/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/colorama/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" },
+]
+
+[[package]]
+name = "cryptography"
+version = "50.0.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
+ { name = "typing-extensions", marker = "python_full_version < '3.11'" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0.tar.gz", hash = "sha256:eeac2acb5a20ed25e0ad6d1df9891a520b78b404266b6d11778f25d5d691a6c9" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:031e2d5dd4bb9caa3ca9c82e5a197fd8ae680232cee62603d1a813f3f07e3d03" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fd9192b7b70c573d7f214eb1ae35e00d359f6f5e4b27c7e21e30de1fc6204645" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:06a32a980526a6ab9a4b9bf8f7385800791e2bb960903cb6b530e4817509a3b7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:a1b30560f2acc95aa8b2e06e716a13dbfc97314747b80d9707e307f77b40d6b3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:8d89f3976b10b4ce31118de72329025f70d2c6ead14a8217c5514dd2c6d5a78f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b42a28c1844fd9de8f3f7d540e36b66f3a9c83fceac7170ebc7a6a19edd9dcae" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:900131fafd8aead39ac7dd3a7e833be754c17a95cfd91221636949fe4eb0aa8a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:07949c449a1abcf60d1ee6e88956d89404c7df3c8258f46589e912988e551987" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:f89831ef99dd7dd169ab06d63a831adb9e20a87aac6d380266bbda5823349169" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:82148ec5bddac30b51a5b3c1945075f896fa022cb93f8e4a01e9f6ee95292c5f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1489e263a8048bb8b6a8bac662eb2d402ea5d2b7b4699b72f385f1e2772db105" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:7cec5b856506da6defb290f30c9ee687d5f5e8cb0bd3f6459dde43b0b4fa40ef" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:bd1c592e4d5974f0d08d4888e432157adba757c66da0246918e43677fafa2d30" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:49e7d93abdbd2990caced757e5fade25302f719c3c8fb6e6fff2dde98999fc41" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:19736989797678c6af1e55cd49055cdbcb55d8f6b5583ac5335f933aba9101dc" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:80b63928fa35083b33966ce1efb70e5b9607181e49dcd1c22c8c005e319f667f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:d58c3db7cd6eed54e6c06744db55456b65ebd7492ddeae9c1e93cfca7aa857d3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:df2a58a472f332225671c35b0a830208b86d004f82baa8530fa3782c85646533" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:11b74db56cdbe3cdee6e3f6982ecb70334fa10dce99ed58bf7894aaaa3b2a037" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:f59e38625469987d7ef6d495323c55e7db6c212eaf6112267e0d3b565a2e9c9f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:ecfed7367f965a0328cfbdd70da860f15441f002f613185668c6e6ebf5a0ac11" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:9aa87839c383bdbab6ef865787a1fb877af8dd03464c4400322726feaaadfc6d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:6ba6a53445bd3cfa809ef3ef5f1589aa6ba08784a1d962bf47d0940e871dab1c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3f5735ffe4996d28b809371756219f5354864902a3b9e7c0b9ee87041209fc9c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1b4a266766514614f8aa60416e71f2fc6e575d36e7bdc90f644fadb2f4b75b95" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:12b9c6996425c76ea6c457ace4f3073e715b8c545add07cd1a8f3a4f90691269" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:ccdc4a71a4dabae05de219404f9f4abc38e3b58422177ff93d0da05967dafa07" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:910e1d2668e7de9648f2bcee30e180db2a6b15c30f887d7c4c93ddf96e3992e3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a91296cb61e8df6f86d0c19cc4068228da256bf59bf86049fbd821084565327f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:e722f16708d854fe924790e051061f6704a472c3bac347b6fd88033ea8dd0dc5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:d764dcf130c428ef66786f866dd750f53182bc608813489915e9fc106bb0c82f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:105110f43a471dbd0060b9c9516cb8a6a79233631a04cc2ba16f28323ac6e025" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:828743d939e9629bc267b8e2d08d8bb67cd4319c771a33d4b18b22dd8fb7440a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:2a8183b489dc1f7f80f135780fadc1108f14b31b8a40411c7a5b17425f65f28b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:6e7d61120573a7f2cd94cc095f9e81f6967c61ccdf194285aa143ecec8e0b708" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:37fdb0d0111f1e2ff07139dfb79f1b49531f8e213c46f1163dd7642979b58c47" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c87f62a3d3b9888ed0fdde100ec06aa61ca9cd44bad9057d1dff9a516b5f5bb9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:65c2c3add92b45fd0709db8594536aea39c2a67af0e27ffcf049c498501140b7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:d24fead1d4d076e1bfb006dcec392074a3cd8d7b4fc8a595aa64073b2b7a96ba" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:5e34edd123674534acd70147f0ca331eaa2c74e6325fb2028c886aa26ba0b68c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:8eb5e1172eb569ea8a872796576e6a67c276351728b6455d5beb01242b027c6a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:910d11e1a385c654bf738bf3e6b8e6ed5de0f5610fcae2be9e5b398d8081d20e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:62598a8a57f815db4c6259a4e97d857dab56697e7de8e8ab02352ab74da1995d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:07479a1cb08219ab719147e742e76090c9c773321959bb94946fffdd397a6437" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/cryptography/cryptography-50.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c99c003e088647b8a5b7c145d6f78c335f6348332b62e142d411c4b63d1460b9" },
+]
+
+[[package]]
+name = "distro"
+version = "1.9.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/distro/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/distro/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2" },
+]
+
+[[package]]
+name = "exceptiongroup"
+version = "1.3.1"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/exceptiongroup/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/exceptiongroup/exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598" },
+]
+
+[[package]]
+name = "fastapi"
+version = "0.141.1"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "annotated-doc" },
+ { name = "pydantic" },
+ { name = "starlette" },
+ { name = "typing-extensions" },
+ { name = "typing-inspection" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/fastapi/fastapi-0.141.1.tar.gz", hash = "sha256:e8822fc40db1e1858054d7a949a888695bc9bdce70139178e33bd2871a453ca1" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/fastapi/fastapi-0.141.1-py3-none-any.whl", hash = "sha256:bfb91aa2d334c61cb35ba9a116fc123b3d3df31640b801cf57a7a78ec3f603b3" },
+]
+
+[[package]]
+name = "frozenlist"
+version = "1.8.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b37f6d31b3dcea7deb5e9696e529a6aa4a898adc33db82da12e4c60a7c4d2011" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef2b7b394f208233e471abc541cc6991f907ffd47dc72584acee3147899d6565" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a88f062f072d1589b7b46e951698950e7da00442fc1cacbe17e19e025dc327ad" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f57fb59d9f385710aa7060e89410aeb5058b99e62f4d16b08b91986b9a2140c2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:799345ab092bee59f01a915620b5d014698547afd011e691a208637312db9186" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c23c3ff005322a6e16f71bf8692fcf4d5a304aaafe1e262c98c6d4adc7be863e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8a76ea0f0b9dfa06f254ee06053d93a600865b3274358ca48a352ce4f0798450" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c7366fe1418a6133d5aa824ee53d406550110984de7637d65a178010f759c6ef" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:13d23a45c4cebade99340c4165bd90eeb4a56c6d8a9d8aa49568cac19a6d0dc4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:e4a3408834f65da56c83528fb52ce7911484f0d1eaf7b761fc66001db1646eff" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:42145cd2748ca39f32801dad54aeea10039da6f86e303659db90db1c4b614c8c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e2de870d16a7a53901e41b64ffdf26f2fbb8917b3e6ebf398098d72c5b20bd7f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:20e63c9493d33ee48536600d1a5c95eefc870cd71e7ab037763d1fbb89cc51e7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp310-cp310-win32.whl", hash = "sha256:adbeebaebae3526afc3c96fad434367cafbfd1b25d72369a9e5858453b1bb71a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:667c3777ca571e5dbeb76f331562ff98b957431df140b54c85fd4d52eea8d8f6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp310-cp310-win_arm64.whl", hash = "sha256:80f85f0a7cc86e7a54c46d99c9e1318ff01f4687c172ede30fd52d19d1da1c8e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:09474e9831bc2b2199fad6da3c14c7b0fbdd377cce9d3d77131be28906cb7d84" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:17c883ab0ab67200b5f964d2b9ed6b00971917d5d8a92df149dc2c9779208ee9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:957e7c38f250991e48a9a73e6423db1bb9dd14e722a10f6b8bb8e16a0f55f695" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8585e3bb2cdea02fc88ffa245069c36555557ad3609e83be0ec71f54fd4abb52" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:edee74874ce20a373d62dc28b0b18b93f645633c2943fd90ee9d898550770581" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c9a63152fe95756b85f31186bddf42e4c02c6321207fd6601a1c89ebac4fe567" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b6db2185db9be0a04fecf2f241c70b63b1a242e2805be291855078f2b404dd6b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:f4be2e3d8bc8aabd566f8d5b8ba7ecc09249d74ba3c9ed52e54dc23a293f0b92" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c8d1634419f39ea6f5c427ea2f90ca85126b54b50837f31497f3bf38266e853d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1a7fa382a4a223773ed64242dbe1c9c326ec09457e6b8428efb4118c685c3dfd" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:11847b53d722050808926e785df837353bd4d75f1d494377e59b23594d834967" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp311-cp311-win32.whl", hash = "sha256:27c6e8077956cf73eadd514be8fb04d77fc946a7fe9f7fe167648b0b9085cc25" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:d4d3214a0f8394edfa3e303136d0575eece0745ff2b47bd2cb2e66dd92d4351a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/frozenlist/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d" },
+]
+
+[[package]]
+name = "google-adk"
+version = "2.7.1"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "aiohttp" },
+ { name = "aiosqlite" },
+ { name = "authlib" },
+ { name = "click" },
+ { name = "fastapi" },
+ { name = "google-auth", extra = ["pyopenssl"] },
+ { name = "google-genai" },
+ { name = "graphviz" },
+ { name = "httpx" },
+ { name = "jsonschema" },
+ { name = "opentelemetry-api" },
+ { name = "opentelemetry-sdk" },
+ { name = "packaging" },
+ { name = "pydantic" },
+ { name = "python-dotenv" },
+ { name = "python-multipart" },
+ { name = "pyyaml" },
+ { name = "requests" },
+ { name = "starlette" },
+ { name = "tenacity" },
+ { name = "typing-extensions" },
+ { name = "tzlocal" },
+ { name = "uvicorn" },
+ { name = "watchdog" },
+ { name = "websockets" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/google-adk/google_adk-2.7.1.tar.gz", hash = "sha256:0485bfba1a04960a3784eb67531491475be1a3f8acefcc5c880a906857ecb3e2" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/google-adk/google_adk-2.7.1-py3-none-any.whl", hash = "sha256:cd21e37c9846a80086fd880924aa5548e625ef85178122b40cda81ef5316129f" },
+]
+
+[[package]]
+name = "google-api-core"
+version = "2.35.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "google-auth" },
+ { name = "googleapis-common-protos" },
+ { name = "proto-plus" },
+ { name = "protobuf" },
+ { name = "requests" },
+]
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/google-api-core/google_api_core-2.35.0-py3-none-any.whl", hash = "sha256:88ce7a11146e1ddd331f7d2fd379787eb7e9015c34c6ed681e4f5fb8af3615af" },
+]
+
+[[package]]
+name = "google-auth"
+version = "2.57.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "cryptography" },
+ { name = "pyasn1-modules" },
+]
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/google-auth/google_auth-2.57.0-py3-none-any.whl", hash = "sha256:180dafe015cfb62193bea26b677500fab5b9fd51a1e825ebf3ad9b182047ae59" },
+]
+
+[package.optional-dependencies]
+pyopenssl = [
+ { name = "cryptography" },
+]
+requests = [
+ { name = "requests" },
+]
+
+[[package]]
+name = "google-genai"
+version = "2.19.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "anyio" },
+ { name = "distro" },
+ { name = "google-auth", extra = ["requests"] },
+ { name = "httpx" },
+ { name = "pydantic" },
+ { name = "requests" },
+ { name = "sniffio" },
+ { name = "tenacity" },
+ { name = "typing-extensions" },
+ { name = "websockets" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/google-genai/google_genai-2.19.0.tar.gz", hash = "sha256:d8f4126643793a7de230c396bcd142d21c948c8bb57507580e152549a7a41d9d" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/google-genai/google_genai-2.19.0-py3-none-any.whl", hash = "sha256:36e0326dd886b52ef765be4c46042732b46b21f637abbe060e3db7c3de23974c" },
+]
+
+[[package]]
+name = "googleapis-common-protos"
+version = "1.75.1"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "protobuf" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/googleapis-common-protos/googleapis_common_protos-1.75.1.tar.gz", hash = "sha256:d3042c6c5a2d4e67113104d6b6818b59b6bd92a197f2a91508e801fe815cf071" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/googleapis-common-protos/googleapis_common_protos-1.75.1-py3-none-any.whl", hash = "sha256:28a1934bcd33b9c9da66ac301a0a4227e3367f095a17d0375cb98f0a09d93b79" },
+]
+
+[[package]]
+name = "graphviz"
+version = "0.21"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/graphviz/graphviz-0.21.tar.gz", hash = "sha256:20743e7183be82aaaa8ad6c93f8893c923bd6658a04c32ee115edb3c8a835f78" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/graphviz/graphviz-0.21-py3-none-any.whl", hash = "sha256:54f33de9f4f911d7e84e4191749cac8cc5653f815b06738c54db9a15ab8b1e42" },
+]
+
+[[package]]
+name = "h11"
+version = "0.16.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/h11/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/h11/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86" },
+]
+
+[[package]]
+name = "httpcore"
+version = "1.0.9"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "certifi" },
+ { name = "h11" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/httpcore/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/httpcore/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55" },
+]
+
+[[package]]
+name = "httpx"
+version = "0.28.1"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "anyio" },
+ { name = "certifi" },
+ { name = "httpcore" },
+ { name = "idna" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/httpx/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/httpx/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad" },
+]
+
+[[package]]
+name = "httpx-sse"
+version = "0.4.3"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/httpx-sse/httpx_sse-0.4.3.tar.gz", hash = "sha256:9b1ed0127459a66014aec3c56bebd93da3c1bc8bb6618c8082039a44889a755d" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/httpx-sse/httpx_sse-0.4.3-py3-none-any.whl", hash = "sha256:0ac1c9fe3c0afad2e0ebb25a934a59f4c7823b60792691f779fad2c5568830fc" },
+]
+
+[[package]]
+name = "idna"
+version = "3.19"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/idna/idna-3.19.tar.gz", hash = "sha256:5e0811a4383b21dc5838069f801c4fb62113b7447663d2530d2bd6e77b49bf15" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/idna/idna-3.19-py3-none-any.whl", hash = "sha256:815e7be7a7806d54abb586dc943addc79e8b2ee16915059658cbeff4b1b43bf4" },
+]
+
+[[package]]
+name = "joserfc"
+version = "1.7.4"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "cryptography" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/joserfc/joserfc-1.7.4.tar.gz", hash = "sha256:b3bc561672ae541b17a9237053b48a03dacddd92d68047b3ecdfb4b5714a88ed" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/joserfc/joserfc-1.7.4-py3-none-any.whl", hash = "sha256:32d46c2cd5e3203c13e87a6c61333cab310b1ba80cd54b4c4f386a848a122463" },
+]
+
+[[package]]
+name = "jsonschema"
+version = "4.26.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "attrs" },
+ { name = "jsonschema-specifications" },
+ { name = "referencing" },
+ { name = "rpds-py", version = "0.30.0", source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }, marker = "python_full_version < '3.11'" },
+ { name = "rpds-py", version = "2026.6.3", source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }, marker = "python_full_version >= '3.11'" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/jsonschema/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/jsonschema/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce" },
+]
+
+[[package]]
+name = "jsonschema-specifications"
+version = "2025.9.1"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "referencing" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/jsonschema-specifications/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/jsonschema-specifications/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe" },
+]
+
+[[package]]
+name = "multidict"
+version = "6.7.1"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "typing-extensions", marker = "python_full_version < '3.11'" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1.tar.gz", hash = "sha256:ec6652a1bee61c53a3e5776b6049172c53b6aaba34f18c9ad04f82712bac623d" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c93c3db7ea657dd4637d57e74ab73de31bccefe144d3d4ce370052035bc85fb5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:974e72a2474600827abaeda71af0c53d9ebbc3c2eb7da37b37d7829ae31232d8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cdea2e7b2456cfb6694fb113066fd0ec7ea4d67e3a35e1f4cbeea0b448bf5872" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:17207077e29342fdc2c9a82e4b306f1127bf1ea91f8b71e02d4798a70bb99991" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4f49cb5661344764e4c7c7973e92a47a59b8fc19b6523649ec9dc4960e58a03" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a9fc4caa29e2e6ae408d1c450ac8bf19892c5fca83ee634ecd88a53332c59981" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c5f0c21549ab432b57dcc82130f388d84ad8179824cc3f223d5e7cfbfd4143f6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7dfb78d966b2c906ae1d28ccf6e6712a3cd04407ee5088cd276fe8cb42186190" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9b0d9b91d1aa44db9c1f1ecd0d9d2ae610b2f4f856448664e01a3b35899f3f92" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:dd96c01a9dcd4889dcfcf9eb5544ca0c77603f239e3ffab0524ec17aea9a93ee" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:067343c68cd6612d375710f895337b3a98a033c94f14b9a99eff902f205424e2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5884a04f4ff56c6120f6ccf703bdeb8b5079d808ba604d4d53aec0d55dc33568" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8affcf1c98b82bc901702eb73b6947a1bfa170823c153fe8a47b5f5f02e48e40" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0d17522c37d03e85c8098ec8431636309b2682cf12e58f4dbc76121fb50e4962" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:24c0cf81544ca5e17cfcb6e482e7a82cd475925242b308b890c9452a074d4505" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-win32.whl", hash = "sha256:d82dd730a95e6643802f4454b8fdecdf08667881a9c5670db85bc5a56693f122" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:cf37cbe5ced48d417ba045aca1b21bafca67489452debcde94778a576666a1df" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp310-cp310-win_arm64.whl", hash = "sha256:59bc83d3f66b41dac1e7460aac1d196edc70c9ba3094965c467715a70ecb46db" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7ff981b266af91d7b4b3793ca3382e53229088d193a85dfad6f5f4c27fc73e5d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:844c5bca0b5444adb44a623fb0a1310c2f4cd41f402126bb269cd44c9b3f3e1e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f2a0a924d4c2e9afcd7ec64f9de35fcd96915149b2216e1cb2c10a56df483855" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:8be1802715a8e892c784c0197c2ace276ea52702a0ede98b6310c8f255a5afb3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2e2d2ed645ea29f31c4c7ea1552fcfd7cb7ba656e1eafd4134a6620c9f5fdd9e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:95922cee9a778659e91db6497596435777bd25ed116701a4c034f8e46544955a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6b83cabdc375ffaaa15edd97eb7c0c672ad788e2687004990074d7d6c9b140c8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:38fb49540705369bab8484db0689d86c0a33a0a9f2c1b197f506b71b4b6c19b0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:439cbebd499f92e9aa6793016a8acaa161dfa749ae86d20960189f5398a19144" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6d3bc717b6fe763b8be3f2bee2701d3c8eb1b2a8ae9f60910f1b2860c82b6c49" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:619e5a1ac57986dbfec9f0b301d865dddf763696435e2962f6d9cf2fdff2bb71" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0b38ebffd9be37c1170d33bc0f36f4f262e0a09bc1aac1c34c7aa51a7293f0b3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:10ae39c9cfe6adedcdb764f5e8411d4a92b055e35573a2eaa88d3323289ef93c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:25167cc263257660290fba06b9318d2026e3c910be240a146e1f66dd114af2b0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:128441d052254f42989ef98b7b6a6ecb1e6f708aa962c7984235316db59f50fa" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-win32.whl", hash = "sha256:d62b7f64ffde3b99d06b707a280db04fb3855b55f5a06df387236051d0668f4a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:bdbf9f3b332abd0cdb306e7c2113818ab1e922dc84b8f8fd06ec89ed2a19ab8b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp311-cp311-win_arm64.whl", hash = "sha256:b8c990b037d2fff2f4e33d3f21b9b531c5745b33a49a7d6dbe7a177266af44f6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:a90f75c956e32891a4eda3639ce6dd86e87105271f43d43442a3aedf3cddf172" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fccb473e87eaa1382689053e4a4618e7ba7b9b9b8d6adf2027ee474597128cd" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b0fa96985700739c4c7853a43c0b3e169360d6855780021bfc6d0f1ce7c123e7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cb2a55f408c3043e42b40cc8eecd575afa27b7e0b956dfb190de0f8499a57a53" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eb0ce7b2a32d09892b3dd6cc44877a0d02a33241fafca5f25c8b6b62374f8b75" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c3a32d23520ee37bf327d1e1a656fec76a2edd5c038bf43eddfa0572ec49c60b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9c90fed18bffc0189ba814749fdcc102b536e83a9f738a9003e569acd540a733" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:da62917e6076f512daccfbbde27f46fed1c98fee202f0559adec8ee0de67f71a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bfde23ef6ed9db7eaee6c37dcec08524cb43903c60b285b172b6c094711b3961" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3758692429e4e32f1ba0df23219cd0b4fc0a52f476726fff9337d1a57676a582" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:398c1478926eca669f2fd6a5856b6de9c0acf23a2cb59a14c0ba5844fa38077e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c102791b1c4f3ab36ce4101154549105a53dc828f016356b3e3bcae2e3a039d3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a088b62bd733e2ad12c50dad01b7d0166c30287c166e137433d3b410add807a6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3d51ff4785d58d3f6c91bdbffcb5e1f7ddfda557727043aa20d20ec4f65e324a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc5907494fccf3e7d3f94f95c91d6336b092b5fc83811720fae5e2765890dfba" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-win32.whl", hash = "sha256:28ca5ce2fd9716631133d0e9a9b9a745ad7f60bac2bccafb56aa380fc0b6c511" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcee94dfbd638784645b066074b338bc9cc155d4b4bffa4adce1615c5a426c19" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp312-cp312-win_arm64.whl", hash = "sha256:ba0a9fb644d0c1a2194cf7ffb043bd852cea63a57f66fbd33959f7dae18517bf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2b41f5fed0ed563624f1c17630cb9941cf2309d4df00e494b551b5f3e3d67a23" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84e61e3af5463c19b67ced91f6c634effb89ef8bfc5ca0267f954451ed4bb6a2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:935434b9853c7c112eee7ac891bc4cb86455aa631269ae35442cb316790c1445" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:432feb25a1cb67fe82a9680b4d65fb542e4635cb3166cd9c01560651ad60f177" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e82d14e3c948952a1a85503817e038cba5905a3352de76b9a465075d072fba23" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4cfb48c6ea66c83bcaaf7e4dfa7ec1b6bbcf751b7db85a328902796dfde4c060" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1d540e51b7e8e170174555edecddbd5538105443754539193e3e1061864d444d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:273d23f4b40f3dce4d6c8a821c741a86dec62cded82e1175ba3d99be128147ed" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d624335fd4fa1c08a53f8b4be7676ebde19cd092b3895c421045ca87895b429" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:12fad252f8b267cc75b66e8fc51b3079604e8d43a75428ffe193cd9e2195dfd6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:03ede2a6ffbe8ef936b92cb4529f27f42be7f56afcdab5ab739cd5f27fb1cbf9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:90efbcf47dbe33dcf643a1e400d67d59abeac5db07dc3f27d6bdeae497a2198c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:5c4b9bfc148f5a91be9244d6264c53035c8a0dcd2f51f1c3c6e30e30ebaa1c84" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:401c5a650f3add2472d1d288c26deebc540f99e2fb83e9525007a74cd2116f1d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:97891f3b1b3ffbded884e2916cacf3c6fc87b66bb0dde46f7357404750559f33" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-win32.whl", hash = "sha256:e1c5988359516095535c4301af38d8a8838534158f649c05dd1050222321bcb3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:960c83bf01a95b12b08fd54324a4eb1d5b52c88932b5cba5d6e712bb3ed12eb5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313-win_arm64.whl", hash = "sha256:563fe25c678aaba333d5399408f5ec3c383ca5b663e7f774dd179a520b8144df" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:c76c4bec1538375dad9d452d246ca5368ad6e1c9039dadcf007ae59c70619ea1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:57b46b24b5d5ebcc978da4ec23a819a9402b4228b8a90d9c656422b4bdd8a963" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e954b24433c768ce78ab7929e84ccf3422e46deb45a4dc9f93438f8217fa2d34" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3bd231490fa7217cc832528e1cd8752a96f0125ddd2b5749390f7c3ec8721b65" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:253282d70d67885a15c8a7716f3a73edf2d635793ceda8173b9ecc21f2fb8292" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0b4c48648d7649c9335cf1927a8b87fa692de3dcb15faa676c6a6f1f1aabda43" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:98bc624954ec4d2c7cb074b8eefc2b5d0ce7d482e410df446414355d158fe4ca" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1b99af4d9eec0b49927b4402bcbb58dea89d3e0db8806a4086117019939ad3dd" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6aac4f16b472d5b7dc6f66a0d49dd57b0e0902090be16594dc9ebfd3d17c47e7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:21f830fe223215dffd51f538e78c172ed7c7f60c9b96a2bf05c4848ad49921c3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f5dd81c45b05518b9aa4da4aa74e1c93d715efa234fd3e8a179df611cc85e5f4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:eb304767bca2bb92fb9c5bd33cedc95baee5bb5f6c88e63706533a1c06ad08c8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:c9035dde0f916702850ef66460bc4239d89d08df4d02023a5926e7446724212c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:af959b9beeb66c822380f222f0e0a1889331597e81f1ded7f374f3ecb0fd6c52" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:41f2952231456154ee479651491e94118229844dd7226541788be783be2b5108" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-win32.whl", hash = "sha256:df9f19c28adcb40b6aae30bbaa1478c389efd50c28d541d76760199fc1037c32" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-win_amd64.whl", hash = "sha256:d54ecf9f301853f2c5e802da559604b3e95bb7a3b01a9c295c6ee591b9882de8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp313-cp313t-win_arm64.whl", hash = "sha256:5a37ca18e360377cfda1d62f5f382ff41f2b8c4ccb329ed974cc2e1643440118" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8f333ec9c5eb1b7105e3b84b53141e66ca05a19a605368c55450b6ba208cb9ee" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a407f13c188f804c759fc6a9f88286a565c242a76b27626594c133b82883b5c2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0e161ddf326db5577c3a4cc2d8648f81456e8a20d40415541587a71620d7a7d1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1e3a8bb24342a8201d178c3b4984c26ba81a577c80d4d525727427460a50c22d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97231140a50f5d447d3164f994b86a0bed7cd016e2682f8650d6a9158e14fd31" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6b10359683bd8806a200fd2909e7c8ca3a7b24ec1d8132e483d58e791d881048" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:283ddac99f7ac25a4acadbf004cb5ae34480bbeb063520f70ce397b281859362" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:538cec1e18c067d0e6103aa9a74f9e832904c957adc260e61cd9d8cf0c3b3d37" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7eee46ccb30ff48a1e35bb818cc90846c6be2b68240e42a78599166722cea709" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa263a02f4f2dd2d11a7b1bb4362aa7cb1049f84a9235d31adf63f30143469a0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:2e1425e2f99ec5bd36c15a01b690a1a2456209c5deed58f95469ffb46039ccbb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:497394b3239fc6f0e13a78a3e1b61296e72bf1c5f94b4c4eb80b265c37a131cd" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:233b398c29d3f1b9676b4b6f75c518a06fcb2ea0b925119fb2c1bc35c05e1601" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:93b1818e4a6e0930454f0f2af7dfce69307ca03cdcfb3739bf4d91241967b6c1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f33dc2a3abe9249ea5d8360f969ec7f4142e7ac45ee7014d8f8d5acddf178b7b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-win32.whl", hash = "sha256:3ab8b9d8b75aef9df299595d5388b14530839f6422333357af1339443cff777d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:5e01429a929600e7dab7b166062d9bb54a5eed752384c7384c968c2afab8f50f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314-win_arm64.whl", hash = "sha256:4885cb0e817aef5d00a2e8451d4665c1808378dc27c2705f1bf4ef8505c0d2e5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:0458c978acd8e6ea53c81eefaddbbee9c6c5e591f41b3f5e8e194780fe026581" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:c0abd12629b0af3cf590982c0b413b1e7395cd4ec026f30986818ab95bfaa94a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:14525a5f61d7d0c94b368a42cff4c9a4e7ba2d52e2672a7b23d84dc86fb02b0c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:17307b22c217b4cf05033dabefe68255a534d637c6c9b0cc8382718f87be4262" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7a7e590ff876a3eaf1c02a4dfe0724b6e69a9e9de6d8f556816f29c496046e59" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5fa6a95dfee63893d80a34758cd0e0c118a30b8dcb46372bf75106c591b77889" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a0543217a6a017692aa6ae5cc39adb75e587af0f3a82288b1492eb73dd6cc2a4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f99fe611c312b3c1c0ace793f92464d8cd263cc3b26b5721950d977b006b6c4d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9004d8386d133b7e6135679424c91b0b854d2d164af6ea3f289f8f2761064609" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e628ef0e6859ffd8273c69412a2465c4be4a9517d07261b33334b5ec6f3c7489" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:841189848ba629c3552035a6a7f5bf3b02eb304e9fea7492ca220a8eda6b0e5c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:ce1bbd7d780bb5a0da032e095c951f7014d6b0a205f8318308140f1a6aba159e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b26684587228afed0d50cf804cc71062cc9c1cdf55051c4c6345d372947b268c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:9f9af11306994335398293f9958071019e3ab95e9a707dc1383a35613f6abcb9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b4938326284c4f1224178a560987b6cf8b4d38458b113d9b8c1db1a836e640a2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-win32.whl", hash = "sha256:98655c737850c064a65e006a3df7c997cd3b220be4ec8fe26215760b9697d4d7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-win_amd64.whl", hash = "sha256:497bde6223c212ba11d462853cfa4f0ae6ef97465033e7dc9940cdb3ab5b48e5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-cp314-cp314t-win_arm64.whl", hash = "sha256:2bbd113e0d4af5db41d5ebfe9ccaff89de2120578164f86a5d17d5a576d1e5b2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/multidict/multidict-6.7.1-py3-none-any.whl", hash = "sha256:55d97cc6dae627efa6a6e548885712d4864b81110ac76fa4e534c03819fa4a56" },
+]
+
+[[package]]
+name = "opentelemetry-api"
+version = "1.42.1"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "typing-extensions" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/opentelemetry-api/opentelemetry_api-1.42.1.tar.gz", hash = "sha256:56c63bea9f77b62856be8c47600474acad853b2924b99b1687c4cb6297166716" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/opentelemetry-api/opentelemetry_api-1.42.1-py3-none-any.whl", hash = "sha256:51a69edacadbc03a8950ace1c4c21099cacc538820ac2c9e36277e78cebba714" },
+]
+
+[[package]]
+name = "opentelemetry-sdk"
+version = "1.42.1"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "opentelemetry-api" },
+ { name = "opentelemetry-semantic-conventions" },
+ { name = "typing-extensions" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/opentelemetry-sdk/opentelemetry_sdk-1.42.1.tar.gz", hash = "sha256:8c834e8f8c9ba4171d4ec843d0cb8a67e4c7394d3f9e9297e582cbd9456ddbf7" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/opentelemetry-sdk/opentelemetry_sdk-1.42.1-py3-none-any.whl", hash = "sha256:083cd4bbfaa5aa7b5a9e552430d9951219967cfb27aa61feb13a77aba1fc839d" },
+]
+
+[[package]]
+name = "opentelemetry-semantic-conventions"
+version = "0.63b1"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "opentelemetry-api" },
+ { name = "typing-extensions" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/opentelemetry-semantic-conventions/opentelemetry_semantic_conventions-0.63b1.tar.gz", hash = "sha256:3daf963611334b365e98a57438183eb012d3bfb40b2d931a9af613476b8701a9" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/opentelemetry-semantic-conventions/opentelemetry_semantic_conventions-0.63b1-py3-none-any.whl", hash = "sha256:dfe5ef4dee82586b746f522b818ceb298d00b3d59f660042bd79404bff8d0682" },
+]
+
+[[package]]
+name = "packaging"
+version = "26.3"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/packaging/packaging-26.3.tar.gz", hash = "sha256:94edc256424af38762eb31306eed28beb9f0efc50a8837492c9d6fd6004aed79" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/packaging/packaging-26.3-py3-none-any.whl", hash = "sha256:d7193f7c8e4e93f444fde0262bf90af30e16fa0ad0ad44cb553c87339b23cd1c" },
+]
+
+[[package]]
+name = "propcache"
+version = "0.5.2"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2.tar.gz", hash = "sha256:01c4fc7480cd0598bb4b57022df55b9ca296da7fc5a8760bd8451a7e63a7d427" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d5a81be28596d6559f6131ef33e10200de6e17643b3c74ce03f9eb103be6ae8b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29cbaac5ea0212663e6845e04b5e188d5a6ae6dd919810ac835bf1d3b42c3f4c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6bf3be92233808fcd338eba0fb4d0b59ec5772af4f4ecfcec450d1bfc0f8b5eb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2f8ea531c794b9d6274acd4e8d2c2ebcac590a4361d27482edd3010b79f1325e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:decfca4c79dd53ebab484b00cc4b6717d8c369f86e74aa4ca395a64ac651495e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:4621064bbf28fa77ff64dd5d94367c04684c67d3a5bf1dff25f0cd0d98a38f3b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b96db7141a592cbc968daf1feea83a118e6ab378af4abbc72b248c895414c22d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1ca071adabaab6e9219924bbe00af821f1ee7de113a9eca1cdc292de3d120f4d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e4294d04a94dcab1b3bccd8b66d962dcad411a1d19414b2a41d1445f1de32ad0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a0e399a2eccb91ed18721f86aa85757727400b6865c89e88934781deb9c8498b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:823581fd5cb08b12a48bfa11fe962a7916766b6170c17b028fbdf762b85eb9bf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:949c91d1a990cf3b2e8188dfcfb25005e0b834a06c63fa4ef9f360878ce21ecf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:cc1177027eda740fdb152706bd215a3f124e3eea15afc39f2cb9fe351b50619e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b05d643f944a8c3c4bd86d65ffd87bf3264b617f87791940302bc474d2ff5274" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp310-cp310-win32.whl", hash = "sha256:8114f28879e0904748e831c3a7774261bd9e75f49be089f389a76f959dcd13fe" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:5fcb98e7598b1ee0addab320d90f65b530297a867dbfe9de52ea838077e16e3d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp310-cp310-win_arm64.whl", hash = "sha256:04dc2390d9edbbaef7461f33322555976ffddf0b650a038649d026358714e6c5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:74b70780220e2dd89175ca24b81b68b67c83db499ae611e7f2313cb329801c78" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a4840ab0ae0216d952f4b53dc6d0b992bfc2bedbfe360bdd9b548bc184c08959" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c6844ba6364fb12f403928a82cfd295ab103a2b315c77c747b2dbe4a41894ea7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2293949b855ce597f2826452d17c2d545fb5622379c4ea6fdf525e9b8e8a2511" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0fd59b5af35f74da48d905dcbad55449ba13be91823cb05a9bd590bbf5b61660" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29f9309a2e42b0d273be006fdb4be2d6c39a47f6f57d8fb1cf9f81481df81b66" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5aaa2b923c1944ac8febd6609cb373540a5563e7cbcb0fd770f75dace2eb817b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:66ea454f095ddf5b6b14f56c064c0941c4788be11e18d2464cf643bf7203ff67" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:95f1e3f4760d404b13c9976c0229b2b49a3c8e2c62a9ce92efdd2b11ada75e3f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:85341b12b9d55bad0bded24cac341bb34289469e03a11f3f583ea1cc1db0326c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:26a4dca084132874e639895c3135dfad5eb20bae209f62d1aeb31b03e601c3c0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:3b199b9b2b3d6a7edf3183ba8a9a137a22b97f7df525feb5ae1eccf026d2a9c6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e59bc9e66329185b93dab73f210f1a37f81cb40f321501db8017c9aea15dba27" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:552ffadf6ad409844bc5919c42a0a83d88314cedddaea0e41e80a8b8fffe881f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp311-cp311-win32.whl", hash = "sha256:cd416c1de191973c52ff1a12a57446bfc7642797b282d7caf2162d7d1b8aa9a0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:44e488ef40dbb452700b2b1f8188934121f6648f52c295055662d2191959ff82" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp311-cp311-win_arm64.whl", hash = "sha256:54adaa85a22078d1e306304a40984dc5be99d599bf3dc0a24dc98f7daeab89ab" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:806719138ecd720339a12410fb9614ac9b2b2d3a5fdf8235d56981c36f4039ba" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:db2b80ea58eab4f86b2beec3cc8b39e8ff9276ac20e96b7cce43c8ae84cd6b5a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e5cbfac9f61484f7e9f3597775500cd3ebe8274e9b050c38f9525c77c97520bf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5dbc581d2814337da56222fab8dc5f161cd798a434e49bac27930aaef798e144" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:857187f381f88c8e2fa2fe56ab94879d011b883d5a2ee5a1b60a8cd2a06846d9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:178b4a2cdaac1818e2bf1c5a99b94383fa73ea5382e032a48dec07dc5668dc42" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f328175a2cde1f0ff2c4ed8ce968b9dcfb55f3a7153f39e2957ed994da13476" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5671d09a36b06d0fd4a3da0fccbcae360e9b1570924171a15e9e0997f0249fba" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:80168e2ebe4d3ec6599d10ad8f520304ae1cad9b6c5a95372aef1b66b7bfb53a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:45f11346f884bc47444f6e6647131055844134c3175b629f84952e2b5cd62b64" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8e778ebd44ef4f66ed60a0416b06b489687db264a9c0b3620362f26489492913" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:c0cb9ed24c8964e172768d455a38254c2dd8a552905729ce006cad3d3dda59b1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1d1ad32d9d4355e2be65574fd0bfd3677e7066b009cd5b9b2dee8aa6a6393b33" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c80f4ba3e8f00189165999a742ee526ebeccedf6c3f7beb0c7df821e9772435a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp312-cp312-win32.whl", hash = "sha256:8c7972d8f193740d9175f0998ab38717e6cd322d5935c5b0fef8c0d323fd9031" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:d9ee8826a7d47863a08ac44e1a5f611a462eefc3a194b492da242128bec75b42" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp312-cp312-win_arm64.whl", hash = "sha256:2800a4a8ead6b28cccd1ec54b59346f0def7922ee1c7598e8499c733cfbb7c84" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:099aaf4b4d1a02265b92a977edf00b5c4f63b3b17ac6de39b0d637c9cac0188a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:68ce1c44c7a813a7f71ea04315a8c7b330b63db99d059a797a4651bb6f69f117" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fc299c129490f55f254cd90be0deca4764e36e9a7c08b4aa588479a3bbed3098" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a6ae2198be502c10f09b2516e7b5d019816924bc3183a43ce792a7bd6625e6f4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6041d31504dc1779d700e1edcfb08eea334b357620b06681a4eabb57a74e574e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f7eabc04151c78a9f4d5bbb5f1faf571e4defeb4b585e0fe95b60ff2dbe4d3d7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4db0ba63d693afd40d249bd93f842b5f144f8fcbb83de05660373bcf30517b1d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1dbcf7675229b35d31abb6547d8ebc8c27a830ac3f9a794edff6254873ec7c0a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d310c013aad2c72f1c3f2f8dd3279d460a858c551f97aeb8c63e4693cca7b4d2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:06187263ddad280d05b4d8a8b3bb7d164cbebd469236544a42e6d9b28ac6a4fa" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3115559b8effafd63b142ea5ed53d63a16ea6469cbc63dce4ee194b42db5d853" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c60462af8e6dc30c35407c7237ea908d777b22862bbee27bc4699c0d8bcdc45a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:40314bca9ac559716fe374094fc81c11dcc34b64fd6c585360f5775690505704" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:cfa21e036ce1e1db2be04ba3b85d2df1bb1702fa01932d984c5464c665228ff4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313-win32.whl", hash = "sha256:f156a3529f38063b6dbaf356e15602a7f95f8055b1295a438433a6386f10463d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313-win_amd64.whl", hash = "sha256:dfed59d0a5aeb01e242e66ff0300bc4a265a7c05f612d30016f0b60b1017d757" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313-win_arm64.whl", hash = "sha256:ba338430e87ceb9c8f0cf754de38a9860560261e56c00376debd628698a7364f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a592f5f3da71c8691c788c13cb6734b6d17663d2e1cb8caddf0673d01ef8847d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:6a997d0489e9668a384fcfd5061b857aa5361de73191cac204d04b889cfbbafa" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:10734b5484ea113152ee25a91dccedf81631791805d2c9ccb054958e51842c94" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cafca7e56c12bb02ae16d283742bef25a61122e9dab2b5b3f2ccbe589ce32164" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f064f8d2b59177878b7615df1735cd8fe3462ed6be8c7b217d17a276489c2b7f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f78abfa8dfc32376fd1aacf597b2f2fbbe0ea751419aee718af5d4f82537ef8c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f7467da8a9822bf1a55336f877340c5bcbd3c482afc43a99771169f74a26dedc" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a6ddc6ac9e25de626c1f129c1b467d7ecd33ce2237d3fd0c4e429feef0a7ee1f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2f22cbbac9e26a8e864c0985ff1268d5d939d53d9d9411a9824279097e03a2cb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:fc76378c62a0f04d0cd82fbb1a2cd2d7e28fcb40d5873f28a6c44e388aaa2751" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:acd2c8edba48e31e58a363b8cf4e5c7db3b04b3f9e371f601df30d9b0d244836" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:452b5065457eb9991ec5eb38ff41d6cd4c991c9ac7c531c4d5849ae473a9a13f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:3430bb2bfe1331885c427745a751e774ee679fd4344f80b97bf879815fe8fa55" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cef6cea3922890dd6c9654971001fa797b526c16ab5e1e46c05fd6f877be7568" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313t-win32.whl", hash = "sha256:72d61e16dd78228b58c5d47be830ff3da7e5f139abdf0aef9d86cde1c5cf2191" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313t-win_amd64.whl", hash = "sha256:0958834041a0166d343b8d2cedcd8bcbaeb4fdbe0cf08320c5379f143c3be6e7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp313-cp313t-win_arm64.whl", hash = "sha256:6de8bd93ddde9b992cf2b2e0d796d501a19026b5b9fd87356d7d0779531a8d96" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:46088abff4cba581dea21ae0467a480526cb25aa5f3c269e909f800328bc3999" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fc88b26f08d634f7bc819a7852e5214f5802641ab8d9fd5326892292eee1993e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:97797ebb098e670a2f92dd66f32897e30d7615b14e7f59711de23e30a9072539" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba57fffe4ac99c5d30076161b5866336d97600769bad35cc68f7774b15298a4e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:583c19759d9eec1e5b69e2fbef36a7d9c326041be9746cb822d335c8cedc2979" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d0326e2e5e1f3163fa306c834e48e8d490e5fae607a097a40c0648109b47ba80" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e00820e192c8dbebcafb383ebbf99030895f09905e7a0eb2e0340a0bcc2bc825" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c66afea89b1e43725731d2004732a046fe6fe955d51f952c3e95a7314a284a39" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d4dc37dec6c6cdad0b57881a5658fd14fbf53e333b1a86cf86559f190e1d9ec4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:5570dbcc97571c15f68068e529c92715a12f8d54030e272d264b377e22bd17a5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f814362777a9f841adddb200ecdf8f5cb1e5a3c4b7a86378edbd6ccb26edd702" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:196913dea116aeb5a2ba95af4ddcb7ea85559ae07d8eee8751688310d09168c3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:6e7b8719005dd1175be4ab1cd25e9b98659a5e0347331506ec6760d2773a7fb5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:51f96d685ab16e88cab128cd37a52c5da540809c8b879fa047731bfcb4ad35a4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314-win32.whl", hash = "sha256:cc6fc3cc62e8501d3ed62894425040d2728ecddb1ed072737a5c70bd537aa9f0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314-win_amd64.whl", hash = "sha256:81e3a30b0bb60caa22033dd0f8a3618d1d67356212514f62c57db75cb0ef410c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314-win_arm64.whl", hash = "sha256:0d2c9bf8528f135dbb805ce027567e09164f7efa51a2be07458a2c0420f292d0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:4bc8ff1feffc6a61c7002ffe84634c41b822e104990ae009f44a0834430070bb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:79aa3ff0a9b566633b642fa9caf7e21ed1c13d6feca718187873f199e1514078" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1b31822f4474c4036bae62de9402710051d431a606d6a0f907fec79935a071aa" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13fef48778b5a2a756523fdb781326b028ca75e32858b04f2cdd19f394564917" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8b73ab70f1a3351fbc71f663b3e645af6dd0329100c353081cf69c37433fc6fe" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5538d2c13d93e4698af7e092b57bc7298fd35d1d58e656ae18f23ee0d0378e03" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd645f03898405cabe694fb8bc35241e3a9c332ec85627584fe3de201452b335" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a473b3440261e0c60706e732b2ed2f517857344fc21bf48fdfe211e2d98eb285" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7afa37062e6650640e932e4cc9297d81f9f42d9944029cc386b8247dea4da837" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:8a90efd5777e996e42d568db9ac740b944d691e565cbfd31b2f7832f9184b2b8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:f19bb891234d72535764d703bfed1153cc34f4214d5bd7150aee1eec9e8f4366" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:32775082acd2d807ee3db715c7770d38767b817870acfa08c29e057f3c4d5b56" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:9282fb1a3bccd038da9f768b927b24a0c753e466c086b7c4f3c6982851eefb2d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cc49723e2f60d6b32a0f0b08a3fd6d13203c07f1cd9566cfce0f12a917c967a2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314t-win32.whl", hash = "sha256:2d7aa89ebca5acc98cba9d1472d976e394782f587bad6661003602a619fd1821" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314t-win_amd64.whl", hash = "sha256:d447bb0b3054be5818458fbb171208b1d9ff11eba14e18ca18b90cbb45767370" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-cp314-cp314t-win_arm64.whl", hash = "sha256:fe67a3d11cd9b4efabfa45c3d00ffba2b26811442a73a581a94b67c2b5faccf6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/propcache/propcache-0.5.2-py3-none-any.whl", hash = "sha256:be1ddfcbb376e3de5d2e2db1d58d6d67463e6b4f9f040c000de8e300295465fe" },
+]
+
+[[package]]
+name = "proto-plus"
+version = "1.28.3"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "protobuf" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/proto-plus/proto_plus-1.28.3.tar.gz", hash = "sha256:5f91b30dafa6bb38d432c5557a6ee1d35ffd40b4b1e0e3ca27260448560b91d9" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/proto-plus/proto_plus-1.28.3-py3-none-any.whl", hash = "sha256:dc76880b8ee951cca002098574376cf71e055f9f16d9ba6570fb8a06f726d281" },
+]
+
+[[package]]
+name = "protobuf"
+version = "7.36.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/protobuf/protobuf-7.36.0.tar.gz", hash = "sha256:e8e09cb0d794c6687926fa558a8a6e72aa10edb997d5ca61da0765f12a3e00ea" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/protobuf/protobuf-7.36.0-cp310-abi3-macosx_10_9_universal2.whl", hash = "sha256:9103532dffd80c6fab7e50c65a31007680a06eb57537d437bb1b35812c138a37" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/protobuf/protobuf-7.36.0-cp310-abi3-manylinux2014_aarch64.whl", hash = "sha256:bf94a5917c71058262de683669bc0a797a7669d3de71f0b36d058e3194f47b44" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/protobuf/protobuf-7.36.0-cp310-abi3-manylinux2014_s390x.whl", hash = "sha256:3297e60abdff301e5f74393d87f6cc59dacab5f024a89548a6e8de1d26576b16" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/protobuf/protobuf-7.36.0-cp310-abi3-manylinux2014_x86_64.whl", hash = "sha256:70f5ec8eb0da81a44360c0dc0beac99a0d78071d21956a7076bae8bd2051841b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/protobuf/protobuf-7.36.0-cp310-abi3-win32.whl", hash = "sha256:7326fd717bdc419162a735938d89d4032332bcc3408804012b24ff3a37086071" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/protobuf/protobuf-7.36.0-cp310-abi3-win_amd64.whl", hash = "sha256:1781cc1de61249b750848029bca452c0a8b7e990080316b9bbc2518b2117b488" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/protobuf/protobuf-7.36.0-py3-none-any.whl", hash = "sha256:53374d53fc29a67f7dbbf0ade47d7526a0f0137bf0f9c90e48d8a60790ef748c" },
+]
+
+[[package]]
+name = "pyasn1"
+version = "0.6.4"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyasn1/pyasn1-0.6.4.tar.gz", hash = "sha256:9c447d8431c947fe4c8febc4ed9e760bc29011a5b01e5c74b67025bd9fb8ce81" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyasn1/pyasn1-0.6.4-py3-none-any.whl", hash = "sha256:deda9277cfd454080ec40b207fb6df82206a3a2688735233cdcd8d3d565f088b" },
+]
+
+[[package]]
+name = "pyasn1-modules"
+version = "0.4.2"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "pyasn1" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyasn1-modules/pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyasn1-modules/pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a" },
+]
+
+[[package]]
+name = "pycparser"
+version = "3.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pycparser/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pycparser/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992" },
+]
+
+[[package]]
+name = "pydantic"
+version = "2.13.4"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "annotated-types" },
+ { name = "pydantic-core" },
+ { name = "typing-extensions" },
+ { name = "typing-inspection" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba" },
+]
+
+[[package]]
+name = "pydantic-core"
+version = "2.46.4"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "typing-extensions" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:a396dcc17e5a0b164dbe026896245a4fa9ff402edca1dff0be3d53a517f74de4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:da4b951fe36dc7c3a1ccb4e3cd1747c3542b8c9ceede8fc86cae054e764485f5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb63e0198ca18aad131c089b9204c23079c3afa95487e561f4c522d519e55aba" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f47286a97f0bc9b8859519809077b91b2cefe4ae47fcbf5e466a009c1c5d742b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:905a0ed8ea6f2d61c1738835f99b699348d7857379083e5fc497fa0c967a407c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea793e075b70290d89d8142074262885d3f7da19634845135751bd6344f73b50" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:395aebd9183f9d112f569aeb5b2214d1a10a33bec8456447f7fbdfa51d38d4cd" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:b078afbc25f3a1436c7a1d2cd3e322497ee99615ba97c563566fdf46aff1ee01" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f747929cf940cddb5b3668a390056ddd5ba2e5010615ea2dcf4f9c4f3ab8791d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:daa27d92c36f24388fe3ad306b174781c747627f134452e4f128ea00ce1fe8c4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:19e51f073cd3df251856a8a4189fbdf1de4012c3ebacfb1884f94f1eb406079f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1747f85cee84c26985853c6f3d9bd3e75da5212912443fa111c113b9c246f39" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp310-cp310-win32.whl", hash = "sha256:2f84c03c8607173d16b5a854ec68a2f9079ae03237a54fb506d13af47e1d018d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp310-cp310-win_amd64.whl", hash = "sha256:8358a950c8909158e3df31538a7e4edc2d7265a7c54b47f0864d9e5bae9dcebf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp311-cp311-win32.whl", hash = "sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp311-cp311-win_amd64.whl", hash = "sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp311-cp311-win_arm64.whl", hash = "sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp312-cp312-win32.whl", hash = "sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp312-cp312-win_amd64.whl", hash = "sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp312-cp312-win_arm64.whl", hash = "sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pydantic-core/pydantic_core-2.46.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983" },
+]
+
+[[package]]
+name = "python-dotenv"
+version = "1.2.3"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/python-dotenv/python_dotenv-1.2.3.tar.gz", hash = "sha256:a20a594dabeaa385725aa239d5244871c143ecb356add8a20fcf23773a6c3a35" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/python-dotenv/python_dotenv-1.2.3-py3-none-any.whl", hash = "sha256:904552145e8bfed22162c09dab1c2b9b54fefa7b23ba780f4f26ca0316b0f0d9" },
+]
+
+[[package]]
+name = "python-multipart"
+version = "0.0.32"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/python-multipart/python_multipart-0.0.32.tar.gz", hash = "sha256:be54b7f3fa167bb83e4fcd936b887b708f4e57fe75911c02aebf53efaf8d938e" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/python-multipart/python_multipart-0.0.32-py3-none-any.whl", hash = "sha256:ff6d3f776f16878c894e52e107296ffc890e913c611b1a4ec6c44e2821fe2e23" },
+]
+
+[[package]]
+name = "pyyaml"
+version = "6.0.3"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:214ed4befebe12df36bcc8bc2b64b396ca31be9304b8f59e25c11cf94a4c033b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02ea2dfa234451bbb8772601d7b8e426c2bfa197136796224e50e35a78777956" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b30236e45cf30d2b8e7b3e85881719e98507abed1011bf463a8fa23e9c3e98a8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:66291b10affd76d76f54fad28e22e51719ef9ba22b29e1d7d03d6777a9174198" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c7708761fccb9397fe64bbc0395abcae8c4bf7b0eac081e12b809bf47700d0b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:418cf3f2111bc80e0933b2cd8cd04f286338bb88bdc7bc8e6dd775ebde60b5e0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5e0b74767e5f8c593e8c9b5912019159ed0533c70051e9cce3e8b6aa699fcd69" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp310-cp310-win32.whl", hash = "sha256:28c8d926f98f432f88adc23edf2e6d4921ac26fb084b028c733d01868d19007e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:bdb2c67c6c1390b63c6ff89f210c8fd09d9a1217a465701eac7316313c915e4c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/pyyaml/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b" },
+]
+
+[[package]]
+name = "referencing"
+version = "0.37.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "attrs" },
+ { name = "rpds-py", version = "0.30.0", source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }, marker = "python_full_version < '3.11'" },
+ { name = "rpds-py", version = "2026.6.3", source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }, marker = "python_full_version >= '3.11'" },
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/referencing/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/referencing/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231" },
+]
+
+[[package]]
+name = "requests"
+version = "2.34.2"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "certifi" },
+ { name = "charset-normalizer" },
+ { name = "idna" },
+ { name = "urllib3" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/requests/requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/requests/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0" },
+]
+
+[[package]]
+name = "rpds-py"
+version = "0.30.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+resolution-markers = [
+ "python_full_version < '3.11'",
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0.tar.gz", hash = "sha256:dd8ff7cf90014af0c0f787eea34794ebf6415242ee1d6fa91eaba725cc441e84" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:679ae98e00c0e8d68a7fda324e16b90fd5260945b45d3b824c892cec9eea3288" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4cc2206b76b4f576934f0ed374b10d7ca5f457858b157ca52064bdfc26b9fc00" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:389a2d49eded1896c3d48b0136ead37c48e221b391c052fba3f4055c367f60a6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:32c8528634e1bf7121f3de08fa85b138f4e0dc47657866630611b03967f041d7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f207f69853edd6f6700b86efb84999651baf3789e78a466431df1331608e5324" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:67b02ec25ba7a9e8fa74c63b6ca44cf5707f2fbfadae3ee8e7494297d56aa9df" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0e95f6819a19965ff420f65578bacb0b00f251fefe2c8b23347c37174271f3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:a452763cc5198f2f98898eb98f7569649fe5da666c2dc6b5ddb10fde5a574221" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e0b65193a413ccc930671c55153a03ee57cecb49e6227204b04fae512eb657a7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:858738e9c32147f78b3ac24dc0edb6610000e56dc0f700fd5f651d0a0f0eb9ff" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:da279aa314f00acbb803da1e76fa18666778e8a8f83484fba94526da5de2cba7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7c64d38fb49b6cdeda16ab49e35fe0da2e1e9b34bc38bd78386530f218b37139" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp310-cp310-win32.whl", hash = "sha256:6de2a32a1665b93233cde140ff8b3467bdb9e2af2b91079f0333a0974d12d464" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:1726859cd0de969f88dc8673bdd954185b9104e05806be64bcd87badbe313169" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a2bffea6a4ca9f01b3f8e548302470306689684e61602aa3d141e34da06cf425" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dc4f992dfe1e2bc3ebc7444f6c7051b4bc13cd8e33e43511e8ffd13bf407010d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:422c3cb9856d80b09d30d2eb255d0754b23e090034e1deb4083f8004bd0761e4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07ae8a593e1c3c6b82ca3292efbe73c30b61332fd612e05abee07c79359f292f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12f90dd7557b6bd57f40abe7747e81e0c0b119bef015ea7726e69fe550e394a4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:99b47d6ad9a6da00bec6aabe5a6279ecd3c06a329d4aa4771034a21e335c3a97" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33f559f3104504506a44bb666b93a33f5d33133765b0c216a5bf2f1e1503af89" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:946fe926af6e44f3697abbc305ea168c2c31d3e3ef1058cf68f379bf0335a78d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:495aeca4b93d465efde585977365187149e75383ad2684f81519f504f5c13038" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d9a0ca5da0386dee0655b4ccdf46119df60e0f10da268d04fe7cc87886872ba7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8d6d1cc13664ec13c1b84241204ff3b12f9bb82464b8ad6e7a5d3486975c2eed" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3896fa1be39912cf0757753826bc8bdc8ca331a28a7c4ae46b7a21280b06bb85" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp311-cp311-win32.whl", hash = "sha256:55f66022632205940f1827effeff17c4fa7ae1953d2b74a8581baaefb7d16f8c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:a51033ff701fca756439d641c0ad09a41d9242fa69121c7d8769604a0a629825" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp311-cp311-win_arm64.whl", hash = "sha256:47b0ef6231c58f506ef0b74d44e330405caa8428e770fec25329ed2cb971a229" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a161f20d9a43006833cd7068375a94d035714d73a172b681d8881820600abfad" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6abc8880d9d036ecaafe709079969f56e876fcf107f7a8e9920ba6d5a3878d05" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca28829ae5f5d569bb62a79512c842a03a12576375d5ece7d2cadf8abe96ec28" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a1010ed9524c73b94d15919ca4d41d8780980e1765babf85f9a2f90d247153dd" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8d1736cfb49381ba528cd5baa46f82fdc65c06e843dab24dd70b63d09121b3f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d948b135c4693daff7bc2dcfc4ec57237a29bd37e60c2fabf5aff2bbacf3e2f1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47f236970bccb2233267d89173d3ad2703cd36a0e2a6e92d0560d333871a3d23" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:2e6ecb5a5bcacf59c3f912155044479af1d0b6681280048b338b28e364aca1f6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a8fa71a2e078c527c3e9dc9fc5a98c9db40bcc8a92b4e8858e36d329f8684b51" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:73c67f2db7bc334e518d097c6d1e6fed021bbc9b7d678d6cc433478365d1d5f5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5ba103fb455be00f3b1c2076c9d4264bfcb037c976167a6047ed82f23153f02e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7cee9c752c0364588353e627da8a7e808a66873672bcb5f52890c33fd965b394" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp312-cp312-win32.whl", hash = "sha256:1ab5b83dbcf55acc8b08fc62b796ef672c457b17dbd7820a11d6c52c06839bdf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:a090322ca841abd453d43456ac34db46e8b05fd9b3b4ac0c78bcde8b089f959b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp312-cp312-win_arm64.whl", hash = "sha256:669b1805bd639dd2989b281be2cfd951c6121b65e729d9b843e9639ef1fd555e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f83424d738204d9770830d35290ff3273fbb02b41f919870479fab14b9d303b2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e7536cd91353c5273434b4e003cbda89034d67e7710eab8761fd918ec6c69cf8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2771c6c15973347f50fece41fc447c054b7ac2ae0502388ce3b6738cd366e3d4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0a59119fc6e3f460315fe9d08149f8102aa322299deaa5cab5b40092345c2136" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:76fec018282b4ead0364022e3c54b60bf368b9d926877957a8624b58419169b7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:692bef75a5525db97318e8cd061542b5a79812d711ea03dbc1f6f8dbb0c5f0d2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9027da1ce107104c50c81383cae773ef5c24d296dd11c99e2629dbd7967a20c6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:9cf69cdda1f5968a30a359aba2f7f9aa648a9ce4b580d6826437f2b291cfc86e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4796a717bf12b9da9d3ad002519a86063dcac8988b030e405704ef7d74d2d9d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5d4c2aa7c50ad4728a094ebd5eb46c452e9cb7edbfdb18f9e1221f597a73e1e7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ba81a9203d07805435eb06f536d95a266c21e5b2dfbf6517748ca40c98d19e31" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:945dccface01af02675628334f7cf49c2af4c1c904748efc5cf7bbdf0b579f95" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313-win32.whl", hash = "sha256:b40fb160a2db369a194cb27943582b38f79fc4887291417685f3ad693c5a1d5d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:806f36b1b605e2d6a72716f321f20036b9489d29c51c91f4dd29a3e3afb73b15" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313-win_arm64.whl", hash = "sha256:d96c2086587c7c30d44f31f42eae4eac89b60dabbac18c7669be3700f13c3ce1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:eb0b93f2e5c2189ee831ee43f156ed34e2a89a78a66b98cadad955972548be5a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:922e10f31f303c7c920da8981051ff6d8c1a56207dbdf330d9047f6d30b70e5e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdc62c8286ba9bf7f47befdcea13ea0e26bf294bda99758fd90535cbaf408000" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:47f9a91efc418b54fb8190a6b4aa7813a23fb79c51f4bb84e418f5476c38b8db" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f3587eb9b17f3789ad50824084fa6f81921bbf9a795826570bda82cb3ed91f2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39c02563fc592411c2c61d26b6c5fe1e51eaa44a75aa2c8735ca88b0d9599daa" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51a1234d8febafdfd33a42d97da7a43f5dcb120c1060e352a3fbc0c6d36e2083" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:eb2c4071ab598733724c08221091e8d80e89064cd472819285a9ab0f24bcedb9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6bdfdb946967d816e6adf9a3d8201bfad269c67efe6cefd7093ef959683c8de0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c77afbd5f5250bf27bf516c7c4a016813eb2d3e116139aed0096940c5982da94" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:61046904275472a76c8c90c9ccee9013d70a6d0f73eecefd38c1ae7c39045a08" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c5f36a861bc4b7da6516dbdf302c55313afa09b81931e8280361a4f6c9a2d27" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313t-win32.whl", hash = "sha256:3d4a69de7a3e50ffc214ae16d79d8fbb0922972da0356dcf4d0fdca2878559c6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp313-cp313t-win_amd64.whl", hash = "sha256:f14fc5df50a716f7ece6a80b6c78bb35ea2ca47c499e422aa4463455dd96d56d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:68f19c879420aa08f61203801423f6cd5ac5f0ac4ac82a2368a9fcd6a9a075e0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ec7c4490c672c1a0389d319b3a9cfcd098dcdc4783991553c332a15acf7249be" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f251c812357a3fed308d684a5079ddfb9d933860fc6de89f2b7ab00da481e65f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac98b175585ecf4c0348fd7b29c3864bda53b805c773cbf7bfdaffc8070c976f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3e62880792319dbeb7eb866547f2e35973289e7d5696c6e295476448f5b63c87" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e7fc54e0900ab35d041b0601431b0a0eb495f0851a0639b6ef90f7741b39a18" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47e77dc9822d3ad616c3d5759ea5631a75e5809d5a28707744ef79d7a1bcfcad" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:b4dc1a6ff022ff85ecafef7979a2c6eb423430e05f1165d6688234e62ba99a07" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4559c972db3a360808309e06a74628b95eaccbf961c335c8fe0d590cf587456f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0ed177ed9bded28f8deb6ab40c183cd1192aa0de40c12f38be4d59cd33cb5c65" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ad1fa8db769b76ea911cb4e10f049d80bf518c104f15b3edb2371cc65375c46f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:46e83c697b1f1c72b50e5ee5adb4353eef7406fb3f2043d64c33f20ad1c2fc53" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314-win32.whl", hash = "sha256:ee454b2a007d57363c2dfd5b6ca4a5d7e2c518938f8ed3b706e37e5d470801ed" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314-win_amd64.whl", hash = "sha256:95f0802447ac2d10bcc69f6dc28fe95fdf17940367b21d34e34c737870758950" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314-win_arm64.whl", hash = "sha256:613aa4771c99f03346e54c3f038e4cc574ac09a3ddfb0e8878487335e96dead6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:7e6ecfcb62edfd632e56983964e6884851786443739dbfe3582947e87274f7cb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a1d0bc22a7cdc173fedebb73ef81e07faef93692b8c1ad3733b67e31e1b6e1b8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d08f00679177226c4cb8c5265012eea897c8ca3b93f429e546600c971bcbae7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5965af57d5848192c13534f90f9dd16464f3c37aaf166cc1da1cae1fd5a34898" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a4e86e34e9ab6b667c27f3211ca48f73dba7cd3d90f8d5b11be56e5dbc3fb4e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5d3e6b26f2c785d65cc25ef1e5267ccbe1b069c5c21b8cc724efee290554419" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:626a7433c34566535b6e56a1b39a7b17ba961e97ce3b80ec62e6f1312c025551" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:acd7eb3f4471577b9b5a41baf02a978e8bdeb08b4b355273994f8b87032000a8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fe5fa731a1fa8a0a56b0977413f8cacac1768dad38d16b3a296712709476fbd5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:74a3243a411126362712ee1524dfc90c650a503502f135d54d1b352bd01f2404" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:3e8eeb0544f2eb0d2581774be4c3410356eba189529a6b3e36bbbf9696175856" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dbd936cde57abfee19ab3213cf9c26be06d60750e60a8e4dd85d1ab12c8b1f40" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314t-win32.whl", hash = "sha256:dc824125c72246d924f7f796b4f63c1e9dc810c7d9e2355864b3c3a73d59ade0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27f4b0e92de5bfbc6f86e43959e6edd1425c33b5e69aab0984a72047f2bcf1e3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c2262bdba0ad4fc6fb5545660673925c2d2a5d9e2e0fb603aad545427be0fc58" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ee6af14263f25eedc3bb918a3c04245106a42dfd4f5c2285ea6f997b1fc3f89a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3adbb8179ce342d235c31ab8ec511e66c73faa27a47e076ccc92421add53e2bb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:250fa00e9543ac9b97ac258bd37367ff5256666122c2d0f2bc97577c60a1818c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9854cf4f488b3d57b9aaeb105f06d78e5529d3145b1e4a41750167e8c213c6d3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:993914b8e560023bc0a8bf742c5f303551992dcb85e247b1e5c7f4a7d145bda5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58edca431fb9b29950807e301826586e5bbf24163677732429770a697ffe6738" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:dea5b552272a944763b34394d04577cf0f9bd013207bc32323b5a89a53cf9c2f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ba3af48635eb83d03f6c9735dfb21785303e73d22ad03d489e88adae6eab8877" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:dff13836529b921e22f15cb099751209a60009731a68519630a24d61f0b1b30a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:1b151685b23929ab7beec71080a8889d4d6d9fa9a983d213f07121205d48e2c4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-0.30.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ac37f9f516c51e5753f27dfdef11a88330f04de2d564be3991384b2f3535d02e" },
+]
+
+[[package]]
+name = "rpds-py"
+version = "2026.6.3"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+resolution-markers = [
+ "python_full_version >= '3.14'",
+ "python_full_version >= '3.11' and python_full_version < '3.14'",
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3.tar.gz", hash = "sha256:1cebd1337c242e4ec2293e541f712b2da849b29f48f0c293684b71c0632625d4" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:7b689145a1485c335569bd056464f3243a29af7ed3871c7be31ad624ba239bc7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:db08f45aecde626498fb3df07bcf6d2ec040af42e859a4f5040d79c200342911" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:acc992ab27b15f852c76755eb2ab7dce86585ddadba6fa5946e58556088845b4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f88d653e7b3b779d71ae7454e20dcc9b6bae903f33c269db9f2be41bda3f261" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e52655eaf81e32593abedaa4bfe33170c8cfedf3365ed9be6e11e07f148f0278" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dfcc8b909769d19db55c7cc9541eb64b9b774b1057ffffb4f1048070475bb9f9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c1255b302953c86a486b81d330d5ee1d5bd937691ce271b6be0ef0e299eaab7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:8d2294a31386bfa251d8c8a39472beee17db67d4f1a6eabea665d35c9a4461c3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f8f23ead891a3b762f35ab3b04623da7056545b48aa60d59957e6789914545da" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:421aba32367055614287a4292b6a17f1939c9452299f7a0209c117e990b646d4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1e5822dfc2f0d4ab7e745eaa6d85945069329beeccef965af3f3bb26058fcab6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:83e35b57523816c8613fd0776b40cd8bb9f596b37ddd2692eb4a6bb5ab2f8c93" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp311-cp311-win32.whl", hash = "sha256:de3eceba0b683bcbb1ab93da016d0270df1f9ae7be716b40214c5dafac6ea45a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:2c54a076ca4d370980ab57bc0e31df57bbe8d41340436a90ef8b1219a3cbb127" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp311-cp311-win_arm64.whl", hash = "sha256:168c733a7112e071bb7a66460e667edfcff06c017a3c523f7a8a8e08d0140804" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a0811d33247c3d6128a3001d763f2aa056bb3425204335400ac54f89eec3a0d0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:538949e262e46caa31ac01bdb3c1e8f642622922cacbabbae6a8445d9dc33eaf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55927d532399c2c646100ff7feb48eaa940ad70f42cd68e1328f3ded9f81ca24" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f56f1695bc5c0871cbc33dc0130fcf503aab0c57dcc5a6700a4f49eba4f2652e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:270b293dae9058fc9fcedab50f13cebf46fb8ed1d1d54e0521a9da5d6b211975" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:127565fead0a10943b282957bd5447804ff3160ad79f2ad2635e6d249e380680" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecabd69db66de867690f9797f2f8fa27ba501bbc24540cbdbdc649cd15888ba6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:58eadac9cd119677b60e1cf8ac4052f35949d71b8a9e5556efccbe82533cf22a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7491ee23305ac3eb59e492b6945881f5cd77a6f731061a3f25b77fd40f9e99a4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2c99f7e8ccb3dd6e3e4bfeac657a7b208c9bac8075f4b078c02d7404c34107fa" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:62698275682bf121181861295c9181e789030a2d516071f5b8f3c23c170cd0fc" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a214c993455f99a89aaeadc9b21241900037adc9d97203e374d75513c5911822" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp312-cp312-win32.whl", hash = "sha256:501f9f04a588d6a09179368c57071301445191767c64e4b52a6aa9871f1ef5ed" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:2c958bf94822e9290a40aaf2a822d4bc5c88099093e3948ad6c571eca9272e5f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp312-cp312-win_arm64.whl", hash = "sha256:22bffe6042b9bcb0822bcd1955ec00e245daf17b4344e4ed8e9551b976b63e96" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3cfe765c1da0072636ca06628261e0ea05688e160d5c8a03e0217c3854037223" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f4d78253f6996be4901669ad25319f842f740eccf4d58e3c7f3dd39e6dde1d8f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54f45a148e28767bf343d33a684693c70e451c6f4c0e9904709a723fafbdfc1f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:842e7b070435622248c7a2c44ae53fa1440e073cc3023bc919fed570884097a7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8020133a74bd81b4572dd8e4be028a6b1ebcd70e6726edc3918008c08bee6ee6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cdc7e35386f3847df728fbcb5e887e2d79c19e2fa1eba9e51b6621d23e3243af" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acac386b453c2516111b50985d60ce46e7fadb5ea71ae7b25f4c946935bf27cf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:425560c6fa0415f27261727bb20bd097568485e5eb0c121f1949417d1c516885" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a550fb4950a06dde3beb4721f5ad4b25bf4513784665b0a8522c792e2bd822a4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f4bca01b63096f606e095734dd56e74e175f94cfbf24ff3d63281cec61f7bb7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ccffae9a092a00deb7efd545fe5e2c33c33b88e7c054337e9a74c179347d0b7d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1cf01971c4f2c5553b772a542e4aaf191789cd331bc2cd4ff0e6e65ba49e1e97" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp313-cp313-win32.whl", hash = "sha256:8c3d1e9c15b9d51ca0391e13da1a25a0a4df3c58a37c9dc368e0736cf7f69df0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:9250a9a0a6fd4648b3f868da8d91a4c52b5811a62df58e753d50ae4454a36f80" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp313-cp313-win_arm64.whl", hash = "sha256:900a67df3fd1660b035a4761c4ce73c382ea6b35f90f9863c36c6fd8bf8b09bb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:931908d9fc855d8f74783377822be318edb6dcb19e47169dc038f9a1bf60b06e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d7469697dce35be237db177d42e2a2ee26e6dcc5fc052078a6fefabd288c6edd" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcfbcf66006befb9fd2aeaa9e01feaf881b4dc330a02ba07d2322b1c11be7b5d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847927daf4cffbd4e90e42bc890069897101edd015f956cb8721b3473372edda" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aca6c1ef08a82bfe327cc156da694660f599923e2e6665b6d81c9c2d0ac9ffc8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ae50181a047c871561212bb97f7932a2d45fb53e947bd9b57ebad85b529cbc53" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc319e5a1de4b6913aac94bf6a2f9e847371e0a140a43dd4991db1a09bc2d504" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:e4316bf32babbed84e691e352faf967ce2f0f024174a8643c37c94a1080374fc" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8c6e5a2f750cc71c3e3b11d71661f21d6f9bc6cebc6564b1466417a1ec03ec77" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4470ce197d4090875cf6affbf1f853338387428df97c4fb7b7106317b8214698" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ea964164cc9afa72d4d9b23cc28dafae93693c0a53e0b42acbff15b22c3f9ddd" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:639c8929aa0afe81be836b04de888460d6bed38b9c54cfc18da8f6bfabf5af5d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314-win32.whl", hash = "sha256:882076c00c0a608b131187055ddc5ae29f2e7eaf870d6168980420d58528a5c8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314-win_amd64.whl", hash = "sha256:0be972be84cfcaf46c8c6edf690ca0f154ac17babf1f6a955a51579b34ad2dc5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314-win_arm64.whl", hash = "sha256:2a9c6f195058cb45335e8cc3802745c603d716eb96bc9625950c1aac71c0c703" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:f90938e92afda60266da758ee7d363447f7f0138c9559f9e1811629580582d90" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ec829541c45bca16e61c7ae50c20501f213605beb75d1aba91a6ee37fbbb56a4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd70d95892096cdb26f15a00c45907b17817577aa8d1c76b2dcc2788391f9e9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29dfa0533a5d4c94d4dfa1b694fcb56c9c63aad8330ffdd816fd225d0a7a162f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:af05d726809bff6b141be124d4c7ce998f9c9c7f30edb1f46c07aa103d540b41" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9826217f048f620d9a712672818bf231442c1b35d96b227a07eabd11b4bb6945" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:536bceea4fa4acf7e1c61da2b5786304367c816c8895be71b8f537c480b0ea1f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:bc0011654b91cc4fb2ae701bec0a0ba1e552c0714247fa7af6c59e0ccfa3a4e1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:539d75de9e0d536c84ff18dfeb805398e58227001ce09231a26a08b9aed1ee0e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:166cf54d9f44fc6ceb53c7860258dde44a81406646de79f8ed3234fca3b6e538" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:d34c20167764fbcf927194d532dd7e0c56772f0a5f943fa5ef9e9afbba8fb9db" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ea7bb13b7c9a29791f87a0387ba7d3ad3a6d783d827e4d3f27b40a0ff44495e2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314t-win32.whl", hash = "sha256:6de4744d05bd1aa1be4ed7ea1189e3979196808008113bbbf899a460966b925e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp314-cp314t-win_amd64.whl", hash = "sha256:c7b9a2f8f4d8e90af72571d3d495deebdd7e3c75451f5b41719aee166e940fc2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315-macosx_10_12_x86_64.whl", hash = "sha256:e059c5dde6452b44424bd1834557556c226b57781dee1227af23518459722b13" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2f7c26fbc5acd2522b95d4177fe4710ffd8e9b20529e703ffbf8db4d93903f05" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3086b538543802f84c843911242db20447de00d8752dd0efc936dbcf02218ba" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8f2e5c5ee828d42cb11760761c0af6507927bec42d0ad5458f97c9203b054617" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed0c1e5d10cdc7135537988c74a0188da68e2f3c30813ba3744ab1e42e0480f9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c2642a7603ec0b16ed77da4555db3b4b472341904873788327c0b0d7b95f1bb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e4320744c1ffdd95a603def63344bfab2d33edeab301c5007e7de9f9f5b3885" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315-manylinux_2_31_riscv64.whl", hash = "sha256:a9f4645593036b81bbdb36b9c8e0ea0d1c3fee968c4d59db0344c14087ef143a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e55d236be29255554da47abe5c577637db7c24a02b8b46f0ca9524c855801868" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:24e9c5386e16669b674a69c156c8eeefcb578f3b3397b713b08e6d60f3c7b187" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:c60924535c75f1566b6eb75b5c31a48a43fef04fa2d0d201acbad8a9969c6107" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:38a2fea2787428f811719ceb9114cb78964a3138838320c29ac39526c79c16ba" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315-win32.whl", hash = "sha256:d483fe17f01ad64b7bf7cc38fcefff1ca9fb83f8c2b2542b68f97ffe0611b369" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315-win_amd64.whl", hash = "sha256:67e3a721ffc5d8d2210d3671872298c4a84e4b8035cfe42ffd7cde35d772b146" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315-win_arm64.whl", hash = "sha256:6e84adbcf4bf841aed8116a8264b9f50b4cb3e7bd89b516122e616ac56ca269e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315t-macosx_10_12_x86_64.whl", hash = "sha256:ae6dd8f10bd17aad820876d24caec9efdafd80a318d16c0a48edb5e136902c6b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:bdbd97738551fca3917c1bd7188bec1920bb520104f28e7e1007f9ceb17b7690" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b95977e7211527ab0ba576e286d023389fbeeb32a6b7b771665d333c60e5342" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15fde0e6fb0d88a60d221204873743e5d9f0b7d29165e62cd86d0413ad74ba6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a136d453475ac0fcbda502ef1e6504bd28d6d904700915d278deeab0d00fe140" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f826877d462181e5eb1c26a0026b8d0cab05d99844ecb6d8bf3627a2ca0c0442" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79486287de1730dbaff3dbd124d0ca4d2ef7f9d29bf2544f1f93c09b5bcbbd12" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_31_riscv64.whl", hash = "sha256:808345f53cb952433ca2816f1604ff3515608a81784954f38d4452acfe8e61d5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1967debc37f64f2c4dc90a7f563aec558b471966e12adcac4e1c4240496b6ebf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:f0840b5b17057f7fd918b76183a4b5a0635f43e14eb2ce60dce1d4ee4707ea00" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:faa679d19a6696fd54259ad321251ad77a13e70e03dd834daa762a44fb6196ef" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:23a439f31ccbeff1574e24889128821d1f7917470e830cf6544dced1c662262a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315t-win32.whl", hash = "sha256:913ca42ccad3f8cc6e292b587ae8ae49c8c823e5dce51a736252fc7c7cdfa577" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-cp315-cp315t-win_amd64.whl", hash = "sha256:ae3d4fe8c0b9213624fdce7279d70e3b148b682ca20719ebd193a23ebfa47324" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:4cf2d36a2357e4d07bb5a4f98801265327b48256867816cfd2ceb001e9754a8f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:30c6dc199b24a5e3e81d50da0f00858c5bbdb2617a750395687f4339c5818171" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9891e594296ab9dada6551c8e7b387b2721f27a67eecd528412e8906247a7b90" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b5c2dc92304aa48a4a60443b548bb12f12e119d4b72f314015e67b9e1be97fca" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:127e08c0642d880cf32ca47ec2a4a77b901f7e2dd1ad9762adb13955d72ffcc9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8bb68f03f395eb793220b45c097bd4d8c32944393da0fad8b999efac0868fc8c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3450b693fde92133e9f51060568a4c31fcca76d5e53bbd611e689ca446517e9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:5e8d07bddee435a2ff6f1920e18feff28d0bc4533e42f4bf6927fbd073312c41" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3a83ae6c67b7676b9878378547ca8e93ed77a580037bcbcd1d32f739e1e6089c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2bfd04c19ddbd6640de0b51894d764bd2758854d5b75bd102d2ef10cb9c293a9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:ca6546b66be9dc4738b1b043d5ebd5488c66c578c5ff0fd0e8065313fe3afb76" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/rpds-py/rpds_py-2026.6.3-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:8e65860d238379ed982fd9ba690579b5e95af2f4840f99c772816dbe573cb826" },
+]
+
+[[package]]
+name = "sniffio"
+version = "1.3.1"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/sniffio/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/sniffio/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2" },
+]
+
+[[package]]
+name = "starlette"
+version = "1.6.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "anyio" },
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/starlette/starlette-1.6.0.tar.gz", hash = "sha256:d4e3ac5e546444960c710297a3c9fc3f7ebae1b7e963f3d36173b49da535be9b" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/starlette/starlette-1.6.0-py3-none-any.whl", hash = "sha256:a86dd39d14bb45f85a3d18525215a9ef0cfd1f192ac793220e72598c90335f0c" },
+]
+
+[[package]]
+name = "tenacity"
+version = "9.1.4"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/tenacity/tenacity-9.1.4.tar.gz", hash = "sha256:adb31d4c263f2bd041081ab33b498309a57c77f9acf2db65aadf0898179cf93a" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/tenacity/tenacity-9.1.4-py3-none-any.whl", hash = "sha256:6095a360c919085f28c6527de529e76a06ad89b23659fa881ae0649b867a9d55" },
+]
+
+[[package]]
+name = "typing-extensions"
+version = "4.16.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/typing-extensions/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/typing-extensions/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8" },
+]
+
+[[package]]
+name = "typing-inspection"
+version = "0.4.4"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "typing-extensions" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/typing-inspection/typing_inspection-0.4.4.tar.gz", hash = "sha256:547274fa6b0a561ccf549cc9524b999a578e737d015d8709d021f9d0d13bea47" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/typing-inspection/typing_inspection-0.4.4-py3-none-any.whl", hash = "sha256:65b8397ba37ccbce054456aaccddfc91e6e3083c92824df348d96ca832f3f147" },
+]
+
+[[package]]
+name = "tzdata"
+version = "2026.3"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/tzdata/tzdata-2026.3.tar.gz", hash = "sha256:4a1518b8993086a7982523e071643f3c0e5f213e75b21318e78bcabfff9d1415" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/tzdata/tzdata-2026.3-py2.py3-none-any.whl", hash = "sha256:dc096730c87af6cab1b171c9d532be840741ff5d459015e7f6947bd7d7e54931" },
+]
+
+[[package]]
+name = "tzlocal"
+version = "5.4.4"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "tzdata", marker = "sys_platform == 'win32'" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/tzlocal/tzlocal-5.4.4.tar.gz", hash = "sha256:8dbb8660838688a7b6ba4fed31d18dedf842afb4d47ca050d6d891c2c15f3be4" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/tzlocal/tzlocal-5.4.4-py3-none-any.whl", hash = "sha256:aae09f0126a8a86fa736be266eb4a471380d26a0de3bc14844e7821fee3e2a15" },
+]
+
+[[package]]
+name = "urllib3"
+version = "2.7.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/urllib3/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/urllib3/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897" },
+]
+
+[[package]]
+name = "uvicorn"
+version = "0.52.4"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "click" },
+ { name = "h11" },
+ { name = "typing-extensions", marker = "python_full_version < '3.11'" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/uvicorn/uvicorn-0.52.4.tar.gz", hash = "sha256:73acfee47a0b133c5de13d219492d62d8a31e935f4fe6e41a232451a15379f86" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/uvicorn/uvicorn-0.52.4-py3-none-any.whl", hash = "sha256:f86e41a149d7d05a9969337e3946a9c171c06a5d42680896daaba624aeac8da1" },
+]
+
+[[package]]
+name = "watchdog"
+version = "6.0.0"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/watchdog/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f" },
+]
+
+[[package]]
+name = "websockets"
+version = "15.0.1"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d63efaa0cd96cf0c5fe4d581521d9fa87744540d4bc999ae6e08595a1014b45b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac60e3b188ec7574cb761b08d50fcedf9d77f1530352db4eef1707fe9dee7205" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5756779642579d902eed757b21b0164cd6fe338506a8083eb58af5c372e39d9a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fdfe3e2a29e4db3659dbd5bbf04560cea53dd9610273917799f1cde46aa725e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c2529b320eb9e35af0fa3016c187dffb84a3ecc572bcee7c3ce302bfeba52bf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac1e5c9054fe23226fb11e05a6e630837f074174c4c2f0fe442996112a6de4fb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5df592cd503496351d6dc14f7cdad49f268d8e618f80dce0cd5a36b93c3fc08d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0a34631031a8f05657e8e90903e656959234f3a04552259458aac0b0f9ae6fd9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d00075aa65772e7ce9e990cab3ff1de702aa09be3940d1dc88d5abf1ab8a09c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp310-cp310-win32.whl", hash = "sha256:1234d4ef35db82f5446dca8e35a7da7964d02c127b095e172e54397fb6a6c256" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:39c1fec2c11dc8d89bba6b2bf1556af381611a173ac2b511cf7231622058af41" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d99e5546bf73dbad5bf3547174cd6cb8ba7273062a23808ffea025ecb1cf8562" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66dd88c918e3287efc22409d426c8f729688d89a0c587c88971a0faa2c2f3792" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dd8327c795b3e3f219760fa603dcae1dcc148172290a8ab15158cf85a953413" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8fdc51055e6ff4adeb88d58a11042ec9a5eae317a0a53d12c062c8a8865909e8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:693f0192126df6c2327cce3baa7c06f2a117575e32ab2308f7f8216c29d9e2e3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp311-cp311-win32.whl", hash = "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp312-cp312-win32.whl", hash = "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/websockets/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f" },
+]
+
+[[package]]
+name = "yarl"
+version = "1.24.5"
+source = { registry = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/simple/" }
+dependencies = [
+ { name = "idna" },
+ { name = "multidict" },
+ { name = "propcache" },
+]
+sdist = { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5.tar.gz", hash = "sha256:e81b83143bee16329c23db3c1b2d82b29892fcbcb849186d2f6e98a5abe9a57f" }
+wheels = [
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88f50c94e21a0a7f14042c015b0eba1881af78562e7bf007e0033e624da59750" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6efbccc3d7f75d5b03105172a8dc86d82ba4da86817952529dd93185f4a88be2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0ebfaffe1a16cb72141c8e09f18cc76856dbe58639f393a4f2b26e474b96b871" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8ac73abdc7ab75610f95a8fd994c6457e87752b02a63987e188f937a1fc180f0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4d97a951a81039050e45f04e96689b58b8243fa5e62aa14fe67cb6075300885e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fe7b7bb170daccbba19ad33012d2b15f1e7942296fd4d45fc1b79013da8cc0f2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:89a1bbb58e0e3f7a283653d854b1e95d65e5cfd4af224dac5f02629ec1a3e621" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7fa5e51397466ea7e98de493fa2ff1b8193cfef8a7b0f9b4842f92d342df0dba" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4103b77b8a8225e413107d2349b65eb3c1c52627b5cc5c3c4c1c6a798b218950" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f9f3e9c8a9ecffa57bef8fb4fa19e5fa4d2d8307cf6bac5b1fca5e5860f4ba00" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c0ebc836c47a6477e182169c6a476fc691d12b518894bf7dd2572f0d59f1c7ed" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:96d30286dd02679e32a39aa8f0b7498fc847fcda46cfc09df5513e82ce252440" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:fd8c81f346b58f45818d09ea11db69a8d5fd34a224b79871f6d44f12cd7977b1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:5c55256dee8f4b27bfbf636c8363383c7c8db7890c7cba5217d7bd5f5f21dab6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9f4d8cf085a4c6a40fb97ea0f46938a8df43c85d31f9d45e2a8867ea9293790d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp310-cp310-win_amd64.whl", hash = "sha256:240cbec09667c1fed4c6cd0060b9ec57332427d7441289a2ed8875dc9fb2b224" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp310-cp310-win_arm64.whl", hash = "sha256:8a6987eaad834cb32dd57d9d582225f0054a5d1af706ccfbbdba735af4927e13" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2c1fe720934a16ea8e7146175cba2126f87f54912c8c5435e7f7c7a51ef808d3" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c687ed078e145f5fd53a14854beff320e1d2ab76df03e2009c98f39a0f68f39a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:709f1efed56c4a145793c046cd4939f9959bcd818979a787b77d8e09c57a0840" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:874019bd513008b009f58657134e5d0c5e030b3559bd0553976837adf52fe966" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:a4582acf7ef76482f6f511ebaf1946dae7f2e85ec4728b81a678c01df63bd723" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2cabe6546e41dabe439999a23fcb5246e0c3b595b4315b96ef755252be90caeb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:17f57620f5475b3c69109376cc87e42a7af5db13c9398e4292772a706ff10780" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:570fec8fbd22b032733625f03f10b7ff023bc399213db15e72a7acaef28c2f4e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5fede79c6f73ff2c3ef822864cb1ada23196e62756df53bc6231d351a49516a2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8ccf9aca873b767977c73df497a85dbedee4ee086ae9ae49dc461333b9b79f58" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:ad5d8201d310b031e6cd839d9bac2d4e5a01533ce5d3d5b50b7de1ef3af1de61" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:841f0852f48fefea3b12c9dfec00704dfa3aef5215d0e3ce564bb3d7cd8d57c6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:9baafc71b04f8f4bb0703b21d6fc9f0c30b346c636a532ff16ec8491a5ea4b1f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:d897129df1a22b12aeed2c2c98df0785a2e8e6e0bde87b389491d0025c187077" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dd625535328fd9882374356269227670189adfcc6a2d90284f323c05862eecbd" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp311-cp311-win_amd64.whl", hash = "sha256:f4239bbec5a3577ddb49e4b50aeb32d8e5792098262ae2f63723f916a29b1a25" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp311-cp311-win_arm64.whl", hash = "sha256:3ac6aff147deb9c09461b2d4bbdf6256831198f5d8a23f5d37138213090b6d8a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d693396e5aea78db03decd60aec9ece16c9b40ba00a587f089615ff4e718a81d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3363fcc96e665878946ad7a106b9a13eac0541766a690ef287c0232ac768b6ec" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9d399bdcfb4a0f659b9b3788bbc89babe63d9a6a65aacdf4d4e7065ff2e6316c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90333fd89b43c0d08ac85f3f1447593fc2c66de18c3d6378d7125ea118dc7a54" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:665b0a2c463cc9423dd647e0bfd9f4ccc9b50f768c55304d5e9f80b177c1de12" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e006d3a974c4ee19512e5f058abedb6eef36a5e553c14812bdeba1758d812e6d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e7d42c531243450ef0d4d9c172e7ed6ef052640f195629065041b5add4e058d1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f08c7513ecef5aad65687bfdf6bc601ae9fccd04a42904501f8f7141abad9eb9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6c95b17fe34ed802f17e205112e6e10db92275c34fee290aa9bdc55a9c724027" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:56b149b22de33b23b0c6077ab9518c6dcb538ad462e1830e68d06591ccf6e38b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:a8fe66b8f300da93798025a785a5b90b42f3810dc2b72283ff84a41aaaebc293" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:377fe3732edbaf78ee74efdf2c9f49f6e99f20e7f9d2649fda3eb4badd77d76e" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e8ffa78582120024f476a611d7befc123cee59e47e8309d470cf667d806e613b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:daba5e594f06114e37db186efd2dd916609071e59daca901a0a2e71f02b142ce" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:65be18ec59496c13908f02a2472751d9ef840b4f3fb5726f129306bf6a2a7bba" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp312-cp312-win_amd64.whl", hash = "sha256:a929d878fec099030c292803b31e5d5540a7b6a31e6a3cc76cb4685fc2a2f51b" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp312-cp312-win_arm64.whl", hash = "sha256:7ce27823052e2013b597e0c738b13e7e36b8ccb9400df8959417b052ab0fd92c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:79af890482fc94648e8cde4c68620378f7fef60932710fa17a66abc039244da2" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:46c2f213e23a04b93a392942d782eb9e413e6ef6bf7c8c53884e599a5c174dcb" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92ab3e11448f2ff7bf53c5a26eff0edc086898ec8b21fb154b85839ce1d88075" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ebb0ec7f17803063d5aeb982f3b1bd2b2f4e4fae6751226cbd6ba1fcfe9e63ff" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:82632daed195dcc8ea664e8556dc9bdbd671960fb3776bd92806ce05792c2448" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:53e549287ef628fecba270045c9701b0c564563a9b0577d24a4ec75b8ab8040f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fcd3b77e2f17bbe4ca56ec7bcb07992647d19d0b9c05d84886dcd6f9eb810afd" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d46b86567dd4e248c6c159fcbcdcce01e0a5c8a7cd2334a0fff759d0fa075b16" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7f72c74aa99359e27a2ee8d6613fefa28b5f76a983c083074dfc2aaa4ab46213" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3f45789ce415a7ec0820dc4f82925f9b5f7732070be1dec1f5f23ec381435a24" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6e73e7fe93f17a7b191f52ec9da9dd8c06a8fe735a1ecbd13b97d1c723bff385" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4a36f9becdd4c5c52a20c3e9484128b070b1dcfc8944c006f3a528295a359a9c" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:7bcbe0fcf850eae67b6b01749815a4f7161c560a844c769ad7b48fcd99f791c4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:24e861e9630e0daddcb9191fb187f60f034e17a4426f8101279f0c475cd74144" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9335a099ad87287c37fe5d1a982ff392fa5efe5d14b40a730b1ec1d6a41382b4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp313-cp313-win_amd64.whl", hash = "sha256:2dbe06fc16bc91502bca713704022182e5729861ae00277c3a23354b40929740" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp313-cp313-win_arm64.whl", hash = "sha256:6b8536851f9f65e7f00c7a1d49ba7f2be0ffe2c11555367fc9f50d9f842410a1" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:2729fcfc4f6a596fb0c50f32090400aa9367774ac296a00387e65098c0befa76" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:ff330d3c30db4eb6b01d79e29d2d0b407a7ecad39cfd9ec993ece57396a2ec0d" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e42d75862735da90e7fc5a7b23db0c976f737113a54b3c9777a9b665e9cbff75" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a3732e66413163e72508da9eff9ce9d2846fde51fae45d3605393d3e6cd303e9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5b8ee53be440a0cffc991a27be3057e0530122548dbe7c0892df08822fce5ede" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:af3aefa655adb5869491fa907e652290386800ae99cc50095cba71e2c6aefdca" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2120b96872df4a117cde97d270bac96aea7cc52205d305cf4611df694a487027" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:66410eb6345d467151934b49bfa70fb32f5b35a6140baa40ad97d6436abea2e9" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4af7b7e1be0a69bee8210735fe6dcfc38879adfac6d62e789d53ba432d1ffa41" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fa139875ff98ab97da323cfadfaff08900d1ad42f1b5087b0b812a55c5a06373" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:0055afc45e864b92729ac7600e2d102c17bef060647e74bca75fa84d66b9ff36" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:f0e466ed7511fe9d459a819edbc6c2585c0b6eabde9fa8a8947552468a7a6ef0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:f141474e85b7e54998ec5180530a7cda99ab29e282fa50e0756d89981a9b43c5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:e2935f8c39e3b03e83519292d78f075189978f3f4adc15a78144c7c8e2a1cba5" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9d1216a7f6f77836617dba35687c5b78a4170afc3c3f18fc788f785ba26565c4" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314-win_amd64.whl", hash = "sha256:5ba4f78df2bcc19f764a4b26a8a4f5049c110090ad5825993aacb052bf8003ad" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314-win_arm64.whl", hash = "sha256:9e4e16c73d717c5cf27626c524d0a2e261ad20e46932b2670f64ad5dde23e26f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:e1ae548a9d901adca07899a4147a7c826bbcc06239d3ce9a59f57886a28a4c88" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:ff405d91509d88e8d44129cd87b18d70acd1f0c1aeabd7bc3c46792b1fe2acba" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:47e98aab9d8d82ff682e7b0b5dded33bf138a32b817fcf7fa3b27b2d7c412928" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f0a658a6d3fafee5c6f63c58f3e785c8c43c93fbc02bf9f2b6663f8185e0971f" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4377407001ca3c057773f44d8ddd6358fa5f691407c1ba92210bd3cf8d9e4c95" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7c0494a31a1ac5461a226e7947a9c9b78c44e1dc7185164fa7e9651557a5d9bc" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a7cff474ab7cd149765bb784cf6d78b32e18e20473fb7bda860bce98ab58e9da" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cbb833ccacdb5519eff9b8b71ee618cc2801c878e77e288775d77c3a2ced858a" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:82f75e05912e84b7a0fe57075d9c59de3cb352b928330f2eb69b2e1f54c3e1f0" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:16a2f5010280020e90f5330257e6944bc33e73593b136cc5a241e6c1dc292498" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:ffcd54362564dc1a30fb74d8b8a6e5a6b11ebd5e27266adc3b7427a21a6c9104" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0465ec8cedc2349b97a6b595ace64084a50c6e839eca40aa0626f38b8350e331" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:4db9aecb141cb7a5447171b57aa1ed3a8fee06af40b992ffc31206c0b0121550" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:f540c013589084679a6c7fac07096b10159737918174f5dfc5e11bf5bca4dfe6" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a61834fb15d81322d872eaafd333838ae7c9cea84067f232656f75965933d047" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314t-win_amd64.whl", hash = "sha256:5c88e5815a49d289e599f3513aa7fde0bc2092ff188f99c940f007f90f53d104" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-cp314-cp314t-win_arm64.whl", hash = "sha256:cf139c02f5f23ef6532040a30ff662c00a318c952334f211046b8e60b7f17688" },
+ { url = "http://airlock-proxy.uplink.goog:999/python/artifact-foundry-prod/ah-3p-staging-python/yarl/yarl-1.24.5-py3-none-any.whl", hash = "sha256:a33700d13d9b7d84fd10947b09ff69fb9a792e519c8cb9764a3ca70baa6c23a7" },
+]
diff --git a/samples/community/yarn.lock b/samples/community/yarn.lock
index a5171ba747..4d98e596b0 100644
--- a/samples/community/yarn.lock
+++ b/samples/community/yarn.lock
@@ -129,6 +129,46 @@ __metadata:
languageName: unknown
linkType: soft
+"@a2ui/react@npm:^0.10.2":
+ version: 0.10.2
+ resolution: "@a2ui/react@npm:0.10.2"
+ dependencies:
+ "@a2ui/markdown-it": "npm:*"
+ "@a2ui/web_core": "npm:^0.10.5"
+ clsx: "npm:^2.1.1"
+ markdown-it: "npm:^14.2.0"
+ zod: "npm:^3.25.76"
+ peerDependencies:
+ react: ^19.2.7
+ react-dom: ^19.2.7
+ zod: ^3.25.76
+ checksum: 10c0/61db572c7f57079052d452233f58cce68e9e35b72d7b004e702741304f866960d0045d976f354c15dfac223981b1a92550bbc6870ba1002df6ca9670ed45968e
+ languageName: node
+ linkType: hard
+
+"@a2ui/templates-community-demo@workspace:templates/client":
+ version: 0.0.0-use.local
+ resolution: "@a2ui/templates-community-demo@workspace:templates/client"
+ dependencies:
+ "@a2ui/react": "npm:^0.10.2"
+ "@a2ui/web_core": "npm:^0.10.6"
+ "@types/node": "npm:^25.9.3"
+ "@types/react": "npm:^19.2.17"
+ "@types/react-dom": "npm:^19.2.3"
+ "@vitejs/plugin-react": "npm:^6.0.2"
+ eslint: "npm:^10.4.1"
+ eslint-config-prettier: "npm:^10.1.8"
+ eslint-plugin-react: "npm:^7.37.5"
+ eslint-plugin-react-hooks: "npm:^7.1.1"
+ react: "npm:^19.2.7"
+ react-dom: "npm:^19.2.7"
+ typescript: "npm:5.9.3"
+ typescript-eslint: "npm:^8.61.0"
+ vite: "npm:^8.0.16"
+ wireit: "npm:^0.15.0-pre.2"
+ languageName: unknown
+ linkType: soft
+
"@a2ui/web_core@npm:^0.10.0":
version: 0.10.0
resolution: "@a2ui/web_core@npm:0.10.0"
@@ -141,6 +181,18 @@ __metadata:
languageName: node
linkType: hard
+"@a2ui/web_core@npm:^0.10.5, @a2ui/web_core@npm:^0.10.6":
+ version: 0.10.6
+ resolution: "@a2ui/web_core@npm:0.10.6"
+ dependencies:
+ "@preact/signals-core": "npm:^1.14.2"
+ date-fns: "npm:^4.4.0"
+ zod: "npm:^3.25.76"
+ zod-to-json-schema: "npm:^3.25.2"
+ checksum: 10c0/481b90b4caa1428b3fa8344ab0ef5a515545e8fa6ef62e2fa6121968f80a2aab329e48be002e4590f770bd479872aa5963a5db00b12e75e063e2c7846234654b
+ languageName: node
+ linkType: hard
+
"@algolia/abtesting@npm:1.14.1":
version: 1.14.1
resolution: "@algolia/abtesting@npm:1.14.1"
@@ -842,6 +894,17 @@ __metadata:
languageName: node
linkType: hard
+"@babel/parser@npm:^7.24.4":
+ version: 7.29.8
+ resolution: "@babel/parser@npm:7.29.8"
+ dependencies:
+ "@babel/types": "npm:^7.29.8"
+ bin:
+ parser: ./bin/babel-parser.js
+ checksum: 10c0/acc890c5e6a6dd40863a47b50bac111d7185ee6fbbe163ebe11d5214854ca2adb901462ad4d718a65090ef84bd2230e9e8ab45a2e0caccc685f1f57ab0bb1e28
+ languageName: node
+ linkType: hard
+
"@babel/template@npm:^7.28.6, @babel/template@npm:^7.29.7":
version: 7.29.7
resolution: "@babel/template@npm:7.29.7"
@@ -878,6 +941,16 @@ __metadata:
languageName: node
linkType: hard
+"@babel/types@npm:^7.29.8":
+ version: 7.29.8
+ resolution: "@babel/types@npm:7.29.8"
+ dependencies:
+ "@babel/helper-string-parser": "npm:^7.29.7"
+ "@babel/helper-validator-identifier": "npm:^7.29.7"
+ checksum: 10c0/be7c279f0abf2a086c633e21b49c7ca80275d05283cc5a268b67a708c9914bd0c944f1422b3eb3cb37682a2af5d560abf520ccf9b01b53ecbfe6b71fbc3fdde6
+ languageName: node
+ linkType: hard
+
"@bramus/specificity@npm:^2.4.2":
version: 2.4.2
resolution: "@bramus/specificity@npm:2.4.2"
@@ -1231,6 +1304,17 @@ __metadata:
languageName: node
linkType: hard
+"@eslint-community/eslint-utils@npm:^4.9.1":
+ version: 4.10.1
+ resolution: "@eslint-community/eslint-utils@npm:4.10.1"
+ dependencies:
+ eslint-visitor-keys: "npm:^3.4.3"
+ peerDependencies:
+ eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+ checksum: 10c0/b514586655698bc6b74db72a496c77e813c78b63e36a83429845ac7057dd77113b0b6c31e6e590d5baaeee2abae6ea22363a41209bcafa078d895ab83ce83011
+ languageName: node
+ linkType: hard
+
"@eslint-community/regexpp@npm:^4.12.2":
version: 4.12.2
resolution: "@eslint-community/regexpp@npm:4.12.2"
@@ -3270,6 +3354,13 @@ __metadata:
languageName: node
linkType: hard
+"@preact/signals-core@npm:^1.14.2":
+ version: 1.14.4
+ resolution: "@preact/signals-core@npm:1.14.4"
+ checksum: 10c0/963622e5c1c98a6946ec1ad01e9901ebacf316ab0a7e3c56c6ebaefee5b2c8ea03c3bdb8ba74120612b5f8976f5dc94693134670e372dded79db9994045aadd1
+ languageName: node
+ linkType: hard
+
"@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2":
version: 1.1.2
resolution: "@protobufjs/aspromise@npm:1.1.2"
@@ -4249,7 +4340,7 @@ __metadata:
languageName: node
linkType: hard
-"@rolldown/pluginutils@npm:^1.0.0":
+"@rolldown/pluginutils@npm:^1.0.0, @rolldown/pluginutils@npm:^1.0.1":
version: 1.0.1
resolution: "@rolldown/pluginutils@npm:1.0.1"
checksum: 10c0/99d9b06d90196823e4d8c841f258db7a16e5dbba5824a2962b05d907b79f1ba929d56f22dd744fd530936e568c865ee56a719dc31e57e13bc0a8eb4764a8d8dd
@@ -4796,6 +4887,24 @@ __metadata:
languageName: node
linkType: hard
+"@types/react-dom@npm:^19.2.3":
+ version: 19.2.4
+ resolution: "@types/react-dom@npm:19.2.4"
+ peerDependencies:
+ "@types/react": ^19.2.0
+ checksum: 10c0/b7d854ce17bb51a3a067168268a90f0123d10dc490f63f1ff5409f07ac715febeb8f5b7b473404a9d437106571e0312fc2937a945634d590abfc9aa46a14b01b
+ languageName: node
+ linkType: hard
+
+"@types/react@npm:^19.2.17":
+ version: 19.2.18
+ resolution: "@types/react@npm:19.2.18"
+ dependencies:
+ csstype: "npm:^3.2.2"
+ checksum: 10c0/d04216172b4b4362b310017c210dfbe019fb4f4e7dffd0313e70b3acb3051d5c3e76e7e84e3cf4c6a3c824993ffadfe3949e589a6398a09d4200e7670e2962de
+ languageName: node
+ linkType: hard
+
"@types/request@npm:^2.48.8":
version: 2.48.13
resolution: "@types/request@npm:2.48.13"
@@ -4857,6 +4966,141 @@ __metadata:
languageName: node
linkType: hard
+"@typescript-eslint/eslint-plugin@npm:8.67.0":
+ version: 8.67.0
+ resolution: "@typescript-eslint/eslint-plugin@npm:8.67.0"
+ dependencies:
+ "@eslint-community/regexpp": "npm:^4.12.2"
+ "@typescript-eslint/scope-manager": "npm:8.67.0"
+ "@typescript-eslint/type-utils": "npm:8.67.0"
+ "@typescript-eslint/utils": "npm:8.67.0"
+ "@typescript-eslint/visitor-keys": "npm:8.67.0"
+ ignore: "npm:^7.0.5"
+ natural-compare: "npm:^1.4.0"
+ ts-api-utils: "npm:^2.5.0"
+ peerDependencies:
+ "@typescript-eslint/parser": ^8.67.0
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: ">=4.8.4 <6.1.0"
+ checksum: 10c0/5962baaa764cd6350dfdf51c9a09fdd9ee6be65982ac562ee9b732f851744158e5006bf8ce61556a93534d831be8300fd89d7b79b6b4d7170dc2381d987dc8d9
+ languageName: node
+ linkType: hard
+
+"@typescript-eslint/parser@npm:8.67.0":
+ version: 8.67.0
+ resolution: "@typescript-eslint/parser@npm:8.67.0"
+ dependencies:
+ "@typescript-eslint/scope-manager": "npm:8.67.0"
+ "@typescript-eslint/types": "npm:8.67.0"
+ "@typescript-eslint/typescript-estree": "npm:8.67.0"
+ "@typescript-eslint/visitor-keys": "npm:8.67.0"
+ debug: "npm:^4.4.3"
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: ">=4.8.4 <6.1.0"
+ checksum: 10c0/8f6f8fbea429509ca0c95c4d48a45da0c890172a590606d65587e75a3ca762c3e5678a20a63fc9e386b0b21b7aa643ba9724354ceaa75bc8f62d0b22cb0198c8
+ languageName: node
+ linkType: hard
+
+"@typescript-eslint/project-service@npm:8.67.0":
+ version: 8.67.0
+ resolution: "@typescript-eslint/project-service@npm:8.67.0"
+ dependencies:
+ "@typescript-eslint/tsconfig-utils": "npm:^8.67.0"
+ "@typescript-eslint/types": "npm:^8.67.0"
+ debug: "npm:^4.4.3"
+ peerDependencies:
+ typescript: ">=4.8.4 <6.1.0"
+ checksum: 10c0/d8f89dc209f2186c04fb1c42c1a5c69c21696a7a57c5f2be2222682a6440b49ec32687ae85cbd1c1c164431635fbc37bb9404b336e5748966e270ee1347e028c
+ languageName: node
+ linkType: hard
+
+"@typescript-eslint/scope-manager@npm:8.67.0":
+ version: 8.67.0
+ resolution: "@typescript-eslint/scope-manager@npm:8.67.0"
+ dependencies:
+ "@typescript-eslint/types": "npm:8.67.0"
+ "@typescript-eslint/visitor-keys": "npm:8.67.0"
+ checksum: 10c0/8f1fe7dffcb6929ad66dcdca77dd1e4a703f18ab3ab1d685458af74dad10b9be05795e64bd58ff60b45cda8d45737240c84874674d39140c2689e00e3ee82bb9
+ languageName: node
+ linkType: hard
+
+"@typescript-eslint/tsconfig-utils@npm:8.67.0, @typescript-eslint/tsconfig-utils@npm:^8.67.0":
+ version: 8.67.0
+ resolution: "@typescript-eslint/tsconfig-utils@npm:8.67.0"
+ peerDependencies:
+ typescript: ">=4.8.4 <6.1.0"
+ checksum: 10c0/c19161347ea3d7a0081653c4d399275a3e0d66f87a24131fb5a358e6b55bc27d709781dbda16382f3f721d790338dcf42c65c9e6c26077123e9f3d076d37a894
+ languageName: node
+ linkType: hard
+
+"@typescript-eslint/type-utils@npm:8.67.0":
+ version: 8.67.0
+ resolution: "@typescript-eslint/type-utils@npm:8.67.0"
+ dependencies:
+ "@typescript-eslint/types": "npm:8.67.0"
+ "@typescript-eslint/typescript-estree": "npm:8.67.0"
+ "@typescript-eslint/utils": "npm:8.67.0"
+ debug: "npm:^4.4.3"
+ ts-api-utils: "npm:^2.5.0"
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: ">=4.8.4 <6.1.0"
+ checksum: 10c0/0970ea126f9b63a6eb9ca3525a6bf3065dffb3f61a00bd0ee84967140e7ecffe45cafda0cd2c90233dcc06b19c8fb98f4cd90ba8ebbb12deaf9501b9f5b54d8c
+ languageName: node
+ linkType: hard
+
+"@typescript-eslint/types@npm:8.67.0, @typescript-eslint/types@npm:^8.67.0":
+ version: 8.67.0
+ resolution: "@typescript-eslint/types@npm:8.67.0"
+ checksum: 10c0/b892a00d4cbea9604a0abf6eedd0ea019b27df4220a1d90e0035101cb4f846722c9e3eeadce40b423c1e0240709bbc787c6ca49bcc4f8c25ba23b4bd0436492a
+ languageName: node
+ linkType: hard
+
+"@typescript-eslint/typescript-estree@npm:8.67.0":
+ version: 8.67.0
+ resolution: "@typescript-eslint/typescript-estree@npm:8.67.0"
+ dependencies:
+ "@typescript-eslint/project-service": "npm:8.67.0"
+ "@typescript-eslint/tsconfig-utils": "npm:8.67.0"
+ "@typescript-eslint/types": "npm:8.67.0"
+ "@typescript-eslint/visitor-keys": "npm:8.67.0"
+ debug: "npm:^4.4.3"
+ minimatch: "npm:^10.2.2"
+ semver: "npm:^7.7.3"
+ tinyglobby: "npm:^0.2.15"
+ ts-api-utils: "npm:^2.5.0"
+ peerDependencies:
+ typescript: ">=4.8.4 <6.1.0"
+ checksum: 10c0/449350fcf4f4ee55a6bb7a73302c4eef072a1282d366344cb625c0f17231eb4088251e6ce61fb48d0d536febb9a28f3725b9bd78ac8d0dbf9c161cf51745870c
+ languageName: node
+ linkType: hard
+
+"@typescript-eslint/utils@npm:8.67.0":
+ version: 8.67.0
+ resolution: "@typescript-eslint/utils@npm:8.67.0"
+ dependencies:
+ "@eslint-community/eslint-utils": "npm:^4.9.1"
+ "@typescript-eslint/scope-manager": "npm:8.67.0"
+ "@typescript-eslint/types": "npm:8.67.0"
+ "@typescript-eslint/typescript-estree": "npm:8.67.0"
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: ">=4.8.4 <6.1.0"
+ checksum: 10c0/cccaca1aeba52ec332ee95f3367b84eaf5dd9d60a0d1b4332ebe41b775fa7e8b8faf412de4d88b73a22f84b01f6ab48496c61863407b08fcbef9af429b6b89f1
+ languageName: node
+ linkType: hard
+
+"@typescript-eslint/visitor-keys@npm:8.67.0":
+ version: 8.67.0
+ resolution: "@typescript-eslint/visitor-keys@npm:8.67.0"
+ dependencies:
+ "@typescript-eslint/types": "npm:8.67.0"
+ eslint-visitor-keys: "npm:^5.0.0"
+ checksum: 10c0/d43e6151cd1cdbcfb2f9fa54946198baaebaf0b7a9057ccb2f1aeba1aa3eb46708a97cd7773dcfd0eba3bd45642a5520f4607001cd27d8958e41aa56b2fe7a35
+ languageName: node
+ linkType: hard
+
"@vitejs/plugin-basic-ssl@npm:2.1.4":
version: 2.1.4
resolution: "@vitejs/plugin-basic-ssl@npm:2.1.4"
@@ -4866,6 +5110,24 @@ __metadata:
languageName: node
linkType: hard
+"@vitejs/plugin-react@npm:^6.0.2":
+ version: 6.0.5
+ resolution: "@vitejs/plugin-react@npm:6.0.5"
+ dependencies:
+ "@rolldown/pluginutils": "npm:^1.0.1"
+ peerDependencies:
+ "@rolldown/plugin-babel": ^0.1.7 || ^0.2.0
+ babel-plugin-react-compiler: ^1.0.0
+ vite: ^8.0.0
+ peerDependenciesMeta:
+ "@rolldown/plugin-babel":
+ optional: true
+ babel-plugin-react-compiler:
+ optional: true
+ checksum: 10c0/fb02246fe3652d7fb746190bdd098b9e29918dfcf8c67b9c0c37300ce789e82331b2ba761530ac6ac9a61390b774d44f401787bd1c87a6c866d1e74a745cc1a0
+ languageName: node
+ linkType: hard
+
"@vitest/expect@npm:4.1.9":
version: 4.1.9
resolution: "@vitest/expect@npm:4.1.9"
@@ -5301,6 +5563,98 @@ __metadata:
languageName: node
linkType: hard
+"array-buffer-byte-length@npm:^1.0.1, array-buffer-byte-length@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "array-buffer-byte-length@npm:1.0.2"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ is-array-buffer: "npm:^3.0.5"
+ checksum: 10c0/74e1d2d996941c7a1badda9cabb7caab8c449db9086407cad8a1b71d2604cc8abf105db8ca4e02c04579ec58b7be40279ddb09aea4784832984485499f48432d
+ languageName: node
+ linkType: hard
+
+"array-includes@npm:^3.1.6, array-includes@npm:^3.1.8":
+ version: 3.1.9
+ resolution: "array-includes@npm:3.1.9"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ call-bound: "npm:^1.0.4"
+ define-properties: "npm:^1.2.1"
+ es-abstract: "npm:^1.24.0"
+ es-object-atoms: "npm:^1.1.1"
+ get-intrinsic: "npm:^1.3.0"
+ is-string: "npm:^1.1.1"
+ math-intrinsics: "npm:^1.1.0"
+ checksum: 10c0/0235fa69078abeac05ac4250699c44996bc6f774a9cbe45db48674ce6bd142f09b327d31482ff75cf03344db4ea03eae23edb862d59378b484b47ed842574856
+ languageName: node
+ linkType: hard
+
+"array.prototype.findlast@npm:^1.2.5":
+ version: 1.2.5
+ resolution: "array.prototype.findlast@npm:1.2.5"
+ dependencies:
+ call-bind: "npm:^1.0.7"
+ define-properties: "npm:^1.2.1"
+ es-abstract: "npm:^1.23.2"
+ es-errors: "npm:^1.3.0"
+ es-object-atoms: "npm:^1.0.0"
+ es-shim-unscopables: "npm:^1.0.2"
+ checksum: 10c0/ddc952b829145ab45411b9d6adcb51a8c17c76bf89c9dd64b52d5dffa65d033da8c076ed2e17091779e83bc892b9848188d7b4b33453c5565e65a92863cb2775
+ languageName: node
+ linkType: hard
+
+"array.prototype.flat@npm:^1.3.1":
+ version: 1.3.3
+ resolution: "array.prototype.flat@npm:1.3.3"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ define-properties: "npm:^1.2.1"
+ es-abstract: "npm:^1.23.5"
+ es-shim-unscopables: "npm:^1.0.2"
+ checksum: 10c0/d90e04dfbc43bb96b3d2248576753d1fb2298d2d972e29ca7ad5ec621f0d9e16ff8074dae647eac4f31f4fb7d3f561a7ac005fb01a71f51705a13b5af06a7d8a
+ languageName: node
+ linkType: hard
+
+"array.prototype.flatmap@npm:^1.3.3":
+ version: 1.3.3
+ resolution: "array.prototype.flatmap@npm:1.3.3"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ define-properties: "npm:^1.2.1"
+ es-abstract: "npm:^1.23.5"
+ es-shim-unscopables: "npm:^1.0.2"
+ checksum: 10c0/ba899ea22b9dc9bf276e773e98ac84638ed5e0236de06f13d63a90b18ca9e0ec7c97d622d899796e3773930b946cd2413d098656c0c5d8cc58c6f25c21e6bd54
+ languageName: node
+ linkType: hard
+
+"array.prototype.tosorted@npm:^1.1.4":
+ version: 1.1.4
+ resolution: "array.prototype.tosorted@npm:1.1.4"
+ dependencies:
+ call-bind: "npm:^1.0.7"
+ define-properties: "npm:^1.2.1"
+ es-abstract: "npm:^1.23.3"
+ es-errors: "npm:^1.3.0"
+ es-shim-unscopables: "npm:^1.0.2"
+ checksum: 10c0/eb3c4c4fc0381b0bf6dba2ea4d48d367c2827a0d4236a5718d97caaccc6b78f11f4cadf090736e86301d295a6aa4967ed45568f92ced51be8cbbacd9ca410943
+ languageName: node
+ linkType: hard
+
+"arraybuffer.prototype.slice@npm:^1.0.4":
+ version: 1.0.4
+ resolution: "arraybuffer.prototype.slice@npm:1.0.4"
+ dependencies:
+ array-buffer-byte-length: "npm:^1.0.1"
+ call-bind: "npm:^1.0.8"
+ define-properties: "npm:^1.2.1"
+ es-abstract: "npm:^1.23.5"
+ es-errors: "npm:^1.3.0"
+ get-intrinsic: "npm:^1.2.6"
+ is-array-buffer: "npm:^3.0.4"
+ checksum: 10c0/2f2459caa06ae0f7f615003f9104b01f6435cc803e11bd2a655107d52a1781dc040532dc44d93026b694cc18793993246237423e13a5337e86b43ed604932c06
+ languageName: node
+ linkType: hard
+
"arrify@npm:^2.0.0":
version: 2.0.1
resolution: "arrify@npm:2.0.1"
@@ -5345,6 +5699,15 @@ __metadata:
languageName: node
linkType: hard
+"available-typed-arrays@npm:^1.0.7":
+ version: 1.0.7
+ resolution: "available-typed-arrays@npm:1.0.7"
+ dependencies:
+ possible-typed-array-names: "npm:^1.0.0"
+ checksum: 10c0/d07226ef4f87daa01bd0fe80f8f310982e345f372926da2e5296aecc25c41cab440916bbaa4c5e1034b453af3392f67df5961124e4b586df1e99793a1374bdb2
+ languageName: node
+ linkType: hard
+
"balanced-match@npm:^1.0.0":
version: 1.0.2
resolution: "balanced-match@npm:1.0.2"
@@ -5616,7 +5979,19 @@ __metadata:
languageName: node
linkType: hard
-"call-bound@npm:^1.0.2":
+"call-bind@npm:^1.0.7, call-bind@npm:^1.0.8, call-bind@npm:^1.0.9":
+ version: 1.0.9
+ resolution: "call-bind@npm:1.0.9"
+ dependencies:
+ call-bind-apply-helpers: "npm:^1.0.2"
+ es-define-property: "npm:^1.0.1"
+ get-intrinsic: "npm:^1.3.0"
+ set-function-length: "npm:^1.2.2"
+ checksum: 10c0/a6621f6da1444481919ce3b4983dff725691e0754d3507ae483ce56e54985f2da7d6f1df512c56dbf28660745cf1ca52553f1fc9aef5557f3ce353ef14fab714
+ languageName: node
+ linkType: hard
+
+"call-bound@npm:^1.0.2, call-bound@npm:^1.0.3, call-bound@npm:^1.0.4":
version: 1.0.4
resolution: "call-bound@npm:1.0.4"
dependencies:
@@ -6043,6 +6418,13 @@ __metadata:
languageName: node
linkType: hard
+"csstype@npm:^3.2.2":
+ version: 3.2.3
+ resolution: "csstype@npm:3.2.3"
+ checksum: 10c0/cd29c51e70fa822f1cecd8641a1445bed7063697469d35633b516e60fe8c1bde04b08f6c5b6022136bb669b64c63d4173af54864510fbb4ee23281801841a3ce
+ languageName: node
+ linkType: hard
+
"custom-lit-components@workspace:custom-lit-components":
version: 0.0.0-use.local
resolution: "custom-lit-components@workspace:custom-lit-components"
@@ -6074,7 +6456,40 @@ __metadata:
languageName: node
linkType: hard
-"date-fns@npm:^4.1.0":
+"data-view-buffer@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "data-view-buffer@npm:1.0.2"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ es-errors: "npm:^1.3.0"
+ is-data-view: "npm:^1.0.2"
+ checksum: 10c0/7986d40fc7979e9e6241f85db8d17060dd9a71bd53c894fa29d126061715e322a4cd47a00b0b8c710394854183d4120462b980b8554012acc1c0fa49df7ad38c
+ languageName: node
+ linkType: hard
+
+"data-view-byte-length@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "data-view-byte-length@npm:1.0.2"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ es-errors: "npm:^1.3.0"
+ is-data-view: "npm:^1.0.2"
+ checksum: 10c0/f8a4534b5c69384d95ac18137d381f18a5cfae1f0fc1df0ef6feef51ef0d568606d970b69e02ea186c6c0f0eac77fe4e6ad96fec2569cc86c3afcc7475068c55
+ languageName: node
+ linkType: hard
+
+"data-view-byte-offset@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "data-view-byte-offset@npm:1.0.1"
+ dependencies:
+ call-bound: "npm:^1.0.2"
+ es-errors: "npm:^1.3.0"
+ is-data-view: "npm:^1.0.1"
+ checksum: 10c0/fa7aa40078025b7810dcffc16df02c480573b7b53ef1205aa6a61533011005c1890e5ba17018c692ce7c900212b547262d33279fde801ad9843edc0863bf78c4
+ languageName: node
+ linkType: hard
+
+"date-fns@npm:^4.1.0, date-fns@npm:^4.4.0":
version: 4.4.0
resolution: "date-fns@npm:4.4.0"
checksum: 10c0/988f0a13db183f5dfc85c36bbb6847a9c135a9225888bbea4005876ec15539a8613c21a07370a4e7ea543918d5a1cafb423c528b42cdbbde5fdfddb178126b21
@@ -6124,6 +6539,17 @@ __metadata:
languageName: node
linkType: hard
+"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4":
+ version: 1.1.4
+ resolution: "define-data-property@npm:1.1.4"
+ dependencies:
+ es-define-property: "npm:^1.0.0"
+ es-errors: "npm:^1.3.0"
+ gopd: "npm:^1.0.1"
+ checksum: 10c0/dea0606d1483eb9db8d930d4eac62ca0fa16738b0b3e07046cddfacf7d8c868bbe13fa0cb263eb91c7d0d527960dc3f2f2471a69ed7816210307f6744fe62e37
+ languageName: node
+ linkType: hard
+
"define-lazy-prop@npm:^3.0.0":
version: 3.0.0
resolution: "define-lazy-prop@npm:3.0.0"
@@ -6131,6 +6557,17 @@ __metadata:
languageName: node
linkType: hard
+"define-properties@npm:^1.1.3, define-properties@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "define-properties@npm:1.2.1"
+ dependencies:
+ define-data-property: "npm:^1.0.1"
+ has-property-descriptors: "npm:^1.0.0"
+ object-keys: "npm:^1.1.1"
+ checksum: 10c0/88a152319ffe1396ccc6ded510a3896e77efac7a1bfbaa174a7b00414a1747377e0bb525d303794a47cf30e805c2ec84e575758512c6e44a993076d29fd4e6c3
+ languageName: node
+ linkType: hard
+
"delayed-stream@npm:~1.0.0":
version: 1.0.0
resolution: "delayed-stream@npm:1.0.0"
@@ -6173,6 +6610,15 @@ __metadata:
languageName: node
linkType: hard
+"doctrine@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "doctrine@npm:2.1.0"
+ dependencies:
+ esutils: "npm:^2.0.2"
+ checksum: 10c0/b6416aaff1f380bf56c3b552f31fdf7a69b45689368deca72d28636f41c16bb28ec3ebc40ace97db4c1afc0ceeb8120e8492fe0046841c94c2933b2e30a7d5ac
+ languageName: node
+ linkType: hard
+
"dom-serializer@npm:^2.0.0":
version: 2.0.0
resolution: "dom-serializer@npm:2.0.0"
@@ -6230,7 +6676,7 @@ __metadata:
languageName: node
linkType: hard
-"dunder-proto@npm:^1.0.1":
+"dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1":
version: 1.0.1
resolution: "dunder-proto@npm:1.0.1"
dependencies:
@@ -6380,7 +6826,81 @@ __metadata:
languageName: node
linkType: hard
-"es-define-property@npm:^1.0.1":
+"es-abstract-get@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "es-abstract-get@npm:1.0.0"
+ dependencies:
+ es-errors: "npm:^1.3.0"
+ es-object-atoms: "npm:^1.1.2"
+ is-callable: "npm:^1.2.7"
+ object-inspect: "npm:^1.13.4"
+ checksum: 10c0/f9b4838ae719752207383a6d95a74590f891122bf26b92f5e72eeedbe53771029e4561f1cf75ea19330b71bcf3d4f536fb0c8f7e2b601fe24d284f46e488c7e3
+ languageName: node
+ linkType: hard
+
+"es-abstract@npm:^1.17.5, es-abstract@npm:^1.23.2, es-abstract@npm:^1.23.3, es-abstract@npm:^1.23.5, es-abstract@npm:^1.23.6, es-abstract@npm:^1.23.9, es-abstract@npm:^1.24.0, es-abstract@npm:^1.24.2":
+ version: 1.24.2
+ resolution: "es-abstract@npm:1.24.2"
+ dependencies:
+ array-buffer-byte-length: "npm:^1.0.2"
+ arraybuffer.prototype.slice: "npm:^1.0.4"
+ available-typed-arrays: "npm:^1.0.7"
+ call-bind: "npm:^1.0.8"
+ call-bound: "npm:^1.0.4"
+ data-view-buffer: "npm:^1.0.2"
+ data-view-byte-length: "npm:^1.0.2"
+ data-view-byte-offset: "npm:^1.0.1"
+ es-define-property: "npm:^1.0.1"
+ es-errors: "npm:^1.3.0"
+ es-object-atoms: "npm:^1.1.1"
+ es-set-tostringtag: "npm:^2.1.0"
+ es-to-primitive: "npm:^1.3.0"
+ function.prototype.name: "npm:^1.1.8"
+ get-intrinsic: "npm:^1.3.0"
+ get-proto: "npm:^1.0.1"
+ get-symbol-description: "npm:^1.1.0"
+ globalthis: "npm:^1.0.4"
+ gopd: "npm:^1.2.0"
+ has-property-descriptors: "npm:^1.0.2"
+ has-proto: "npm:^1.2.0"
+ has-symbols: "npm:^1.1.0"
+ hasown: "npm:^2.0.2"
+ internal-slot: "npm:^1.1.0"
+ is-array-buffer: "npm:^3.0.5"
+ is-callable: "npm:^1.2.7"
+ is-data-view: "npm:^1.0.2"
+ is-negative-zero: "npm:^2.0.3"
+ is-regex: "npm:^1.2.1"
+ is-set: "npm:^2.0.3"
+ is-shared-array-buffer: "npm:^1.0.4"
+ is-string: "npm:^1.1.1"
+ is-typed-array: "npm:^1.1.15"
+ is-weakref: "npm:^1.1.1"
+ math-intrinsics: "npm:^1.1.0"
+ object-inspect: "npm:^1.13.4"
+ object-keys: "npm:^1.1.1"
+ object.assign: "npm:^4.1.7"
+ own-keys: "npm:^1.0.1"
+ regexp.prototype.flags: "npm:^1.5.4"
+ safe-array-concat: "npm:^1.1.3"
+ safe-push-apply: "npm:^1.0.0"
+ safe-regex-test: "npm:^1.1.0"
+ set-proto: "npm:^1.0.0"
+ stop-iteration-iterator: "npm:^1.1.0"
+ string.prototype.trim: "npm:^1.2.10"
+ string.prototype.trimend: "npm:^1.0.9"
+ string.prototype.trimstart: "npm:^1.0.8"
+ typed-array-buffer: "npm:^1.0.3"
+ typed-array-byte-length: "npm:^1.0.3"
+ typed-array-byte-offset: "npm:^1.0.4"
+ typed-array-length: "npm:^1.0.7"
+ unbox-primitive: "npm:^1.1.0"
+ which-typed-array: "npm:^1.1.19"
+ checksum: 10c0/67a5bf21ef5c7d775e6f6131a836323900b4d87194cf544394ac68fe31c57fa53828b978af4a4f551ef307f83a2f910a16b6b982760ad3ddc3dc471f98d5fd1b
+ languageName: node
+ linkType: hard
+
+"es-define-property@npm:^1.0.0, es-define-property@npm:^1.0.1":
version: 1.0.1
resolution: "es-define-property@npm:1.0.1"
checksum: 10c0/3f54eb49c16c18707949ff25a1456728c883e81259f045003499efba399c08bad00deebf65cccde8c0e07908c1a225c9d472b7107e558f2a48e28d530e34527c
@@ -6394,6 +6914,30 @@ __metadata:
languageName: node
linkType: hard
+"es-iterator-helpers@npm:^1.2.1":
+ version: 1.4.0
+ resolution: "es-iterator-helpers@npm:1.4.0"
+ dependencies:
+ call-bind: "npm:^1.0.9"
+ call-bound: "npm:^1.0.4"
+ define-properties: "npm:^1.2.1"
+ es-abstract: "npm:^1.24.2"
+ es-errors: "npm:^1.3.0"
+ es-set-tostringtag: "npm:^2.1.0"
+ function-bind: "npm:^1.1.2"
+ get-intrinsic: "npm:^1.3.0"
+ globalthis: "npm:^1.0.4"
+ gopd: "npm:^1.2.0"
+ has-property-descriptors: "npm:^1.0.2"
+ has-proto: "npm:^1.2.0"
+ has-symbols: "npm:^1.1.0"
+ internal-slot: "npm:^1.1.0"
+ iterator.prototype: "npm:^1.1.5"
+ math-intrinsics: "npm:^1.1.0"
+ checksum: 10c0/839a5e881446e1b4ab270a9ad5d01a23b83a38fadb9e526674df171357e90ad3111dc8c0b15e7d30db1958f2c3332dd963fab7d55f406a660d098b2b7eefb218
+ languageName: node
+ linkType: hard
+
"es-module-lexer@npm:^2.0.0":
version: 2.1.0
resolution: "es-module-lexer@npm:2.1.0"
@@ -6401,7 +6945,7 @@ __metadata:
languageName: node
linkType: hard
-"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1":
+"es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1, es-object-atoms@npm:^1.1.2":
version: 1.1.2
resolution: "es-object-atoms@npm:1.1.2"
dependencies:
@@ -6422,6 +6966,29 @@ __metadata:
languageName: node
linkType: hard
+"es-shim-unscopables@npm:^1.0.2":
+ version: 1.1.0
+ resolution: "es-shim-unscopables@npm:1.1.0"
+ dependencies:
+ hasown: "npm:^2.0.2"
+ checksum: 10c0/1b9702c8a1823fc3ef39035a4e958802cf294dd21e917397c561d0b3e195f383b978359816b1732d02b255ccf63e1e4815da0065b95db8d7c992037be3bbbcdb
+ languageName: node
+ linkType: hard
+
+"es-to-primitive@npm:^1.3.0":
+ version: 1.3.4
+ resolution: "es-to-primitive@npm:1.3.4"
+ dependencies:
+ es-abstract-get: "npm:^1.0.0"
+ es-define-property: "npm:^1.0.1"
+ es-errors: "npm:^1.3.0"
+ is-callable: "npm:^1.2.7"
+ is-date-object: "npm:^1.1.0"
+ is-symbol: "npm:^1.1.1"
+ checksum: 10c0/b10029f8b0b13841bade224ff39005a13d76d9cb803cd1efb18cc96a24414e83e2e7ed15d7ad9d0d0bda66884afd211b7b579b8fa31940e05b060934aa7077d8
+ languageName: node
+ linkType: hard
+
"es-toolkit@npm:^1.39.7":
version: 1.47.1
resolution: "es-toolkit@npm:1.47.1"
@@ -6546,8 +7113,62 @@ __metadata:
languageName: node
linkType: hard
-"eslint-scope@npm:^9.1.2":
- version: 9.1.2
+"eslint-config-prettier@npm:^10.1.8":
+ version: 10.1.8
+ resolution: "eslint-config-prettier@npm:10.1.8"
+ peerDependencies:
+ eslint: ">=7.0.0"
+ bin:
+ eslint-config-prettier: bin/cli.js
+ checksum: 10c0/e1bcfadc9eccd526c240056b1e59c5cd26544fe59feb85f38f4f1f116caed96aea0b3b87868e68b3099e55caaac3f2e5b9f58110f85db893e83a332751192682
+ languageName: node
+ linkType: hard
+
+"eslint-plugin-react-hooks@npm:^7.1.1":
+ version: 7.1.1
+ resolution: "eslint-plugin-react-hooks@npm:7.1.1"
+ dependencies:
+ "@babel/core": "npm:^7.24.4"
+ "@babel/parser": "npm:^7.24.4"
+ hermes-parser: "npm:^0.25.1"
+ zod: "npm:^3.25.0 || ^4.0.0"
+ zod-validation-error: "npm:^3.5.0 || ^4.0.0"
+ peerDependencies:
+ eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0
+ checksum: 10c0/cee8454915d71ac5d70a0d8f4f260e76eaf45fcd4162747dd4282b792ee5616d187351dabe6cdcff9040c79d0cec625635c4fd0777276be119efa88ebe058525
+ languageName: node
+ linkType: hard
+
+"eslint-plugin-react@npm:^7.37.5":
+ version: 7.37.5
+ resolution: "eslint-plugin-react@npm:7.37.5"
+ dependencies:
+ array-includes: "npm:^3.1.8"
+ array.prototype.findlast: "npm:^1.2.5"
+ array.prototype.flatmap: "npm:^1.3.3"
+ array.prototype.tosorted: "npm:^1.1.4"
+ doctrine: "npm:^2.1.0"
+ es-iterator-helpers: "npm:^1.2.1"
+ estraverse: "npm:^5.3.0"
+ hasown: "npm:^2.0.2"
+ jsx-ast-utils: "npm:^2.4.1 || ^3.0.0"
+ minimatch: "npm:^3.1.2"
+ object.entries: "npm:^1.1.9"
+ object.fromentries: "npm:^2.0.8"
+ object.values: "npm:^1.2.1"
+ prop-types: "npm:^15.8.1"
+ resolve: "npm:^2.0.0-next.5"
+ semver: "npm:^6.3.1"
+ string.prototype.matchall: "npm:^4.0.12"
+ string.prototype.repeat: "npm:^1.0.0"
+ peerDependencies:
+ eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7
+ checksum: 10c0/c850bfd556291d4d9234f5ca38db1436924a1013627c8ab1853f77cac73ec19b020e861e6c7b783436a48b6ffcdfba4547598235a37ad4611b6739f65fd8ad57
+ languageName: node
+ linkType: hard
+
+"eslint-scope@npm:^9.1.2":
+ version: 9.1.2
resolution: "eslint-scope@npm:9.1.2"
dependencies:
"@types/esrecurse": "npm:^4.3.1"
@@ -6565,7 +7186,7 @@ __metadata:
languageName: node
linkType: hard
-"eslint-visitor-keys@npm:^5.0.1":
+"eslint-visitor-keys@npm:^5.0.0, eslint-visitor-keys@npm:^5.0.1":
version: 5.0.1
resolution: "eslint-visitor-keys@npm:5.0.1"
checksum: 10c0/16190bdf2cbae40a1109384c94450c526a79b0b9c3cb21e544256ed85ac48a4b84db66b74a6561d20fe6ab77447f150d711c2ad5ad74df4fcc133736bce99678
@@ -6646,7 +7267,7 @@ __metadata:
languageName: node
linkType: hard
-"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0":
+"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0, estraverse@npm:^5.3.0":
version: 5.3.0
resolution: "estraverse@npm:5.3.0"
checksum: 10c0/1ff9447b96263dec95d6d67431c5e0771eb9776427421260a3e2f0fdd5d6bd4f8e37a7338f5ad2880c9f143450c9b1e4fc2069060724570a49cf9cf0312bd107
@@ -7030,6 +7651,15 @@ __metadata:
languageName: node
linkType: hard
+"for-each@npm:^0.3.3, for-each@npm:^0.3.5":
+ version: 0.3.5
+ resolution: "for-each@npm:0.3.5"
+ dependencies:
+ is-callable: "npm:^1.2.7"
+ checksum: 10c0/0e0b50f6a843a282637d43674d1fb278dda1dd85f4f99b640024cfb10b85058aac0cc781bf689d5fe50b4b7f638e91e548560723a4e76e04fe96ae35ef039cee
+ languageName: node
+ linkType: hard
+
"foreground-child@npm:^3.1.0":
version: 3.3.1
resolution: "foreground-child@npm:3.3.1"
@@ -7119,6 +7749,23 @@ __metadata:
languageName: node
linkType: hard
+"function.prototype.name@npm:^1.1.6, function.prototype.name@npm:^1.1.8":
+ version: 1.2.0
+ resolution: "function.prototype.name@npm:1.2.0"
+ dependencies:
+ call-bind: "npm:^1.0.9"
+ call-bound: "npm:^1.0.4"
+ es-define-property: "npm:^1.0.1"
+ es-errors: "npm:^1.3.0"
+ functions-have-names: "npm:^1.2.3"
+ has-property-descriptors: "npm:^1.0.2"
+ hasown: "npm:^2.0.4"
+ is-callable: "npm:^1.2.7"
+ is-document.all: "npm:^1.0.0"
+ checksum: 10c0/b20e6370ef4f7d56d0bedf5719f6684a517a8dd3334209b4d9f51e8834859302a584187156bf024cda9f50ba2479e4d6764ac34af9532ea47d2f4d9fa6bcf90d
+ languageName: node
+ linkType: hard
+
"functional-red-black-tree@npm:^1.0.1":
version: 1.0.1
resolution: "functional-red-black-tree@npm:1.0.1"
@@ -7126,6 +7773,13 @@ __metadata:
languageName: node
linkType: hard
+"functions-have-names@npm:^1.2.3":
+ version: 1.2.3
+ resolution: "functions-have-names@npm:1.2.3"
+ checksum: 10c0/33e77fd29bddc2d9bb78ab3eb854c165909201f88c75faa8272e35899e2d35a8a642a15e7420ef945e1f64a9670d6aa3ec744106b2aa42be68ca5114025954ca
+ languageName: node
+ linkType: hard
+
"gaxios@npm:7.1.3":
version: 7.1.3
resolution: "gaxios@npm:7.1.3"
@@ -7223,7 +7877,7 @@ __metadata:
languageName: node
linkType: hard
-"get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.3.0":
+"get-intrinsic@npm:^1.2.4, get-intrinsic@npm:^1.2.5, get-intrinsic@npm:^1.2.6, get-intrinsic@npm:^1.2.7, get-intrinsic@npm:^1.3.0":
version: 1.3.1
resolution: "get-intrinsic@npm:1.3.1"
dependencies:
@@ -7251,7 +7905,7 @@ __metadata:
languageName: node
linkType: hard
-"get-proto@npm:^1.0.1":
+"get-proto@npm:^1.0.0, get-proto@npm:^1.0.1":
version: 1.0.1
resolution: "get-proto@npm:1.0.1"
dependencies:
@@ -7261,6 +7915,17 @@ __metadata:
languageName: node
linkType: hard
+"get-symbol-description@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "get-symbol-description@npm:1.1.0"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ es-errors: "npm:^1.3.0"
+ get-intrinsic: "npm:^1.2.6"
+ checksum: 10c0/d6a7d6afca375779a4b307738c9e80dbf7afc0bdbe5948768d54ab9653c865523d8920e670991a925936eb524b7cb6a6361d199a760b21d0ca7620194455aa4b
+ languageName: node
+ linkType: hard
+
"glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2":
version: 5.1.2
resolution: "glob-parent@npm:5.1.2"
@@ -7327,6 +7992,16 @@ __metadata:
languageName: node
linkType: hard
+"globalthis@npm:^1.0.4":
+ version: 1.0.4
+ resolution: "globalthis@npm:1.0.4"
+ dependencies:
+ define-properties: "npm:^1.2.1"
+ gopd: "npm:^1.0.1"
+ checksum: 10c0/9d156f313af79d80b1566b93e19285f481c591ad6d0d319b4be5e03750d004dde40a39a0f26f7e635f9007a3600802f53ecd85a759b86f109e80a5f705e01846
+ languageName: node
+ linkType: hard
+
"google-auth-library@npm:10.5.0":
version: 10.5.0
resolution: "google-auth-library@npm:10.5.0"
@@ -7410,7 +8085,7 @@ __metadata:
languageName: node
linkType: hard
-"gopd@npm:^1.2.0":
+"gopd@npm:^1.0.1, gopd@npm:^1.2.0":
version: 1.2.0
resolution: "gopd@npm:1.2.0"
checksum: 10c0/50fff1e04ba2b7737c097358534eacadad1e68d24cccee3272e04e007bed008e68d2614f3987788428fd192a5ae3889d08fb2331417e4fc4a9ab366b2043cead
@@ -7444,6 +8119,13 @@ __metadata:
languageName: node
linkType: hard
+"has-bigints@npm:^1.0.2":
+ version: 1.1.0
+ resolution: "has-bigints@npm:1.1.0"
+ checksum: 10c0/2de0cdc4a1ccf7a1e75ffede1876994525ac03cc6f5ae7392d3415dd475cd9eee5bceec63669ab61aa997ff6cceebb50ef75561c7002bed8988de2b9d1b40788
+ languageName: node
+ linkType: hard
+
"has-flag@npm:^4.0.0":
version: 4.0.0
resolution: "has-flag@npm:4.0.0"
@@ -7451,6 +8133,24 @@ __metadata:
languageName: node
linkType: hard
+"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "has-property-descriptors@npm:1.0.2"
+ dependencies:
+ es-define-property: "npm:^1.0.0"
+ checksum: 10c0/253c1f59e80bb476cf0dde8ff5284505d90c3bdb762983c3514d36414290475fe3fd6f574929d84de2a8eec00d35cf07cb6776205ff32efd7c50719125f00236
+ languageName: node
+ linkType: hard
+
+"has-proto@npm:^1.2.0":
+ version: 1.2.0
+ resolution: "has-proto@npm:1.2.0"
+ dependencies:
+ dunder-proto: "npm:^1.0.0"
+ checksum: 10c0/46538dddab297ec2f43923c3d35237df45d8c55a6fc1067031e04c13ed8a9a8f94954460632fd4da84c31a1721eefee16d901cbb1ae9602bab93bb6e08f93b95
+ languageName: node
+ linkType: hard
+
"has-symbols@npm:^1.0.3, has-symbols@npm:^1.1.0":
version: 1.1.0
resolution: "has-symbols@npm:1.1.0"
@@ -7476,6 +8176,22 @@ __metadata:
languageName: node
linkType: hard
+"hermes-estree@npm:0.25.1":
+ version: 0.25.1
+ resolution: "hermes-estree@npm:0.25.1"
+ checksum: 10c0/48be3b2fa37a0cbc77a112a89096fa212f25d06de92781b163d67853d210a8a5c3784fac23d7d48335058f7ed283115c87b4332c2a2abaaccc76d0ead1a282ac
+ languageName: node
+ linkType: hard
+
+"hermes-parser@npm:^0.25.1":
+ version: 0.25.1
+ resolution: "hermes-parser@npm:0.25.1"
+ dependencies:
+ hermes-estree: "npm:0.25.1"
+ checksum: 10c0/3abaa4c6f1bcc25273f267297a89a4904963ea29af19b8e4f6eabe04f1c2c7e9abd7bfc4730ddb1d58f2ea04b6fee74053d8bddb5656ec6ebf6c79cc8d14202c
+ languageName: node
+ linkType: hard
+
"hono@npm:^4.11.4":
version: 4.12.25
resolution: "hono@npm:4.12.25"
@@ -7629,6 +8345,13 @@ __metadata:
languageName: node
linkType: hard
+"ignore@npm:^7.0.5":
+ version: 7.0.6
+ resolution: "ignore@npm:7.0.6"
+ checksum: 10c0/fc01ef1d14efbe003439b60538726351e81483d1b6f55bdbb3a4465c6346d9481afad5b350dfbd604ddd7049618ef9093ff26dc147984aabc303c56ba53ea3b5
+ languageName: node
+ linkType: hard
+
"image-size@npm:~0.5.0":
version: 0.5.5
resolution: "image-size@npm:0.5.5"
@@ -7685,6 +8408,17 @@ __metadata:
languageName: node
linkType: hard
+"internal-slot@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "internal-slot@npm:1.1.0"
+ dependencies:
+ es-errors: "npm:^1.3.0"
+ hasown: "npm:^2.0.2"
+ side-channel: "npm:^1.1.0"
+ checksum: 10c0/03966f5e259b009a9bf1a78d60da920df198af4318ec004f57b8aef1dd3fe377fbc8cce63a96e8c810010302654de89f9e19de1cd8ad0061d15be28a695465c7
+ languageName: node
+ linkType: hard
+
"interpret@npm:^1.0.0":
version: 1.4.0
resolution: "interpret@npm:1.4.0"
@@ -7706,6 +8440,39 @@ __metadata:
languageName: node
linkType: hard
+"is-array-buffer@npm:^3.0.4, is-array-buffer@npm:^3.0.5":
+ version: 3.0.5
+ resolution: "is-array-buffer@npm:3.0.5"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ call-bound: "npm:^1.0.3"
+ get-intrinsic: "npm:^1.2.6"
+ checksum: 10c0/c5c9f25606e86dbb12e756694afbbff64bc8b348d1bc989324c037e1068695131930199d6ad381952715dad3a9569333817f0b1a72ce5af7f883ce802e49c83d
+ languageName: node
+ linkType: hard
+
+"is-async-function@npm:^2.0.0":
+ version: 2.1.1
+ resolution: "is-async-function@npm:2.1.1"
+ dependencies:
+ async-function: "npm:^1.0.0"
+ call-bound: "npm:^1.0.3"
+ get-proto: "npm:^1.0.1"
+ has-tostringtag: "npm:^1.0.2"
+ safe-regex-test: "npm:^1.1.0"
+ checksum: 10c0/d70c236a5e82de6fc4d44368ffd0c2fee2b088b893511ce21e679da275a5ecc6015ff59a7d7e1bdd7ca39f71a8dbdd253cf8cce5c6b3c91cdd5b42b5ce677298
+ languageName: node
+ linkType: hard
+
+"is-bigint@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "is-bigint@npm:1.1.0"
+ dependencies:
+ has-bigints: "npm:^1.0.2"
+ checksum: 10c0/f4f4b905ceb195be90a6ea7f34323bf1c18e3793f18922e3e9a73c684c29eeeeff5175605c3a3a74cc38185fe27758f07efba3dbae812e5c5afbc0d2316b40e4
+ languageName: node
+ linkType: hard
+
"is-binary-path@npm:~2.1.0":
version: 2.1.0
resolution: "is-binary-path@npm:2.1.0"
@@ -7715,7 +8482,24 @@ __metadata:
languageName: node
linkType: hard
-"is-core-module@npm:^2.16.1":
+"is-boolean-object@npm:^1.2.1":
+ version: 1.2.2
+ resolution: "is-boolean-object@npm:1.2.2"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ has-tostringtag: "npm:^1.0.2"
+ checksum: 10c0/36ff6baf6bd18b3130186990026f5a95c709345c39cd368468e6c1b6ab52201e9fd26d8e1f4c066357b4938b0f0401e1a5000e08257787c1a02f3a719457001e
+ languageName: node
+ linkType: hard
+
+"is-callable@npm:^1.2.7":
+ version: 1.2.7
+ resolution: "is-callable@npm:1.2.7"
+ checksum: 10c0/ceebaeb9d92e8adee604076971dd6000d38d6afc40bb843ea8e45c5579b57671c3f3b50d7f04869618242c6cee08d1b67806a8cb8edaaaf7c0748b3720d6066f
+ languageName: node
+ linkType: hard
+
+"is-core-module@npm:^2.16.1, is-core-module@npm:^2.16.2":
version: 2.16.2
resolution: "is-core-module@npm:2.16.2"
dependencies:
@@ -7724,6 +8508,27 @@ __metadata:
languageName: node
linkType: hard
+"is-data-view@npm:^1.0.1, is-data-view@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "is-data-view@npm:1.0.2"
+ dependencies:
+ call-bound: "npm:^1.0.2"
+ get-intrinsic: "npm:^1.2.6"
+ is-typed-array: "npm:^1.1.13"
+ checksum: 10c0/ef3548a99d7e7f1370ce21006baca6d40c73e9f15c941f89f0049c79714c873d03b02dae1c64b3f861f55163ecc16da06506c5b8a1d4f16650b3d9351c380153
+ languageName: node
+ linkType: hard
+
+"is-date-object@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "is-date-object@npm:1.1.0"
+ dependencies:
+ call-bound: "npm:^1.0.2"
+ has-tostringtag: "npm:^1.0.2"
+ checksum: 10c0/1a4d199c8e9e9cac5128d32e6626fa7805175af9df015620ac0d5d45854ccf348ba494679d872d37301032e35a54fc7978fba1687e8721b2139aea7870cafa2f
+ languageName: node
+ linkType: hard
+
"is-docker@npm:^3.0.0":
version: 3.0.0
resolution: "is-docker@npm:3.0.0"
@@ -7733,6 +8538,15 @@ __metadata:
languageName: node
linkType: hard
+"is-document.all@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "is-document.all@npm:1.0.0"
+ dependencies:
+ call-bound: "npm:^1.0.4"
+ checksum: 10c0/955c20ed5bf01d49da8243b4c714947a6ff64b6d9ba0e12bdbfa654a3e7c47f72cc01c6cd2905e85512d02bc3a1290edd73857bca8842566ff9dcfb7c3f92dae
+ languageName: node
+ linkType: hard
+
"is-extglob@npm:^2.1.1":
version: 2.1.1
resolution: "is-extglob@npm:2.1.1"
@@ -7740,6 +8554,15 @@ __metadata:
languageName: node
linkType: hard
+"is-finalizationregistry@npm:^1.1.0":
+ version: 1.1.1
+ resolution: "is-finalizationregistry@npm:1.1.1"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ checksum: 10c0/818dff679b64f19e228a8205a1e2d09989a98e98def3a817f889208cfcbf918d321b251aadf2c05918194803ebd2eb01b14fc9d0b2bea53d984f4137bfca5e97
+ languageName: node
+ linkType: hard
+
"is-fullwidth-code-point@npm:^3.0.0":
version: 3.0.0
resolution: "is-fullwidth-code-point@npm:3.0.0"
@@ -7756,6 +8579,19 @@ __metadata:
languageName: node
linkType: hard
+"is-generator-function@npm:^1.0.10":
+ version: 1.1.2
+ resolution: "is-generator-function@npm:1.1.2"
+ dependencies:
+ call-bound: "npm:^1.0.4"
+ generator-function: "npm:^2.0.0"
+ get-proto: "npm:^1.0.1"
+ has-tostringtag: "npm:^1.0.2"
+ safe-regex-test: "npm:^1.1.0"
+ checksum: 10c0/83da102e89c3e3b71d67b51d47c9f9bc862bceb58f87201727e27f7fa19d1d90b0ab223644ecaee6fc6e3d2d622bb25c966fbdaf87c59158b01ce7c0fe2fa372
+ languageName: node
+ linkType: hard
+
"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3, is-glob@npm:~4.0.1":
version: 4.0.3
resolution: "is-glob@npm:4.0.3"
@@ -7783,6 +8619,30 @@ __metadata:
languageName: node
linkType: hard
+"is-map@npm:^2.0.3":
+ version: 2.0.3
+ resolution: "is-map@npm:2.0.3"
+ checksum: 10c0/2c4d431b74e00fdda7162cd8e4b763d6f6f217edf97d4f8538b94b8702b150610e2c64961340015fe8df5b1fcee33ccd2e9b62619c4a8a3a155f8de6d6d355fc
+ languageName: node
+ linkType: hard
+
+"is-negative-zero@npm:^2.0.3":
+ version: 2.0.3
+ resolution: "is-negative-zero@npm:2.0.3"
+ checksum: 10c0/bcdcf6b8b9714063ffcfa9929c575ac69bfdabb8f4574ff557dfc086df2836cf07e3906f5bbc4f2a5c12f8f3ba56af640c843cdfc74da8caed86c7c7d66fd08e
+ languageName: node
+ linkType: hard
+
+"is-number-object@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "is-number-object@npm:1.1.1"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ has-tostringtag: "npm:^1.0.2"
+ checksum: 10c0/97b451b41f25135ff021d85c436ff0100d84a039bb87ffd799cbcdbea81ef30c464ced38258cdd34f080be08fc3b076ca1f472086286d2aa43521d6ec6a79f53
+ languageName: node
+ linkType: hard
+
"is-number@npm:^7.0.0":
version: 7.0.0
resolution: "is-number@npm:7.0.0"
@@ -7804,6 +8664,34 @@ __metadata:
languageName: node
linkType: hard
+"is-regex@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "is-regex@npm:1.2.1"
+ dependencies:
+ call-bound: "npm:^1.0.2"
+ gopd: "npm:^1.2.0"
+ has-tostringtag: "npm:^1.0.2"
+ hasown: "npm:^2.0.2"
+ checksum: 10c0/1d3715d2b7889932349241680032e85d0b492cfcb045acb75ffc2c3085e8d561184f1f7e84b6f8321935b4aea39bc9c6ba74ed595b57ce4881a51dfdbc214e04
+ languageName: node
+ linkType: hard
+
+"is-set@npm:^2.0.3":
+ version: 2.0.3
+ resolution: "is-set@npm:2.0.3"
+ checksum: 10c0/f73732e13f099b2dc879c2a12341cfc22ccaca8dd504e6edae26484bd5707a35d503fba5b4daad530a9b088ced1ae6c9d8200fd92e09b428fe14ea79ce8080b7
+ languageName: node
+ linkType: hard
+
+"is-shared-array-buffer@npm:^1.0.4":
+ version: 1.0.4
+ resolution: "is-shared-array-buffer@npm:1.0.4"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ checksum: 10c0/65158c2feb41ff1edd6bbd6fd8403a69861cf273ff36077982b5d4d68e1d59278c71691216a4a64632bd76d4792d4d1d2553901b6666d84ade13bba5ea7bc7db
+ languageName: node
+ linkType: hard
+
"is-stream@npm:^2.0.0":
version: 2.0.1
resolution: "is-stream@npm:2.0.1"
@@ -7811,6 +8699,36 @@ __metadata:
languageName: node
linkType: hard
+"is-string@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "is-string@npm:1.1.1"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ has-tostringtag: "npm:^1.0.2"
+ checksum: 10c0/2f518b4e47886bb81567faba6ffd0d8a8333cf84336e2e78bf160693972e32ad00fe84b0926491cc598dee576fdc55642c92e62d0cbe96bf36f643b6f956f94d
+ languageName: node
+ linkType: hard
+
+"is-symbol@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "is-symbol@npm:1.1.1"
+ dependencies:
+ call-bound: "npm:^1.0.2"
+ has-symbols: "npm:^1.1.0"
+ safe-regex-test: "npm:^1.1.0"
+ checksum: 10c0/f08f3e255c12442e833f75a9e2b84b2d4882fdfd920513cf2a4a2324f0a5b076c8fd913778e3ea5d258d5183e9d92c0cd20e04b03ab3df05316b049b2670af1e
+ languageName: node
+ linkType: hard
+
+"is-typed-array@npm:^1.1.13, is-typed-array@npm:^1.1.14, is-typed-array@npm:^1.1.15":
+ version: 1.1.15
+ resolution: "is-typed-array@npm:1.1.15"
+ dependencies:
+ which-typed-array: "npm:^1.1.16"
+ checksum: 10c0/415511da3669e36e002820584e264997ffe277ff136643a3126cc949197e6ca3334d0f12d084e83b1994af2e9c8141275c741cf2b7da5a2ff62dd0cac26f76c4
+ languageName: node
+ linkType: hard
+
"is-unicode-supported@npm:^2.0.0, is-unicode-supported@npm:^2.1.0":
version: 2.1.0
resolution: "is-unicode-supported@npm:2.1.0"
@@ -7825,6 +8743,32 @@ __metadata:
languageName: node
linkType: hard
+"is-weakmap@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "is-weakmap@npm:2.0.2"
+ checksum: 10c0/443c35bb86d5e6cc5929cd9c75a4024bb0fff9586ed50b092f94e700b89c43a33b186b76dbc6d54f3d3d09ece689ab38dcdc1af6a482cbe79c0f2da0a17f1299
+ languageName: node
+ linkType: hard
+
+"is-weakref@npm:^1.0.2, is-weakref@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "is-weakref@npm:1.1.1"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ checksum: 10c0/8e0a9c07b0c780949a100e2cab2b5560a48ecd4c61726923c1a9b77b6ab0aa0046c9e7fb2206042296817045376dee2c8ab1dabe08c7c3dfbf195b01275a085b
+ languageName: node
+ linkType: hard
+
+"is-weakset@npm:^2.0.3":
+ version: 2.0.4
+ resolution: "is-weakset@npm:2.0.4"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ get-intrinsic: "npm:^1.2.6"
+ checksum: 10c0/6491eba08acb8dc9532da23cb226b7d0192ede0b88f16199e592e4769db0a077119c1f5d2283d1e0d16d739115f70046e887e477eb0e66cd90e1bb29f28ba647
+ languageName: node
+ linkType: hard
+
"is-what@npm:^4.1.8":
version: 4.1.16
resolution: "is-what@npm:4.1.16"
@@ -7841,6 +8785,13 @@ __metadata:
languageName: node
linkType: hard
+"isarray@npm:^2.0.5":
+ version: 2.0.5
+ resolution: "isarray@npm:2.0.5"
+ checksum: 10c0/4199f14a7a13da2177c66c31080008b7124331956f47bca57dd0b6ea9f11687aa25e565a2c7a2b519bc86988d10398e3049a1f5df13c9f6b7664154690ae79fd
+ languageName: node
+ linkType: hard
+
"isexe@npm:^2.0.0":
version: 2.0.0
resolution: "isexe@npm:2.0.0"
@@ -7875,6 +8826,20 @@ __metadata:
languageName: node
linkType: hard
+"iterator.prototype@npm:^1.1.5":
+ version: 1.1.5
+ resolution: "iterator.prototype@npm:1.1.5"
+ dependencies:
+ define-data-property: "npm:^1.1.4"
+ es-object-atoms: "npm:^1.0.0"
+ get-intrinsic: "npm:^1.2.6"
+ get-proto: "npm:^1.0.0"
+ has-symbols: "npm:^1.1.0"
+ set-function-name: "npm:^2.0.2"
+ checksum: 10c0/f7a262808e1b41049ab55f1e9c29af7ec1025a000d243b83edf34ce2416eedd56079b117fa59376bb4a724110690f13aa8427f2ee29a09eec63a7e72367626d0
+ languageName: node
+ linkType: hard
+
"jackspeak@npm:^3.1.2":
version: 3.4.3
resolution: "jackspeak@npm:3.4.3"
@@ -8037,6 +9002,18 @@ __metadata:
languageName: node
linkType: hard
+"jsx-ast-utils@npm:^2.4.1 || ^3.0.0":
+ version: 3.3.5
+ resolution: "jsx-ast-utils@npm:3.3.5"
+ dependencies:
+ array-includes: "npm:^3.1.6"
+ array.prototype.flat: "npm:^1.3.1"
+ object.assign: "npm:^4.1.4"
+ object.values: "npm:^1.1.6"
+ checksum: 10c0/a32679e9cb55469cb6d8bbc863f7d631b2c98b7fc7bf172629261751a6e7bc8da6ae374ddb74d5fbd8b06cf0eb4572287b259813d92b36e384024ed35e4c13e1
+ languageName: node
+ linkType: hard
+
"jwa@npm:^2.0.1":
version: 2.0.1
resolution: "jwa@npm:2.0.1"
@@ -8446,7 +9423,7 @@ __metadata:
languageName: node
linkType: hard
-"loose-envify@npm:^1.1.0":
+"loose-envify@npm:^1.1.0, loose-envify@npm:^1.4.0":
version: 1.4.0
resolution: "loose-envify@npm:1.4.0"
dependencies:
@@ -8706,7 +9683,7 @@ __metadata:
languageName: node
linkType: hard
-"minimatch@npm:3.1.5, minimatch@npm:^3.1.1":
+"minimatch@npm:3.1.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2":
version: 3.1.5
resolution: "minimatch@npm:3.1.5"
dependencies:
@@ -8999,6 +9976,18 @@ __metadata:
languageName: node
linkType: hard
+"node-exports-info@npm:^1.6.0":
+ version: 1.6.2
+ resolution: "node-exports-info@npm:1.6.2"
+ dependencies:
+ array.prototype.flatmap: "npm:^1.3.3"
+ es-errors: "npm:^1.3.0"
+ object.entries: "npm:^1.1.9"
+ semver: "npm:^6.3.1"
+ checksum: 10c0/5278fab18e8c97f45275c51819c3078ca9488361e875bc01b680776a339d2fee1ca9c6fcfb972df14945a1b184cc9924a1d9ba87e90f6cb3422c7f5b6900f4bc
+ languageName: node
+ linkType: hard
+
"node-fetch@npm:^2.6.9":
version: 2.7.0
resolution: "node-fetch@npm:2.7.0"
@@ -9197,7 +10186,7 @@ __metadata:
languageName: node
linkType: hard
-"object-assign@npm:^4":
+"object-assign@npm:^4, object-assign@npm:^4.1.1":
version: 4.1.1
resolution: "object-assign@npm:4.1.1"
checksum: 10c0/1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414
@@ -9218,6 +10207,63 @@ __metadata:
languageName: node
linkType: hard
+"object-keys@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "object-keys@npm:1.1.1"
+ checksum: 10c0/b11f7ccdbc6d406d1f186cdadb9d54738e347b2692a14439ca5ac70c225fa6db46db809711b78589866d47b25fc3e8dee0b4c722ac751e11180f9380e3d8601d
+ languageName: node
+ linkType: hard
+
+"object.assign@npm:^4.1.4, object.assign@npm:^4.1.7":
+ version: 4.1.7
+ resolution: "object.assign@npm:4.1.7"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ call-bound: "npm:^1.0.3"
+ define-properties: "npm:^1.2.1"
+ es-object-atoms: "npm:^1.0.0"
+ has-symbols: "npm:^1.1.0"
+ object-keys: "npm:^1.1.1"
+ checksum: 10c0/3b2732bd860567ea2579d1567525168de925a8d852638612846bd8082b3a1602b7b89b67b09913cbb5b9bd6e95923b2ae73580baa9d99cb4e990564e8cbf5ddc
+ languageName: node
+ linkType: hard
+
+"object.entries@npm:^1.1.9":
+ version: 1.1.9
+ resolution: "object.entries@npm:1.1.9"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ call-bound: "npm:^1.0.4"
+ define-properties: "npm:^1.2.1"
+ es-object-atoms: "npm:^1.1.1"
+ checksum: 10c0/d4b8c1e586650407da03370845f029aa14076caca4e4d4afadbc69cfb5b78035fd3ee7be417141abdb0258fa142e59b11923b4c44d8b1255b28f5ffcc50da7db
+ languageName: node
+ linkType: hard
+
+"object.fromentries@npm:^2.0.8":
+ version: 2.0.8
+ resolution: "object.fromentries@npm:2.0.8"
+ dependencies:
+ call-bind: "npm:^1.0.7"
+ define-properties: "npm:^1.2.1"
+ es-abstract: "npm:^1.23.2"
+ es-object-atoms: "npm:^1.0.0"
+ checksum: 10c0/cd4327e6c3369cfa805deb4cbbe919bfb7d3aeebf0bcaba291bb568ea7169f8f8cdbcabe2f00b40db0c20cd20f08e11b5f3a5a36fb7dd3fe04850c50db3bf83b
+ languageName: node
+ linkType: hard
+
+"object.values@npm:^1.1.6, object.values@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "object.values@npm:1.2.1"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ call-bound: "npm:^1.0.3"
+ define-properties: "npm:^1.2.1"
+ es-object-atoms: "npm:^1.0.0"
+ checksum: 10c0/3c47814fdc64842ae3d5a74bc9d06bdd8d21563c04d9939bf6716a9c00596a4ebc342552f8934013d1ec991c74e3671b26710a0c51815f0b603795605ab6b2c9
+ languageName: node
+ linkType: hard
+
"obug@npm:^2.1.1":
version: 2.1.3
resolution: "obug@npm:2.1.3"
@@ -9317,6 +10363,18 @@ __metadata:
languageName: node
linkType: hard
+"own-keys@npm:^1.0.1":
+ version: 1.0.2
+ resolution: "own-keys@npm:1.0.2"
+ dependencies:
+ call-bound: "npm:^1.0.4"
+ get-intrinsic: "npm:^1.3.0"
+ object-keys: "npm:^1.1.1"
+ safe-push-apply: "npm:^1.0.0"
+ checksum: 10c0/84b0d9959475231166c3d4b9abd1b8af8042911e2e5625761eed980d1a1e4381cf52b34d907cae21ee8766c79de943f3cd85eba636149dee5e64cceff3ccdb78
+ languageName: node
+ linkType: hard
+
"p-limit@npm:^3.0.1, p-limit@npm:^3.0.2":
version: 3.1.0
resolution: "p-limit@npm:3.1.0"
@@ -9598,6 +10656,13 @@ __metadata:
languageName: node
linkType: hard
+"possible-typed-array-names@npm:^1.0.0, possible-typed-array-names@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "possible-typed-array-names@npm:1.1.0"
+ checksum: 10c0/c810983414142071da1d644662ce4caebce890203eb2bc7bf119f37f3fe5796226e117e6cca146b521921fa6531072674174a3325066ac66fce089a53e1e5196
+ languageName: node
+ linkType: hard
+
"postcss-media-query-parser@npm:^0.2.3":
version: 0.2.3
resolution: "postcss-media-query-parser@npm:0.2.3"
@@ -9683,6 +10748,17 @@ __metadata:
languageName: node
linkType: hard
+"prop-types@npm:^15.8.1":
+ version: 15.8.1
+ resolution: "prop-types@npm:15.8.1"
+ dependencies:
+ loose-envify: "npm:^1.4.0"
+ object-assign: "npm:^4.1.1"
+ react-is: "npm:^16.13.1"
+ checksum: 10c0/59ece7ca2fb9838031d73a48d4becb9a7cc1ed10e610517c7d8f19a1e02fa47f7c27d557d8a5702bec3cfeccddc853579832b43f449e54635803f277b1c78077
+ languageName: node
+ linkType: hard
+
"proper-lockfile@npm:^4.1.2":
version: 4.1.2
resolution: "proper-lockfile@npm:4.1.2"
@@ -9807,6 +10883,24 @@ __metadata:
languageName: node
linkType: hard
+"react-dom@npm:^19.2.7":
+ version: 19.2.8
+ resolution: "react-dom@npm:19.2.8"
+ dependencies:
+ scheduler: "npm:^0.27.0"
+ peerDependencies:
+ react: ^19.2.8
+ checksum: 10c0/41ba2247b76f687fcfe5bbc99f514d6b851d8c8041c2f5ded36ed05bd7fdc5208cacbac9de51e3e6633e77f96f44cec9f0d4a5a55184dba4e00738f224439134
+ languageName: node
+ linkType: hard
+
+"react-is@npm:^16.13.1":
+ version: 16.13.1
+ resolution: "react-is@npm:16.13.1"
+ checksum: 10c0/33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1
+ languageName: node
+ linkType: hard
+
"react-remove-scroll-bar@npm:^2.3.7":
version: 2.3.8
resolution: "react-remove-scroll-bar@npm:2.3.8"
@@ -9877,6 +10971,13 @@ __metadata:
languageName: node
linkType: hard
+"react@npm:^19.2.7":
+ version: 19.2.8
+ resolution: "react@npm:19.2.8"
+ checksum: 10c0/5f86bdb56426652fd6d989d30a6f2e603c057272c47c9ca3a3fbe190a3a39ee9ccce937d63cfc039717abed1b8891d6a499134bc35311acc07eafdacd86537cd
+ languageName: node
+ linkType: hard
+
"readable-stream@npm:^3.1.1":
version: 3.6.2
resolution: "readable-stream@npm:3.6.2"
@@ -9927,6 +11028,36 @@ __metadata:
languageName: node
linkType: hard
+"reflect.getprototypeof@npm:^1.0.10, reflect.getprototypeof@npm:^1.0.9":
+ version: 1.0.10
+ resolution: "reflect.getprototypeof@npm:1.0.10"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ define-properties: "npm:^1.2.1"
+ es-abstract: "npm:^1.23.9"
+ es-errors: "npm:^1.3.0"
+ es-object-atoms: "npm:^1.0.0"
+ get-intrinsic: "npm:^1.2.7"
+ get-proto: "npm:^1.0.1"
+ which-builtin-type: "npm:^1.2.1"
+ checksum: 10c0/7facec28c8008876f8ab98e80b7b9cb4b1e9224353fd4756dda5f2a4ab0d30fa0a5074777c6df24e1e0af463a2697513b0a11e548d99cf52f21f7bc6ba48d3ac
+ languageName: node
+ linkType: hard
+
+"regexp.prototype.flags@npm:^1.5.3, regexp.prototype.flags@npm:^1.5.4":
+ version: 1.5.4
+ resolution: "regexp.prototype.flags@npm:1.5.4"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ define-properties: "npm:^1.2.1"
+ es-errors: "npm:^1.3.0"
+ get-proto: "npm:^1.0.1"
+ gopd: "npm:^1.2.0"
+ set-function-name: "npm:^2.0.2"
+ checksum: 10c0/83b88e6115b4af1c537f8dabf5c3744032cb875d63bc05c288b1b8c0ef37cbe55353f95d8ca817e8843806e3e150b118bc624e4279b24b4776b4198232735a77
+ languageName: node
+ linkType: hard
+
"require-directory@npm:^2.1.1":
version: 2.1.1
resolution: "require-directory@npm:2.1.1"
@@ -9955,6 +11086,22 @@ __metadata:
languageName: node
linkType: hard
+"resolve@npm:^2.0.0-next.5":
+ version: 2.0.0-next.7
+ resolution: "resolve@npm:2.0.0-next.7"
+ dependencies:
+ es-errors: "npm:^1.3.0"
+ is-core-module: "npm:^2.16.2"
+ node-exports-info: "npm:^1.6.0"
+ object-keys: "npm:^1.1.1"
+ path-parse: "npm:^1.0.7"
+ supports-preserve-symlinks-flag: "npm:^1.0.0"
+ bin:
+ resolve: bin/resolve
+ checksum: 10c0/8c6fa17ccdb826a3a52387ed8c42bf705dbc19d5494da52a86661b124b5b88fad5d8edbbb4434a1b563ecf7768368b7da9fb9489e20f36e02f7551a4ea87d707
+ languageName: node
+ linkType: hard
+
"resolve@patch:resolve@npm%3A^1.1.6#optional!builtin":
version: 1.22.12
resolution: "resolve@patch:resolve@npm%3A1.22.12#optional!builtin::version=1.22.12&hash=c3c19d"
@@ -9969,6 +11116,22 @@ __metadata:
languageName: node
linkType: hard
+"resolve@patch:resolve@npm%3A^2.0.0-next.5#optional!builtin":
+ version: 2.0.0-next.7
+ resolution: "resolve@patch:resolve@npm%3A2.0.0-next.7#optional!builtin::version=2.0.0-next.7&hash=c3c19d"
+ dependencies:
+ es-errors: "npm:^1.3.0"
+ is-core-module: "npm:^2.16.2"
+ node-exports-info: "npm:^1.6.0"
+ object-keys: "npm:^1.1.1"
+ path-parse: "npm:^1.0.7"
+ supports-preserve-symlinks-flag: "npm:^1.0.0"
+ bin:
+ resolve: bin/resolve
+ checksum: 10c0/6bb6f1d8a1789f7a5b4e35d950e76bc0ba632ff7d51fe86b6f34fb5f41e1ce0f7b884ec166828cfc0728ddffeaee49527711d752d12398297f90c51acd22195e
+ languageName: node
+ linkType: hard
+
"restore-cursor@npm:^5.0.0":
version: 5.1.0
resolution: "restore-cursor@npm:5.1.0"
@@ -10296,6 +11459,19 @@ __metadata:
languageName: node
linkType: hard
+"safe-array-concat@npm:^1.1.3":
+ version: 1.1.4
+ resolution: "safe-array-concat@npm:1.1.4"
+ dependencies:
+ call-bind: "npm:^1.0.9"
+ call-bound: "npm:^1.0.4"
+ get-intrinsic: "npm:^1.3.0"
+ has-symbols: "npm:^1.1.0"
+ isarray: "npm:^2.0.5"
+ checksum: 10c0/95fb4904ab1d9360a666fe5ba6d88f1c4a3a39682739e4512cff809fc6b5722a94bd95189211015bfb45859a7ffbc3340ea303ae22721c91c59e8946d310975a
+ languageName: node
+ linkType: hard
+
"safe-buffer@npm:>=5.1.0, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.2.1, safe-buffer@npm:~5.2.0":
version: 5.2.1
resolution: "safe-buffer@npm:5.2.1"
@@ -10303,6 +11479,27 @@ __metadata:
languageName: node
linkType: hard
+"safe-push-apply@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "safe-push-apply@npm:1.0.0"
+ dependencies:
+ es-errors: "npm:^1.3.0"
+ isarray: "npm:^2.0.5"
+ checksum: 10c0/831f1c9aae7436429e7862c7e46f847dfe490afac20d0ee61bae06108dbf5c745a0de3568ada30ccdd3eeb0864ca8331b2eef703abd69bfea0745b21fd320750
+ languageName: node
+ linkType: hard
+
+"safe-regex-test@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "safe-regex-test@npm:1.1.0"
+ dependencies:
+ call-bound: "npm:^1.0.2"
+ es-errors: "npm:^1.3.0"
+ is-regex: "npm:^1.2.1"
+ checksum: 10c0/f2c25281bbe5d39cddbbce7f86fca5ea9b3ce3354ea6cd7c81c31b006a5a9fff4286acc5450a3b9122c56c33eba69c56b9131ad751457b2b4a585825e6a10665
+ languageName: node
+ linkType: hard
+
"safer-buffer@npm:>= 2.1.2 < 3.0.0":
version: 2.1.2
resolution: "safer-buffer@npm:2.1.2"
@@ -10369,6 +11566,13 @@ __metadata:
languageName: node
linkType: hard
+"scheduler@npm:^0.27.0":
+ version: 0.27.0
+ resolution: "scheduler@npm:0.27.0"
+ checksum: 10c0/4f03048cb05a3c8fddc45813052251eca00688f413a3cee236d984a161da28db28ba71bd11e7a3dd02f7af84ab28d39fb311431d3b3772fed557945beb00c452
+ languageName: node
+ linkType: hard
+
"semver@npm:7.7.4":
version: 7.7.4
resolution: "semver@npm:7.7.4"
@@ -10405,6 +11609,15 @@ __metadata:
languageName: node
linkType: hard
+"semver@npm:^7.7.3":
+ version: 7.8.5
+ resolution: "semver@npm:7.8.5"
+ bin:
+ semver: bin/semver.js
+ checksum: 10c0/b1f3127a5be8125a94f37188b361c212466c292c6910adce3ec106cff5dc211ccaedc4739c11bb70fda59d6fc1f040a9bca289f4e093451521a2372e5231fe0c
+ languageName: node
+ linkType: hard
+
"send@npm:^1.1.0, send@npm:^1.2.0":
version: 1.2.1
resolution: "send@npm:1.2.1"
@@ -10451,6 +11664,43 @@ __metadata:
languageName: node
linkType: hard
+"set-function-length@npm:^1.2.2":
+ version: 1.2.2
+ resolution: "set-function-length@npm:1.2.2"
+ dependencies:
+ define-data-property: "npm:^1.1.4"
+ es-errors: "npm:^1.3.0"
+ function-bind: "npm:^1.1.2"
+ get-intrinsic: "npm:^1.2.4"
+ gopd: "npm:^1.0.1"
+ has-property-descriptors: "npm:^1.0.2"
+ checksum: 10c0/82850e62f412a258b71e123d4ed3873fa9377c216809551192bb6769329340176f109c2eeae8c22a8d386c76739855f78e8716515c818bcaef384b51110f0f3c
+ languageName: node
+ linkType: hard
+
+"set-function-name@npm:^2.0.2":
+ version: 2.0.2
+ resolution: "set-function-name@npm:2.0.2"
+ dependencies:
+ define-data-property: "npm:^1.1.4"
+ es-errors: "npm:^1.3.0"
+ functions-have-names: "npm:^1.2.3"
+ has-property-descriptors: "npm:^1.0.2"
+ checksum: 10c0/fce59f90696c450a8523e754abb305e2b8c73586452619c2bad5f7bf38c7b6b4651895c9db895679c5bef9554339cf3ef1c329b66ece3eda7255785fbe299316
+ languageName: node
+ linkType: hard
+
+"set-proto@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "set-proto@npm:1.0.0"
+ dependencies:
+ dunder-proto: "npm:^1.0.1"
+ es-errors: "npm:^1.3.0"
+ es-object-atoms: "npm:^1.0.0"
+ checksum: 10c0/ca5c3ccbba479d07c30460e367e66337cec825560b11e8ba9c5ebe13a2a0d6021ae34eddf94ff3dfe17a3104dc1f191519cb6c48378b503e5c3f36393938776a
+ languageName: node
+ linkType: hard
+
"setprototypeof@npm:~1.2.0":
version: 1.2.0
resolution: "setprototypeof@npm:1.2.0"
@@ -10762,6 +12012,16 @@ __metadata:
languageName: node
linkType: hard
+"stop-iteration-iterator@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "stop-iteration-iterator@npm:1.1.0"
+ dependencies:
+ es-errors: "npm:^1.3.0"
+ internal-slot: "npm:^1.1.0"
+ checksum: 10c0/de4e45706bb4c0354a4b1122a2b8cc45a639e86206807ce0baf390ee9218d3ef181923fa4d2b67443367c491aa255c5fbaa64bb74648e3c5b48299928af86c09
+ languageName: node
+ linkType: hard
+
"stream-events@npm:^1.0.5":
version: 1.0.5
resolution: "stream-events@npm:1.0.5"
@@ -10821,6 +12081,76 @@ __metadata:
languageName: node
linkType: hard
+"string.prototype.matchall@npm:^4.0.12":
+ version: 4.0.12
+ resolution: "string.prototype.matchall@npm:4.0.12"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ call-bound: "npm:^1.0.3"
+ define-properties: "npm:^1.2.1"
+ es-abstract: "npm:^1.23.6"
+ es-errors: "npm:^1.3.0"
+ es-object-atoms: "npm:^1.0.0"
+ get-intrinsic: "npm:^1.2.6"
+ gopd: "npm:^1.2.0"
+ has-symbols: "npm:^1.1.0"
+ internal-slot: "npm:^1.1.0"
+ regexp.prototype.flags: "npm:^1.5.3"
+ set-function-name: "npm:^2.0.2"
+ side-channel: "npm:^1.1.0"
+ checksum: 10c0/1a53328ada73f4a77f1fdf1c79414700cf718d0a8ef6672af5603e709d26a24f2181208144aed7e858b1bcc1a0d08567a570abfb45567db4ae47637ed2c2f85c
+ languageName: node
+ linkType: hard
+
+"string.prototype.repeat@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "string.prototype.repeat@npm:1.0.0"
+ dependencies:
+ define-properties: "npm:^1.1.3"
+ es-abstract: "npm:^1.17.5"
+ checksum: 10c0/94c7978566cffa1327d470fd924366438af9b04b497c43a9805e476e2e908aa37a1fd34cc0911156c17556dab62159d12c7b92b3cc304c3e1281fe4c8e668f40
+ languageName: node
+ linkType: hard
+
+"string.prototype.trim@npm:^1.2.10":
+ version: 1.2.11
+ resolution: "string.prototype.trim@npm:1.2.11"
+ dependencies:
+ call-bind: "npm:^1.0.9"
+ call-bound: "npm:^1.0.4"
+ define-data-property: "npm:^1.1.4"
+ define-properties: "npm:^1.2.1"
+ es-abstract: "npm:^1.24.2"
+ es-object-atoms: "npm:^1.1.2"
+ has-property-descriptors: "npm:^1.0.2"
+ safe-regex-test: "npm:^1.1.0"
+ checksum: 10c0/b153cf8ed06db82ff40e27829e88e5c13f45eff9799f1d5707626e25989b488b059d6f5d57011e07f77745e28451e16735f295bc59c8ae146a4fd73a442366b0
+ languageName: node
+ linkType: hard
+
+"string.prototype.trimend@npm:^1.0.9":
+ version: 1.0.10
+ resolution: "string.prototype.trimend@npm:1.0.10"
+ dependencies:
+ call-bind: "npm:^1.0.9"
+ call-bound: "npm:^1.0.4"
+ define-properties: "npm:^1.2.1"
+ es-object-atoms: "npm:^1.1.2"
+ checksum: 10c0/cc09233181769047a5330becfd5740fec5f0c8137886e7b553626788b00f75df9f34db1159bc52dbb7fc389b8ebb6e1dab44c8c9e31eb600039729a542013286
+ languageName: node
+ linkType: hard
+
+"string.prototype.trimstart@npm:^1.0.8":
+ version: 1.0.8
+ resolution: "string.prototype.trimstart@npm:1.0.8"
+ dependencies:
+ call-bind: "npm:^1.0.7"
+ define-properties: "npm:^1.2.1"
+ es-object-atoms: "npm:^1.0.0"
+ checksum: 10c0/d53af1899959e53c83b64a5fd120be93e067da740e7e75acb433849aa640782fb6c7d4cd5b84c954c84413745a3764df135a8afeb22908b86a835290788d8366
+ languageName: node
+ linkType: hard
+
"string_decoder@npm:^1.1.1":
version: 1.3.0
resolution: "string_decoder@npm:1.3.0"
@@ -11057,6 +12387,15 @@ __metadata:
languageName: node
linkType: hard
+"ts-api-utils@npm:^2.5.0":
+ version: 2.5.0
+ resolution: "ts-api-utils@npm:2.5.0"
+ peerDependencies:
+ typescript: ">=4.8.4"
+ checksum: 10c0/767849383c114e7f1971fa976b20e73ac28fd0c70d8d65c0004790bf4d8f89888c7e4cf6d5949f9c1beae9bc3c64835bef77bbe27fddf45a3c7b60cebcf85c8c
+ languageName: node
+ linkType: hard
+
"ts-node@npm:^10.9.2":
version: 10.9.2
resolution: "ts-node@npm:10.9.2"
@@ -11148,6 +12487,74 @@ __metadata:
languageName: node
linkType: hard
+"typed-array-buffer@npm:^1.0.3":
+ version: 1.0.3
+ resolution: "typed-array-buffer@npm:1.0.3"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ es-errors: "npm:^1.3.0"
+ is-typed-array: "npm:^1.1.14"
+ checksum: 10c0/1105071756eb248774bc71646bfe45b682efcad93b55532c6ffa4518969fb6241354e4aa62af679ae83899ec296d69ef88f1f3763657cdb3a4d29321f7b83079
+ languageName: node
+ linkType: hard
+
+"typed-array-byte-length@npm:^1.0.3":
+ version: 1.0.3
+ resolution: "typed-array-byte-length@npm:1.0.3"
+ dependencies:
+ call-bind: "npm:^1.0.8"
+ for-each: "npm:^0.3.3"
+ gopd: "npm:^1.2.0"
+ has-proto: "npm:^1.2.0"
+ is-typed-array: "npm:^1.1.14"
+ checksum: 10c0/6ae083c6f0354f1fce18b90b243343b9982affd8d839c57bbd2c174a5d5dc71be9eb7019ffd12628a96a4815e7afa85d718d6f1e758615151d5f35df841ffb3e
+ languageName: node
+ linkType: hard
+
+"typed-array-byte-offset@npm:^1.0.4":
+ version: 1.0.4
+ resolution: "typed-array-byte-offset@npm:1.0.4"
+ dependencies:
+ available-typed-arrays: "npm:^1.0.7"
+ call-bind: "npm:^1.0.8"
+ for-each: "npm:^0.3.3"
+ gopd: "npm:^1.2.0"
+ has-proto: "npm:^1.2.0"
+ is-typed-array: "npm:^1.1.15"
+ reflect.getprototypeof: "npm:^1.0.9"
+ checksum: 10c0/3d805b050c0c33b51719ee52de17c1cd8e6a571abdf0fffb110e45e8dd87a657e8b56eee94b776b13006d3d347a0c18a730b903cf05293ab6d92e99ff8f77e53
+ languageName: node
+ linkType: hard
+
+"typed-array-length@npm:^1.0.7":
+ version: 1.0.8
+ resolution: "typed-array-length@npm:1.0.8"
+ dependencies:
+ call-bind: "npm:^1.0.9"
+ for-each: "npm:^0.3.5"
+ gopd: "npm:^1.2.0"
+ is-typed-array: "npm:^1.1.15"
+ possible-typed-array-names: "npm:^1.1.0"
+ reflect.getprototypeof: "npm:^1.0.10"
+ checksum: 10c0/5319f740fc426a3217182c2f7c87656acb0903e046de5a938e30167337d26abf1bb3ad4b32833a72521a4cc58223aec80627b38b357d0a3d5fd64881427e77ab
+ languageName: node
+ linkType: hard
+
+"typescript-eslint@npm:^8.61.0":
+ version: 8.67.0
+ resolution: "typescript-eslint@npm:8.67.0"
+ dependencies:
+ "@typescript-eslint/eslint-plugin": "npm:8.67.0"
+ "@typescript-eslint/parser": "npm:8.67.0"
+ "@typescript-eslint/typescript-estree": "npm:8.67.0"
+ "@typescript-eslint/utils": "npm:8.67.0"
+ peerDependencies:
+ eslint: ^8.57.0 || ^9.0.0 || ^10.0.0
+ typescript: ">=4.8.4 <6.1.0"
+ checksum: 10c0/6ec860f6763be8a5fabf143ff8b6d4e43b98be0c781afc4725eda578ba0e0cecfcc1f06bd1b56fcccc41fa3fc15e4661ec32120d28f2e7abe4953e91ee346de1
+ languageName: node
+ linkType: hard
+
"typescript@npm:5.9.3":
version: 5.9.3
resolution: "typescript@npm:5.9.3"
@@ -11175,6 +12582,18 @@ __metadata:
languageName: node
linkType: hard
+"unbox-primitive@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "unbox-primitive@npm:1.1.0"
+ dependencies:
+ call-bound: "npm:^1.0.3"
+ has-bigints: "npm:^1.0.2"
+ has-symbols: "npm:^1.1.0"
+ which-boxed-primitive: "npm:^1.1.1"
+ checksum: 10c0/7dbd35ab02b0e05fe07136c72cb9355091242455473ec15057c11430129bab38b7b3624019b8778d02a881c13de44d63cd02d122ee782fb519e1de7775b5b982
+ languageName: node
+ linkType: hard
+
"undici-types@npm:>=7.24.0 <7.24.7":
version: 7.24.6
resolution: "undici-types@npm:7.24.6"
@@ -11545,6 +12964,67 @@ __metadata:
languageName: node
linkType: hard
+"which-boxed-primitive@npm:^1.1.0, which-boxed-primitive@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "which-boxed-primitive@npm:1.1.1"
+ dependencies:
+ is-bigint: "npm:^1.1.0"
+ is-boolean-object: "npm:^1.2.1"
+ is-number-object: "npm:^1.1.1"
+ is-string: "npm:^1.1.1"
+ is-symbol: "npm:^1.1.1"
+ checksum: 10c0/aceea8ede3b08dede7dce168f3883323f7c62272b49801716e8332ff750e7ae59a511ae088840bc6874f16c1b7fd296c05c949b0e5b357bfe3c431b98c417abe
+ languageName: node
+ linkType: hard
+
+"which-builtin-type@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "which-builtin-type@npm:1.2.1"
+ dependencies:
+ call-bound: "npm:^1.0.2"
+ function.prototype.name: "npm:^1.1.6"
+ has-tostringtag: "npm:^1.0.2"
+ is-async-function: "npm:^2.0.0"
+ is-date-object: "npm:^1.1.0"
+ is-finalizationregistry: "npm:^1.1.0"
+ is-generator-function: "npm:^1.0.10"
+ is-regex: "npm:^1.2.1"
+ is-weakref: "npm:^1.0.2"
+ isarray: "npm:^2.0.5"
+ which-boxed-primitive: "npm:^1.1.0"
+ which-collection: "npm:^1.0.2"
+ which-typed-array: "npm:^1.1.16"
+ checksum: 10c0/8dcf323c45e5c27887800df42fbe0431d0b66b1163849bb7d46b5a730ad6a96ee8bfe827d078303f825537844ebf20c02459de41239a0a9805e2fcb3cae0d471
+ languageName: node
+ linkType: hard
+
+"which-collection@npm:^1.0.2":
+ version: 1.0.2
+ resolution: "which-collection@npm:1.0.2"
+ dependencies:
+ is-map: "npm:^2.0.3"
+ is-set: "npm:^2.0.3"
+ is-weakmap: "npm:^2.0.2"
+ is-weakset: "npm:^2.0.3"
+ checksum: 10c0/3345fde20964525a04cdf7c4a96821f85f0cc198f1b2ecb4576e08096746d129eb133571998fe121c77782ac8f21cbd67745a3d35ce100d26d4e684c142ea1f2
+ languageName: node
+ linkType: hard
+
+"which-typed-array@npm:^1.1.16, which-typed-array@npm:^1.1.19":
+ version: 1.1.22
+ resolution: "which-typed-array@npm:1.1.22"
+ dependencies:
+ available-typed-arrays: "npm:^1.0.7"
+ call-bind: "npm:^1.0.9"
+ call-bound: "npm:^1.0.4"
+ for-each: "npm:^0.3.5"
+ get-proto: "npm:^1.0.1"
+ gopd: "npm:^1.2.0"
+ has-tostringtag: "npm:^1.0.2"
+ checksum: 10c0/e59db184a4e78b461fac3b05fafc1e7badbbedafbf04a967ee1de73717f1f9723a79699e7b5de71d449541cb5da8353efc01a4f8a72a152479850e54fa196c40
+ languageName: node
+ linkType: hard
+
"which@npm:^2.0.1":
version: 2.0.2
resolution: "which@npm:2.0.2"
@@ -11814,7 +13294,7 @@ __metadata:
languageName: node
linkType: hard
-"zod-to-json-schema@npm:^3.25.1":
+"zod-to-json-schema@npm:^3.25.1, zod-to-json-schema@npm:^3.25.2":
version: 3.25.2
resolution: "zod-to-json-schema@npm:3.25.2"
peerDependencies:
@@ -11823,6 +13303,15 @@ __metadata:
languageName: node
linkType: hard
+"zod-validation-error@npm:^3.5.0 || ^4.0.0":
+ version: 4.0.2
+ resolution: "zod-validation-error@npm:4.0.2"
+ peerDependencies:
+ zod: ^3.25.0 || ^4.0.0
+ checksum: 10c0/0ccfec48c46de1be440b719cd02044d4abb89ed0e14c13e637cd55bf29102f67ccdba373f25def0fc7130e5f15025be4d557a7edcc95d5a3811599aade689e1b
+ languageName: node
+ linkType: hard
+
"zod@npm:^3.25.76":
version: 3.25.76
resolution: "zod@npm:3.25.76"
diff --git a/specification/proposals/templates/README.md b/specification/proposals/templates/README.md
new file mode 100644
index 0000000000..fd2ec6b2a1
--- /dev/null
+++ b/specification/proposals/templates/README.md
@@ -0,0 +1,737 @@
+# A2UI Template Specification
+
+## Abstract
+
+This document defines the authoritative specification for **A2UI Templates**.
+
+Templates provide a declarative, human-readable mechanism for authoring reusable UI subtrees in nested YAML or via native programmatic render functions. At generation time, an agent or Large Language Model (LLM) outputs compact, high-level template invocations (such as `UserProfile("u1", "Alice")` or `PayrollSummary("Eng", true)`). The backend SDK expands these invocations into standard, flat A2UI Basic Catalog components in a single synchronous pass before emitting standard A2UI protocol messages (`updateComponents`) to the client.
+
+This architecture achieves three fundamental objectives:
+
+1. **Human Readability**: Layouts are authored as clean, natural tree hierarchies in YAML or native language code, eliminating artificial IDs and flat array boilerplate.
+2. **Token Efficiency & Context Optimization**: LLMs emit concise function-like signatures rather than verbose, deeply nested UI component trees, saving prompt context and generation tokens.
+3. **Zero Client Overhead**: Client renderers (@a2ui/react, @a2ui/lit, @a2ui/angular, @a2ui/flutter) implement only standard Basic Catalog primitives (`Card`, `Column`, `Row`, `Text`, `Divider`, `Icon`, `Button`). No custom client widgets, dynamic code deployment, or renderer plugins are required.
+
+---
+
+## 1. Architectural Overview & Execution Pipeline
+
+The template engine operates entirely server-side within the A2UI Agent SDK:
+
+```mermaid
+flowchart TD
+ subgraph Stage1["1. Authoring & Registration"]
+ YAML["Static YAML Files (multi-doc '---' & cross-references)"]
+ Dynamic["Dynamic Resolvers (data-binding & programmatic AST)"]
+ end
+
+ subgraph Stage2["2. Synthetic Catalog Generation"]
+ Proc["TemplateProcessor indexes templates & synthesizes virtual Component Catalog"]
+ end
+
+ subgraph Stage3["3. Model Prompt Generation & Inference"]
+ Prompt["PromptGenerator injects template signatures into prompt"]
+ LLM["LLM emits compact Express DSL / JSON (e.g. root = TeamRoster(...))"]
+ end
+
+ subgraph Stage4["4. Synchronous Template Expansion"]
+ Expand["TemplateProcessor unrolls loops, substitutes params, assigns synthetic IDs"]
+ end
+
+ subgraph Stage5["5. Standard A2UI Protocol Emission"]
+ Msg["Emits createSurface & updateComponents (100% standard Basic Catalog primitives)"]
+ end
+
+ subgraph Stage6["6. Client Renderer Execution"]
+ Client["Client renderers paint standard components & bind reactive paths to client DataModel"]
+ end
+
+ Stage1 --> Stage2
+ Stage2 --> Stage3
+ Stage3 --> Stage4
+ Stage4 --> Stage5
+ Stage5 --> Stage6
+```
+
+---
+
+## 2. Template Taxonomy
+
+A2UI supports three template authoring styles:
+
+### A. Declarative Static Templates (YAML)
+
+Declarative static templates define immutable layout trees authored in YAML files. All parameter placeholders are populated directly from arguments provided by the model or caller.
+
+```yaml
+version: '0.1'
+name: UserProfile
+catalogs:
+ - 'https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json'
+description: Standard identity card for team members.
+parameters:
+ userId:
+ type: string
+ description: Unique user identifier.
+ userName:
+ type: string
+ description: Full name of the user.
+ role:
+ type: string
+ description: Position or title within the team.
+ default: Team Member
+
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Icon
+ name: person
+ - component: Text
+ text: '{{ userName }}'
+ variant: h3
+ - component: Text
+ text: '{{ role }}'
+ variant: caption
+```
+
+### B. Dynamic Templates: Data-Binding Mode (`resolver + layout`)
+
+Data-binding dynamic templates decouple public model parameters from private or live backend data.
+
+- **Public Surface**: The model only sees and outputs high-level lookup parameters (e.g. `employeeId: "emp_101"`).
+- **Server Resolver**: At expansion time, a backend callback executes (e.g., querying an internal HR database or API) and produces a data dictionary.
+- **Layout Inflation**: The resolved dictionary is merged with the caller's arguments and applied to an underlying static YAML layout.
+
+```python
+# Server Registration
+dynamic_salary = DynamicTemplate(
+ name="EmployeeSalaryCard",
+ catalogs=["https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"],
+ resolver=fetch_private_compensation,
+ layout=salary_yaml_layout,
+ description="Verified compensation card. Pass only employeeId.",
+)
+```
+
+**Security Rationale**: Confidential numbers (e.g., executive salaries, PII) never enter the model's prompt context window or inference transcript.
+
+### C. Dynamic Templates: Programmatic Render Mode (`render_fn`)
+
+Programmatic dynamic templates bypass static YAML layouts entirely. Instead, a developer writes a native function in the host language (Python, Dart, etc.) that accepts parameters and directly returns a UI component tree.
+
+```python
+def render_payroll_summary(department: str = "Engineering", includeBonus: bool = True) -> dict:
+ total_base = sum(e.salary for e in db.get_dept(department))
+ total_bonus = sum(e.bonus for e in db.get_dept(department))
+
+ rows = []
+ for emp in db.get_dept(department):
+ cols = [
+ {"component": "Text", "text": emp.name, "variant": "body"},
+ {"component": "Text", "text": f"${emp.salary:,}", "variant": "body"}
+ ]
+ if includeBonus:
+ cols.append({"component": "Text", "text": f"${emp.bonus:,}", "variant": "body"})
+ rows.append({"component": "Row", "justify": "spaceBetween", "children": cols})
+
+ return {
+ "component": "Card",
+ "child": {
+ "component": "Column",
+ "children": [
+ {"component": "Text", "text": f"Payroll Summary: {department}", "variant": "h2"},
+ {"component": "Divider", "axis": "horizontal"},
+ *rows,
+ {"component": "Divider", "axis": "horizontal"},
+ {"component": "Text", "text": f"Total Budget: ${total_base + (total_bonus if includeBonus else 0):,}", "variant": "h3"}
+ ]
+ }
+ }
+
+payroll_tmpl = DynamicTemplate(
+ name="PayrollSummary",
+ catalogs=["https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"],
+ render=render_payroll_summary,
+ description="Dynamic payroll calculation matrix.",
+)
+```
+
+**Advantages**:
+
+- Full host language power: arbitrary `for` loops, mathematical calculations, currency formatting, conditionals, and recursion.
+- Polymorphic return values: accepts raw dictionaries/maps, dataclasses, or typesafe fluent builder objects (`Card()`, `Column()`).
+
+---
+
+## 3. Loop Processing: Server Unrolling vs. Client Data Model
+
+A critical question in template design is: **When does the template engine unroll loops vs. when are collections handled by the client runtime?**
+
+### Comparison Matrix
+
+| Dimension | Server-Side Template Unrolling | Client-Side DataModel Loop |
+| :--------------------- | :-------------------------------------------------------------------------------- | :--------------------------------------------------------------------------------- |
+| **Execution Point** | Backend SDK (`TemplateProcessor`) during template expansion. | Client Renderer runtime during paint/state updates. |
+| **Data Source** | Static YAML literals, LLM invocation arguments, or server resolver output. | Client `DataModel` tree (e.g. `/session/cart/items`). |
+| **Component Output** | Emits $N$ concrete Basic Catalog component nodes with synthesized unique IDs. | Emits a single repeater/collection component with a `DataBinding` path. |
+| **Client Requirement** | Zero. Standard Basic Catalog renderers render it like any other static UI. | Requires client-side repeater support or SDK session re-renders. |
+| **Dynamic Mutation** | Immutable once generated unless the agent emits a new `updateComponents` message. | Reactively re-renders when the client data model updates (e.g. via button events). |
+
+### Example 1: Server-Side Template Loop Unrolling
+
+A template author specifies a loop over a parameter array:
+
+#### Template Definition:
+
+```yaml
+version: '0.1'
+name: TeamGoalList
+catalogs:
+ - 'https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json'
+parameters:
+ teamName: {type: string}
+ goals: {type: array}
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Text
+ text: 'Objectives: {{ teamName }}'
+ variant: h2
+ - component: Column
+ children:
+ loop:
+ param: goals
+ as: goal
+ item:
+ component: Row
+ justify: spaceBetween
+ children:
+ - component: Text
+ text: '{{ goal.title }}'
+ - component: Text
+ text: '{{ goal.priority }}'
+ variant: caption
+```
+
+#### Model Invocation:
+
+```text
+root = TeamGoalList("Core Team", [
+ {title: "Ship Protocol", priority: "High"},
+ {title: "Write Tests", priority: "Medium"}
+])
+```
+
+#### Expanded Output Sent to Client:
+
+The engine unrolls the loop into concrete, synthetic child components:
+
+```json
+[
+ {"id": "root", "component": "Card", "child": "root_child_column"},
+ {
+ "id": "root_child_column",
+ "component": "Column",
+ "children": ["root_child_column_children_0_text", "root_child_column_children_1_column"]
+ },
+ {
+ "id": "root_child_column_children_0_text",
+ "component": "Text",
+ "text": "Objectives: Core Team",
+ "variant": "h2"
+ },
+ {
+ "id": "root_child_column_children_1_column",
+ "component": "Column",
+ "children": [
+ "root_child_column_children_1_column_goals_0_row",
+ "root_child_column_children_1_column_goals_1_row"
+ ]
+ },
+ {
+ "id": "root_child_column_children_1_column_goals_0_row",
+ "component": "Row",
+ "justify": "spaceBetween",
+ "children": [
+ "root_child_column_children_1_column_goals_0_row_children_0_text",
+ "root_child_column_children_1_column_goals_0_row_children_1_text"
+ ]
+ },
+ {
+ "id": "root_child_column_children_1_column_goals_0_row_children_0_text",
+ "component": "Text",
+ "text": "Ship Protocol"
+ },
+ {
+ "id": "root_child_column_children_1_column_goals_0_row_children_1_text",
+ "component": "Text",
+ "text": "High",
+ "variant": "caption"
+ },
+ {
+ "id": "root_child_column_children_1_column_goals_1_row",
+ "component": "Row",
+ "justify": "spaceBetween",
+ "children": [
+ "root_child_column_children_1_column_goals_1_row_children_0_text",
+ "root_child_column_children_1_column_goals_1_row_children_1_text"
+ ]
+ },
+ {
+ "id": "root_child_column_children_1_column_goals_1_row_children_0_text",
+ "component": "Text",
+ "text": "Write Tests"
+ },
+ {
+ "id": "root_child_column_children_1_column_goals_1_row_children_1_text",
+ "component": "Text",
+ "text": "Medium",
+ "variant": "caption"
+ }
+]
+```
+
+---
+
+## 4. Relationship to the A2UI Data Model
+
+Templates and the A2UI Data Model operate in complementary scopes:
+
+- **Templates** expand during **server-side inference / response formulation**.
+- **Data Model** operates during **client-side runtime interaction & reactivity**.
+
+Templates interact with the client Data Model in three distinct patterns:
+
+### Pattern 1: Dynamic Path Plumbing (Path Interpolation)
+
+Templates can accept path prefixes or IDs as parameters, constructing reactive client-side binding paths:
+
+```yaml
+version: '0.1'
+name: BoundLiveMetric
+catalogs:
+ - 'https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json'
+parameters:
+ metricKey: {type: string}
+ label: {type: string}
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Text
+ text: '{{ label }}'
+ - component: Text
+ text:
+ path: '/system/metrics/{{ metricKey }}/currentValue'
+```
+
+**Expanded Output:**
+
+```json
+{
+ "id": "root_val",
+ "component": "Text",
+ "text": {
+ "path": "/system/metrics/cpuLoad/currentValue"
+ }
+}
+```
+
+_Client Behavior_: The client renderer attaches a live subscriber to `/system/metrics/cpuLoad/currentValue`. When telemetry updates arrive via `updateDataModel`, the component automatically re-renders without server roundtrips.
+
+### Pattern 2: Direct `DataBinding` Passthrough
+
+When a template parameter has `type: object`, an agent or caller can pass an explicit A2UI binding object:
+
+#### Model Invocation:
+
+```text
+root = MetricCard("Memory Used", {path: "/device/mem_percent"})
+```
+
+#### Template Layout:
+
+```yaml
+version: '0.1'
+templateId: MetricCard
+parameters:
+ title: {type: string}
+ val: {type: object}
+layout:
+ component: Column
+ children:
+ - component: Text
+ text: '{{ title }}'
+ - component: Text
+ text: '{{ val }}'
+```
+
+**Expanded Output:**
+
+Because `{{ val }}` is an exact-match substitution, the dictionary type is strictly preserved:
+
+```json
+{
+ "component": "Text",
+ "text": {"path": "/device/mem_percent"}
+}
+```
+
+### Pattern 3: Hardcoded Session State References
+
+Templates can embed constant client bindings for global session preferences:
+
+```yaml
+layout:
+ component: Text
+ text:
+ path: '/session/currentUser/displayName'
+```
+
+---
+
+## 5. Catalog Declaration, Validation & Multi-Catalog Disambiguation
+
+Templates must declare which catalog(s) they are authored against via the top-level `catalogs` property.
+
+### A. Mandatory Explicit Catalogs (No Basic Catalog Defaults)
+
+The template engine enforces strict decoupling from any specific catalog:
+
+- **No Hardcoded Defaults**: `TemplateProcessor` does not default to the Basic Catalog or any other specific catalog.
+- **Explicit Catalog Requirement**: All catalogs required by registered templates must be explicitly provided to the processor upon initialization (e.g. via `catalogs={...}`).
+- **Static Integrity Validation**: At registration time, the engine validates that every template's declared `catalogs` can be resolved against the provided catalog registry, and every primitive component referenced in `layout` exists within those catalogs with valid properties.
+
+### B. Prefix-Free Automatic Component Resolution
+
+In layout trees, authors write clean, standard component names (`Card`, `Text`, `HeartRateGraph`) without prefixes or namespace boilerplate:
+
+- **Unique Match (Standard Case)**: If component `Foo` exists in exactly one declared catalog, it automatically resolves to that catalog.
+- **Name Collision**: If two declared catalogs define `Foo`, the author can specify `catalogId` on that specific component in the layout to disambiguate. If omitted, the engine raises an `AmbiguousComponentError`.
+- **Unknown Component**: If `Foo` is found in zero declared catalogs, the engine raises an `UnknownComponentError`.
+
+### C. Protocol Version Rules: v0.9 vs. v1.0
+
+The template engine tailors its expansion and output depending on the target protocol version:
+
+| Dimension | A2UI v0.9 / v0.9.1 Behavior | A2UI v1.0 Behavior |
+| :---------------------------- | :------------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------- |
+| **Surface Catalog Model** | Single catalog per surface (`createSurface.catalogId` required). | Mixable catalogs (`createSurface.catalogId` optional default). |
+| **Multi-Catalog Templates** | **Rejected**: If a template declares multiple catalogs, unrolling onto a v0.9 surface raises `CatalogCompatibilityError`. | **Supported**: Expanded seamlessly across mixed catalogs. |
+| **Surface Validation** | Template's resolved catalog MUST match `createSurface.catalogId`. | All catalogs referenced by the template must be present in surface `supportedCatalogIds`. |
+| **Expanded Component Output** | `catalogId` is **never** emitted on expanded component dicts (illegal property in v0.9). | `catalogId` is automatically injected on any component whose catalog differs from surface default. |
+
+---
+
+## 6. Sub-Template Imports & Global Identity
+
+Templates decouple their local invocation name from their optional global identity:
+
+- **`name`** (Required): Component tag name used in layout trees and LLM prompts (`^[A-Za-z][A-Za-z0-9_]*$`). `templateId` is accepted as a backwards-compatible alias.
+- **`id`** (Optional): Globally unique URI or URN string (e.g. `https://company.org/templates/card/v1.json`) for package distribution and version pinning.
+- **`imports`** (Optional): List of global template IDs, or dictionary mapping local aliases to global template IDs (`imports: { VendorCard: "https://vendor.com/card.json" }`).
+
+### Usage Tiers
+
+1. **Tier 1 (Simple / Local)**: Templates omit `id` and `imports`. Sibling templates in the same file or registry resolve each other directly by `name`.
+2. **Tier 2 (Modular / Distributed)**: Templates declare `id` and import external sub-templates by `id` or alias via `imports`.
+
+---
+
+## 7. The Synthetic Catalog System
+
+To make templates discoverable and invoke-able by LLMs, the backend converts registered templates into a **Synthetic Component Catalog**.
+
+### The Catalog Synthesis Algorithm
+
+When `TemplateProcessor(templates, catalogs)` is initialized:
+
+1. It indexes all provided catalogs.
+2. For each registered `StaticTemplate` and `DynamicTemplate`:
+ - It registers a new component definition under `components[template.name]`.
+ - It maps semantic parameter definitions to JSON schema properties:
+ - `string` $\rightarrow$ `{"type": "string"}`
+ - `number` / `integer` $\rightarrow$ `{"type": "number"}` / `{"type": "integer"}`
+ - `boolean` $\rightarrow$ `{"type": "boolean"}`
+ - `enum` $\rightarrow$ `{"type": "string", "enum": param.values}`
+ - `object` $\rightarrow$ `{"type": "object", "properties": ...}`
+ - `array` $\rightarrow$ `{"type": "array", "items": ...}`
+ - `child` $\rightarrow$ `{"$ref": "#/$defs/ComponentReference"}`
+ - `children` $\rightarrow$ `{"$ref": "#/$defs/ComponentReferenceList"}`
+ - It copies the `description` to provide context for the model.
+3. The synthetic catalog is passed to `PromptGenerator` (Express, Elemental, Atom, Direct JSON), which automatically writes the syntax rules and documentation into the system prompt.
+
+### Surface Isolation Boundary
+
+```mermaid
+flowchart LR
+ Agent["LLM Agent"] <--> SyntheticCatalog["Synthetic Catalog (Templates + Primitives)"]
+ SyntheticCatalog <--> Processor["TemplateProcessor"]
+ Processor -->|"Synchronously expands to flat primitives"| Client["Client Renderer (Basic Catalog)"]
+```
+
+The synthetic catalog is an ephemeral compile-time construct. The client renderer is completely unaware that templates exist.
+
+---
+
+## 8. Parameter Expressions & Substitution Engine
+
+The template substitution engine replaces expressions according to strict typing and evaluation rules using standard double-curly Mustache syntax (`{{ param }}`).
+
+### Rule 1: Exact Match Substitution (Type Preserving)
+
+If a string field value exactly matches the parameter token regex `^\{\{\s*([a-zA-Z0-9_]+(?:\.[a-zA-Z0-9_]+)*)\s*\}\}$`:
+
+- The entire field is replaced by the native runtime value of the parameter.
+- **Integers remain integers**: `level: "{{ userLevel }}"` $\rightarrow$ `level: 4` (not `"4"`).
+- **Booleans remain booleans**: `checked: "{{ isActive }}"` $\rightarrow$ `checked: true` (not `"true"`).
+- **Objects and Arrays remain native structures**: `items: "{{ memberList }}"` $\rightarrow$ `items: [{...}, {...}]`.
+
+### Rule 2: Embedded String Interpolation
+
+If a parameter token appears alongside other characters (e.g. `"Hello, {{ userName }}!"` or `"{{ dept }} - {{ code }}"`):
+
+- All tokens matching `\{\{\s*([a-zA-Z0-9_]+(?:\.[a-zA-Z0-9_]+)*)\s*\}\}` are replaced by their string representations.
+- Evaluates to a native string.
+
+### Rule 3: Client DataModel Disambiguation (`formatString`)
+
+Because template substitutions use double curlies `{{ ... }}`, client-side reactive expressions and data-model bindings in `formatString` (e.g. `${/user/name}`) pass through completely untouched without requiring escaping:
+
+```yaml
+component: Text
+text:
+ call: formatString
+ args:
+ value: 'Hello, ${/user/name}! Your team is {{ teamName }}.'
+```
+
+During server-side template expansion:
+
+- `{{ teamName }}` is resolved server-side and replaced with `"Engineering"`.
+- `${/user/name}` is preserved verbatim and emitted directly to the client renderer for reactive data-binding.
+
+### Rule 4: Deep Dot-Notation for Structured Objects
+
+Templates natively support deep dot-notation paths on object parameters:
+
+#### Invocation:
+
+```text
+root = AccountCard({
+ account: {
+ id: "acc_99",
+ profile: {name: "Alpha Corp", tier: "Enterprise"}
+ }
+})
+```
+
+#### Template Layout:
+
+```yaml
+version: '0.1'
+templateId: AccountCard
+parameters:
+ account: {type: object}
+layout:
+ component: Card
+ child:
+ component: Text
+ text: '{{ account.profile.name }} ({{ account.profile.tier }})'
+```
+
+**Expanded Output:**
+
+```json
+{
+ "component": "Text",
+ "text": "Alpha Corp (Enterprise)"
+}
+```
+
+### Rule 5: String Format AST Expressions
+
+For complex string formatting across multiple languages:
+
+```yaml
+format: 'Level {lvl} ({pts} points)'
+args:
+ lvl: '{{ level }}'
+ pts: '{{ experiencePoints }}'
+```
+
+### Rule 6: Token Escaping
+
+To emit a literal `{{ foo }}` string without triggering parameter substitution, escape the opening curly braces with a backslash:
+
+- `\{{ keep_literal }}` $\rightarrow$ evaluates to literal `"{{ keep_literal }}"`.
+
+### Rule 7: Missing Values & Defaults
+
+- If an argument is omitted but has a declared `default` in its parameter schema, the `default` is used.
+- If an argument is omitted, has no `default`, and is not required: the property is omitted from the synthesized component (it is not emitted as `null`).
+- If an argument is required and missing: expansion raises a `TemplateParameterError`.
+
+---
+
+## 9. Deterministic Synthetic ID Generation Algorithm
+
+To guarantee collision-free component IDs across multiple template instances and deep nesting, implementations in all languages (Python, Dart, TypeScript) must implement the following deterministic naming rules:
+
+### ID Synthesis Specification
+
+```
+Let instance_id be the ID passed to expand_template(instance_id, template_id, params)
+
+1. Root Node:
+ id = instance_id
+
+2. Single Child Slot (e.g. card.child):
+ id = "{parent_id}_{slot_name}_{normalized_type}"
+ (where normalized_type is the component or template type converted to lowercase)
+ Example: "root_child_column"
+
+3. Multi-Child List Slot (e.g. column.children[i]):
+ id = "{parent_id}_{slot_name}_{i}_{normalized_type}"
+ (where normalized_type is the component or template type converted to lowercase)
+ Example: "root_children_0_text", "root_children_1_button"
+
+4. Loop Iteration Item (e.g. loop over param "members", iteration index i):
+ id = "{parent_id}_{param_name}_{i}_{normalized_type}"
+ (where normalized_type is the component or template type converted to lowercase)
+ Example: "team_col_members_0_userprofile"
+
+5. Authored Explicit IDs:
+ If a component in the template specifies an explicit id (e.g. id: "hero_img"):
+ id = "{instance_id}_{authored_id}"
+ Example: "my_card_hero_img"
+```
+
+This guarantees that two instances of the same template (`card_1` and `card_2`) on the same surface will never produce colliding component IDs.
+
+---
+
+## 10. Higher-Order Container Templates (`child` and `children` Slots)
+
+Templates can define structural containers that receive caller-provided components.
+
+### Example: `SectionCard` Container
+
+```yaml
+version: '0.1'
+name: SectionCard
+catalogs:
+ - 'https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json'
+parameters:
+ title: {type: string}
+ headerAction: {type: child}
+ children: {type: children}
+
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Row
+ justify: spaceBetween
+ align: center
+ children:
+ - component: Text
+ text: '{{ title }}'
+ variant: h2
+ - component: Column
+ children: '{{ headerAction }}'
+ - component: Divider
+ axis: horizontal
+ - component: Column
+ children: '{{ children }}'
+```
+
+#### Model Invocation:
+
+```text
+root = SectionCard(
+ "Project Status",
+ Button("Refresh", {action: "reload"}),
+ [
+ Text("Phase 1: Complete"),
+ Text("Phase 2: In Progress")
+ ]
+)
+```
+
+The template engine replaces `{{ headerAction }}` with the synthesized single child node, and concatenates the `{{ children }}` component list into the body column.
+
+---
+
+## 11. Error Handling, Cycle Guards & Safety
+
+### Recursion & Circular Reference Detection
+
+Templates can invoke other templates. However, circular references in template definitions (`A` invokes `B`, which invokes `A`) must be caught immediately to prevent stack overflow.
+
+- **Definition Cycles vs. Instance Nesting**:
+ - **Definition Cycles (Prohibited)**: The cycle guard specifically tracks the chain of template _definitions_ being expanded (`TemplateA -> TemplateB -> TemplateA`). If a template definition unconditionally references itself or another template in a cycle, expansion terminates with `TemplateCycleError`.
+ - **Instance Nesting (Fully Supported)**: When a caller passes an instance of a template as an argument into another template's `child` or `children` slot (for example, a `Card` template containing a `Carousel` template whose items are other `Card` template instances), this is standard, safe hierarchical composition. Each instance receives a unique synthetic ID and is bounded by caller input.
+- **Call Stack Tracking**: The `TemplateProcessor` maintains an active `_call_stack: Set[str]` of template definition names currently being evaluated.
+- **Cycle Guard**: Before expanding any template definition, if `template_name in _call_stack`, expansion terminates immediately with `TemplateCycleError: Circular template reference detected: A -> B -> A`.
+- **Maximum Depth Guard**: An absolute limit (`MAX_EXPANSION_DEPTH = 50`) enforces termination even in deeply nested or runaway recursion.
+
+### Standard Error Hierarchy
+
+1. `TemplateNotFoundError`: Attempted to expand a template `name` or `id` not present in the registry.
+2. `TemplateParameterError`: Missing required parameter or invalid parameter type.
+3. `TemplateCycleError`: Circular reference detected during expansion.
+4. `TemplateDepthExceededError`: Expansion exceeded maximum recursion depth.
+5. `TemplateResolverError`: Exception raised by a dynamic template resolver function.
+6. `CatalogCompatibilityError`: Declared catalogs incompatible with target surface (e.g. multi-catalog template on v0.9 surface).
+7. `AmbiguousComponentError`: Component exists in multiple declared catalogs without disambiguation.
+8. `UnknownComponentError`: Component not found in any declared catalog.
+
+---
+
+## 12. Multi-Document YAML Streams (`---`)
+
+To streamline template maintenance, multiple templates can be defined in a single `.yaml` file separated by `---`:
+
+- **Order Independent**: Templates can reference templates declared later in the file (forward references).
+- **Batch Registration**: Loading a multi-doc file registers all defined templates atomically into the `TemplateProcessor`.
+
+---
+
+## 13. Template Versioning & Schema Evolution
+
+To ensure robust backward compatibility as template syntax and AST features evolve across future protocol releases, every template definition must declare a top-level `version` field.
+
+### Versioning Rules:
+
+1. **Mandatory Version Field**: Every YAML document (and each document within multi-doc streams separated by `---`) must include `version: "0.1"`.
+2. **Strict Schema Validation**: The canonical JSON schema enforces `"version": {"type": "string", "const": "0.1"}`. Attempting to inflate a template with an unsupported version raises an explicit `TemplateVersionError` / `ValueError`.
+3. **Future Extensibility**: As new template language capabilities are standardized (e.g. conditional slot rendering, client-expanded template directives), new version identifiers (such as `"0.2"` or `"1.0"`) allow engines to select the appropriate parser/evaluator without breaking legacy templates.
+
+---
+
+## 14. Conformance Checklist for SDK Implementations
+
+An implementation of the A2UI Template Engine in any language (Python, Dart, TypeScript, Go, etc.) is conformant if and only if it satisfies the following test requirements:
+
+- [ ] **Template Versioning**: Validates that all ingested templates declare `version: "0.1"` and rejects unsupported version strings.
+- [ ] **Catalog Decoupling**: Does not default to the Basic Catalog; requires catalogs to be passed explicitly and validates all components against them.
+- [ ] **Catalog Resolution & Disambiguation**: Resolves components across declared catalogs without prefixes; handles collision disambiguation via component-level `catalogId`.
+- [ ] **Protocol Version Output Rules**: Enforces v0.9 single-catalog surface constraints (stripping component `catalogId`); supports v1.0 mixable catalogs with automatic `catalogId` stamping.
+- [ ] **Sub-Template Imports**: Supports Tier 1 (local by `name`) and Tier 2 (modular by `id` with `imports` list and alias dictionary).
+- [ ] **Multi-Document Ingestion**: Parses single-doc and multi-doc (`---`) YAML streams.
+- [ ] **Forward Reference Resolution**: Expands templates regardless of registration order.
+- [ ] **Strict Native Type Preservation**: Exact `{{ param }}` substitutions preserve `int`, `float`, `bool`, `dict`, and `list` types.
+- [ ] **Dot-Notation Path Traversal**: Resolves arbitrary depth paths (e.g. `{{ user.details.address.zip }}`).
+- [ ] **Inline and Named Loop Expansion**: Accurately unrolls arrays into synthesized component subtrees with indexed child IDs.
+- [ ] **Deterministic Synthetic IDs**: Emits canonical hierarchical IDs matching the `{parent}_{slot}_{index}_{type}` specification.
+- [ ] **Two-Way DataModel Passthrough**: Preserves `{path: "..."}` dictionary bindings without string conversion.
+- [ ] **Cycle and Recursion Safeguards**: Catches circular references and depth violations with explicit exceptions.
+- [ ] **Synthetic Catalog Generation**: Generates valid A2UI JSON schema catalogs matching input parameter definitions.
+- [ ] **Polymorphic Dynamic Templates**: Supports both resolver-based static bindings and programmatic render functions.
diff --git a/specification/proposals/templates/examples/basic_cards.yaml b/specification/proposals/templates/examples/basic_cards.yaml
new file mode 100644
index 0000000000..9b03872d3a
--- /dev/null
+++ b/specification/proposals/templates/examples/basic_cards.yaml
@@ -0,0 +1,86 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+name: BasicUserProfile
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+description: Standard identity card for team members.
+parameters:
+ userId:
+ type: string
+ description: Unique user identifier.
+ userName:
+ type: string
+ description: Full name of the user.
+ role:
+ type: string
+ description: Position or title within the team.
+ default: Team Member
+
+layout:
+ component: Card
+ child:
+ component: Column
+ align: center
+ children:
+ - component: Icon
+ name: person
+ - component: Text
+ text: "{{ userName }}"
+ variant: h3
+ - component: Text
+ text: "{{ role }}"
+ variant: caption
+
+sampleData:
+ userId: usr_101
+ userName: Alice Smith
+ role: Lead Architect
+
+---
+version: "0.1"
+name: BasicMetricCard
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+description: Metric display card supporting both literal values and dynamic data model bindings.
+parameters:
+ title:
+ type: string
+ description: Metric title.
+ metricValue:
+ type: object
+ description: "Literal value or reactive DataBinding object (e.g. {path: '/telemetry/cpu'})."
+ status:
+ type: enum
+ values: ["normal", "warning", "critical"]
+ default: "normal"
+
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Text
+ text: "{{ title }}"
+ variant: caption
+ - component: Text
+ text: "{{ metricValue }}"
+ variant: h1
+
+sampleData:
+ title: CPU Load
+ metricValue:
+ path: /system/metrics/cpuLoad
+ status: normal
diff --git a/specification/proposals/templates/examples/feedback_item.yaml b/specification/proposals/templates/examples/feedback_item.yaml
new file mode 100644
index 0000000000..74796a58eb
--- /dev/null
+++ b/specification/proposals/templates/examples/feedback_item.yaml
@@ -0,0 +1,62 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+name: FeedbackItem
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+description: Card showing feedback note, author, and rating.
+
+parameters:
+ author:
+ type: string
+ title: Author Name
+ description: The name of the colleague or customer providing feedback.
+ note:
+ type: string
+ title: Feedback Note
+ description: The written feedback or retrospective comment.
+ rating:
+ type: number
+ title: Feedback Rating
+ description: Score from 1 to 5.
+ minimum: 1
+ maximum: 5
+ default: 5
+
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Text
+ text: "{{ note }}"
+ variant: body
+ - component: Divider
+ axis: horizontal
+ - component: Row
+ justify: spaceBetween
+ align: center
+ children:
+ - component: Text
+ text: "{{ author }}"
+ variant: caption
+ - component: Text
+ text: "Rating: {{ rating }}/5"
+ variant: caption
+
+sampleData:
+ author: Dr. Elena Vance
+ note: A2UI templates are fast and easy to compose.
+ rating: 5
diff --git a/specification/proposals/templates/examples/goal_item.yaml b/specification/proposals/templates/examples/goal_item.yaml
new file mode 100644
index 0000000000..f1be35d83f
--- /dev/null
+++ b/specification/proposals/templates/examples/goal_item.yaml
@@ -0,0 +1,75 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+name: GoalItem
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+description: Card showing an individual objective with priority, title, target date, and action button.
+
+parameters:
+ title:
+ type: string
+ title: Goal Title
+ description: Summary title of the objective.
+ priority:
+ type: enum
+ title: Priority Level
+ description: Urgency rating for the objective.
+ values:
+ - High
+ - Medium
+ - Low
+ default: Medium
+ targetDate:
+ type: string
+ title: Target Date
+ description: Target completion date in YYYY-MM-DD format.
+ default: "2026-12-31"
+
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Row
+ justify: spaceBetween
+ align: center
+ children:
+ - component: Text
+ text: "Priority: {{ priority }}"
+ variant: caption
+ - component: Icon
+ name: star
+ - component: Text
+ text: "{{ title }}"
+ variant: h4
+ - component: Divider
+ axis: horizontal
+ - component: Row
+ justify: spaceBetween
+ align: center
+ children:
+ - component: Text
+ text: "Due: {{ targetDate }}"
+ variant: caption
+ - component: Button
+ child:
+ component: Text
+ text: View Details
+
+sampleData:
+ title: Launch A2UI SDK v1.0
+ priority: High
+ targetDate: "2026-09-30"
diff --git a/specification/proposals/templates/examples/nested_lists.yaml b/specification/proposals/templates/examples/nested_lists.yaml
new file mode 100644
index 0000000000..8736a150b8
--- /dev/null
+++ b/specification/proposals/templates/examples/nested_lists.yaml
@@ -0,0 +1,103 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+name: NestedTeamRoster
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+description: Team directory roster with styled header banner and nested team lists.
+parameters:
+ directoryTitle:
+ type: string
+ description: Title text for the team directory.
+ teams:
+ type: array
+ description: List of team objects or TeamCard children.
+ default: []
+
+layout:
+ component: Column
+ children:
+ - component: Text
+ text: "{{ directoryTitle }}"
+ variant: h1
+ - component: Divider
+ axis: horizontal
+ - component: Column
+ children:
+ loop:
+ param: teams
+ template: NestedTeamCard
+
+sampleData:
+ directoryTitle: Global Engineering Directory
+ teams:
+ - teamName: Core Architecture
+ members:
+ - userId: u1
+ userName: Dr. Elena Vance
+ role: Principal Architect
+ - userId: u2
+ userName: Marcus Vance
+ role: Streaming Lead
+
+---
+version: "0.1"
+name: NestedTeamCard
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+description: Team container card displaying member cards.
+parameters:
+ teamName:
+ type: string
+ description: Name of the engineering team.
+ members:
+ type: array
+ description: List of team members.
+ default: []
+
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Text
+ text: "{{ teamName }}"
+ variant: h2
+ - component: Divider
+ axis: horizontal
+ - component: Column
+ children:
+ loop:
+ param: members
+ as: member
+ item:
+ component: Row
+ justify: spaceBetween
+ children:
+ - component: Text
+ text: "{{ member.userName }}"
+ - component: Text
+ text: "{{ member.role }}"
+ variant: caption
+
+sampleData:
+ teamName: Core Architecture
+ members:
+ - userId: u1
+ userName: Dr. Elena Vance
+ role: Principal Architect
+ - userId: u2
+ userName: Marcus Vance
+ role: Streaming Lead
diff --git a/specification/proposals/templates/examples/salary_card.yaml b/specification/proposals/templates/examples/salary_card.yaml
new file mode 100644
index 0000000000..167dc967b4
--- /dev/null
+++ b/specification/proposals/templates/examples/salary_card.yaml
@@ -0,0 +1,132 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+name: SalaryCard
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+description: Layout card for employee compensation package with security verification badge.
+
+parameters:
+ employeeName:
+ type: string
+ title: Employee Full Name
+ description: Full name of the verified employee.
+ role:
+ type: string
+ title: Job Title
+ description: Official company role.
+ baseSalary:
+ type: string
+ title: Base Salary
+ description: Annual base compensation.
+ annualBonus:
+ type: string
+ title: Annual Bonus
+ description: Target annual incentive bonus.
+ equity:
+ type: string
+ title: Equity Grants
+ description: Stock units or RSU package.
+ clearanceLevel:
+ type: string
+ title: Security Clearance
+ description: Confidentiality level.
+ default: "Level 4 - Confidential"
+ verifiedAt:
+ type: string
+ title: Verification Date
+ description: Timestamp of record retrieval.
+ default: "2026-08-13"
+
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Row
+ justify: spaceBetween
+ align: center
+ children:
+ - component: Row
+ align: center
+ children:
+ - component: Icon
+ name: lock
+ - component: Text
+ text: "Verified Compensation"
+ variant: caption
+ - component: Text
+ text: "{{ clearanceLevel }}"
+ variant: caption
+ - component: Column
+ children:
+ - component: Text
+ text: "{{ employeeName }}"
+ variant: h3
+ id: name_txt
+ - component: Text
+ text: "{{ role }}"
+ variant: body
+ - component: Divider
+ axis: horizontal
+ - component: Row
+ justify: spaceBetween
+ children:
+ - component: Column
+ children:
+ - component: Text
+ text: "Base Salary"
+ variant: caption
+ - component: Text
+ text: "{{ baseSalary }}"
+ variant: h4
+ id: sal_val
+ - component: Column
+ children:
+ - component: Text
+ text: "Annual Bonus"
+ variant: caption
+ - component: Text
+ text: "{{ annualBonus }}"
+ variant: h4
+ - component: Column
+ children:
+ - component: Text
+ text: "Equity Grants"
+ variant: caption
+ - component: Text
+ text: "{{ equity }}"
+ variant: h4
+ - component: Divider
+ axis: horizontal
+ - component: Row
+ justify: spaceBetween
+ align: center
+ children:
+ - component: Text
+ text: "🔒 Fetched live from secure HR database"
+ variant: caption
+ - component: Text
+ text: "Verified: {{ verifiedAt }}"
+ variant: caption
+
+sampleData:
+ employeeName: Dr. Elena Vance
+ role: Principal Systems Architect
+ baseSalary: "$215,000"
+ annualBonus: "$45,000"
+ equity: "3,500 RSUs"
+ clearanceLevel: "Level 5 - Confidential"
+ verifiedAt: "2026-08-13"
diff --git a/specification/proposals/templates/examples/section_card.yaml b/specification/proposals/templates/examples/section_card.yaml
new file mode 100644
index 0000000000..b64d9aad4f
--- /dev/null
+++ b/specification/proposals/templates/examples/section_card.yaml
@@ -0,0 +1,68 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+name: SectionCard
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+description: Standard container card with title, description, optional action, and child components.
+
+parameters:
+ title:
+ type: string
+ title: Section Title
+ description: Heading text displayed at the top of the section card.
+ description:
+ type: string
+ title: Section Description
+ description: Subordinate descriptive text beneath the title.
+ default: ""
+ headerAction:
+ type: child
+ title: Header Action Component
+ description: Single child component placed in the right side of the header.
+ children:
+ type: children
+ title: Section Children
+ description: Child component IDs rendered in the section body.
+ default: []
+
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Row
+ justify: spaceBetween
+ align: center
+ children:
+ - component: Text
+ text: "{{ title }}"
+ variant: h3
+ - component: Column
+ id: action_slot
+ children: "{{ headerAction }}"
+ - component: Text
+ text: "{{ description }}"
+ variant: caption
+ - component: Divider
+ axis: horizontal
+ - component: Column
+ id: body_container
+ children: "{{ children }}"
+
+sampleData:
+ title: Protocol Overview
+ description: High-level summary of the streaming architecture.
+ children: []
diff --git a/specification/proposals/templates/examples/slot_composition.yaml b/specification/proposals/templates/examples/slot_composition.yaml
new file mode 100644
index 0000000000..51cba60a03
--- /dev/null
+++ b/specification/proposals/templates/examples/slot_composition.yaml
@@ -0,0 +1,97 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+name: CompositeSectionCard
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+description: Collapsible or styled content section card with title, custom header action slot, and children slot.
+parameters:
+ title:
+ type: string
+ description: Section header title.
+ headerAction:
+ type: child
+ description: Single child component placed in the right side of the header.
+ children:
+ type: children
+ description: Content components contained within the section body.
+ default: []
+
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Row
+ justify: spaceBetween
+ align: center
+ children:
+ - component: Text
+ text: "{{ title }}"
+ variant: h2
+ - component: Column
+ children: "{{ headerAction }}"
+ - component: Divider
+ axis: horizontal
+ - component: Column
+ children: "{{ children }}"
+
+sampleData:
+ title: Project Milestones
+ headerAction:
+ component: Button
+ text: Refresh
+ children: []
+
+---
+version: "0.1"
+name: TwoColumnLayoutWithHeader
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+description: Responsive two-column dashboard grid with a hero header, left column, and right column.
+parameters:
+ headerChild:
+ type: child
+ description: Component rendered in the full-width header slot.
+ leftChildren:
+ type: children
+ description: Components rendered in the left column.
+ rightChildren:
+ type: children
+ description: Components rendered in the right column.
+
+layout:
+ component: Column
+ children:
+ - component: Column
+ children: "{{ headerChild }}"
+ - component: Divider
+ axis: horizontal
+ - component: Row
+ justify: spaceBetween
+ align: start
+ children:
+ - component: Column
+ children: "{{ leftChildren }}"
+ - component: Column
+ children: "{{ rightChildren }}"
+
+sampleData:
+ headerChild:
+ component: Text
+ text: Executive Operations Dashboard
+ variant: h1
+ leftChildren: []
+ rightChildren: []
diff --git a/specification/proposals/templates/examples/team_card.yaml b/specification/proposals/templates/examples/team_card.yaml
new file mode 100644
index 0000000000..d1ec4d163b
--- /dev/null
+++ b/specification/proposals/templates/examples/team_card.yaml
@@ -0,0 +1,84 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+name: TeamCard
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+description: Card showing team header and unrolled member cards.
+
+parameters:
+ teamName:
+ type: string
+ title: Team Name
+ description: The display name of the team.
+ members:
+ type: array
+ title: Team Members List
+ description: Array of team member objects.
+ items:
+ type: object
+ title: Team Member
+ properties:
+ userId:
+ type: string
+ title: User ID
+ description: Unique identifier of the user.
+ userName:
+ type: string
+ title: User Name
+ description: Full name of the user.
+ role:
+ type: string
+ title: Role Name
+ description: Role or title of the user.
+ default: Member
+ required:
+ - userId
+ - userName
+
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Row
+ justify: spaceBetween
+ align: center
+ children:
+ - component: Text
+ text: "{{ teamName }}"
+ variant: h3
+ - component: Icon
+ name: person
+ - component: Divider
+ axis: horizontal
+ - component: Column
+ children:
+ loop:
+ param: members
+ template: UserProfile
+
+sampleData:
+ teamName: Antigravity Devs
+ members:
+ - userId: usr_101
+ userName: Alice Smith
+ role: Lead Architect
+ - userId: usr_102
+ userName: Bob Jones
+ role: Senior Engineer
+ - userId: usr_103
+ userName: Charlie Brown
+ role: Product Manager
diff --git a/specification/proposals/templates/examples/team_feedback_board.yaml b/specification/proposals/templates/examples/team_feedback_board.yaml
new file mode 100644
index 0000000000..544f0dfcaa
--- /dev/null
+++ b/specification/proposals/templates/examples/team_feedback_board.yaml
@@ -0,0 +1,80 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+name: TeamFeedbackBoard
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+description: Feedback board showing team header and feedback items.
+
+parameters:
+ teamName:
+ type: string
+ title: Team Name
+ description: The display name of the team whose feedback board is being rendered.
+ feedbacks:
+ type: array
+ title: Feedbacks List
+ description: Array of feedback objects with author, note, and rating.
+ items:
+ type: object
+ title: Feedback Review
+ properties:
+ author:
+ type: string
+ title: Author Name
+ description: Full name of the person giving feedback.
+ note:
+ type: string
+ title: Feedback Note
+ description: Textual comment or recommendation.
+ rating:
+ type: number
+ title: Rating Score
+ minimum: 1
+ maximum: 5
+ default: 5
+ required:
+ - author
+ - note
+
+layout:
+ component: Column
+ children:
+ - component: Card
+ child:
+ component: Row
+ align: center
+ children:
+ - component: Icon
+ name: mail
+ - component: Text
+ text: "Feedback & Retrospective: {{ teamName }}"
+ variant: h2
+ - component: Column
+ id: feedbacks_container
+ children:
+ loop:
+ param: feedbacks
+ template: FeedbackItem
+
+sampleData:
+ teamName: Streaming & Protocols Guild
+ feedbacks:
+ - author: Dr. Elena Vance
+ note: Splitting createSurface and updateComponents cleanly unblocked sequential stream processing.
+ rating: 5
+ - author: Marcus Vance
+ note: Unrolling nested lists statically in Python enables instant frontend mounting with zero runtime recursion.
+ rating: 5
diff --git a/specification/proposals/templates/examples/team_goal_list.yaml b/specification/proposals/templates/examples/team_goal_list.yaml
new file mode 100644
index 0000000000..db6241144a
--- /dev/null
+++ b/specification/proposals/templates/examples/team_goal_list.yaml
@@ -0,0 +1,81 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+name: TeamGoalList
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+description: List of team goals with header banner.
+
+parameters:
+ teamName:
+ type: string
+ title: Team Name
+ description: The display name of the team whose goals are being listed.
+ goals:
+ type: array
+ title: Goals List
+ description: Array of goal objects with title, priority, and targetDate.
+ items:
+ type: object
+ title: Goal Definition
+ properties:
+ title:
+ type: string
+ title: Goal Title
+ description: Summary title of the objective
+ priority:
+ type: enum
+ title: Priority Level
+ values:
+ - High
+ - Medium
+ - Low
+ default: Medium
+ targetDate:
+ type: string
+ title: Target Date
+ description: Target completion date (YYYY-MM-DD)
+ required:
+ - title
+
+layout:
+ component: Column
+ children:
+ - component: Card
+ child:
+ component: Row
+ align: center
+ children:
+ - component: Icon
+ name: star
+ - component: Text
+ text: "Strategic Objectives: {{ teamName }}"
+ variant: h2
+ - component: Column
+ id: goals_container
+ children:
+ loop:
+ param: goals
+ template: GoalItem
+
+sampleData:
+ teamName: A2UI Core Team
+ goals:
+ - title: Implement bidirectional child/children container resolution
+ priority: High
+ targetDate: "2026-07-15"
+ - title: Upgrade all templates to standard Basic Catalog components
+ priority: High
+ targetDate: "2026-07-10"
diff --git a/specification/proposals/templates/examples/team_member_knowledge_panel.yaml b/specification/proposals/templates/examples/team_member_knowledge_panel.yaml
new file mode 100644
index 0000000000..fad8d61bdf
--- /dev/null
+++ b/specification/proposals/templates/examples/team_member_knowledge_panel.yaml
@@ -0,0 +1,94 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+name: TeamMemberKnowledgePanel
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+description: Card showing competency panel with user experience years and completed task count.
+
+parameters:
+ userName:
+ type: string
+ title: User Display Name
+ description: The full name of the team member.
+ role:
+ type: string
+ title: Role Name
+ description: The operational role of the team member.
+ experienceYears:
+ type: integer
+ title: Years of Experience
+ description: The number of years of professional experience.
+ minimum: 0
+ completedTasks:
+ type: integer
+ title: Completed Tasks Count
+ description: The count of completed tasks or tickets.
+ minimum: 0
+
+layout:
+ component: Card
+ child:
+ component: Column
+ children:
+ - component: Row
+ align: center
+ children:
+ - component: Icon
+ name: check
+ - component: Text
+ text: "Competency: {{ userName }}"
+ variant: h4
+ - component: Divider
+ axis: horizontal
+ - component: Row
+ justify: spaceBetween
+ children:
+ - component: Column
+ align: center
+ children:
+ - component: Text
+ text: Role
+ variant: caption
+ - component: Text
+ text: "{{ role }}"
+ variant: body
+ - component: Column
+ align: center
+ children:
+ - component: Text
+ text: Experience
+ variant: caption
+ - component: Text
+ text: "{{ experienceYears }} Yrs"
+ variant: body
+ - component: Column
+ align: center
+ children:
+ - component: Text
+ text: Tasks
+ variant: caption
+ - component: Text
+ text: "{{ completedTasks }} Done"
+ variant: body
+ - component: Text
+ text: Verified Core Contributor
+ variant: caption
+
+sampleData:
+ userName: Alice Smith
+ role: Systems Architect
+ experienceYears: 9
+ completedTasks: 142
diff --git a/specification/proposals/templates/examples/team_roster.yaml b/specification/proposals/templates/examples/team_roster.yaml
new file mode 100644
index 0000000000..b0261c85f4
--- /dev/null
+++ b/specification/proposals/templates/examples/team_roster.yaml
@@ -0,0 +1,45 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+name: TeamRoster
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+description: Team directory roster with styled header banner and nested team lists.
+
+parameters:
+ directoryTitle:
+ type: string
+ title: Directory Title
+ description: Title text for the team directory.
+ children:
+ type: children
+ title: Team Cards List
+ description: List of child TeamCard components.
+ default: []
+
+layout:
+ component: Column
+ children:
+ - component: Text
+ text: "{{ directoryTitle }}"
+ variant: h1
+ - component: Divider
+ axis: horizontal
+ - component: Column
+ children: "{{ children }}"
+
+sampleData:
+ directoryTitle: Global Engineering Directory
+ children: []
diff --git a/specification/proposals/templates/examples/two_column_layout.yaml b/specification/proposals/templates/examples/two_column_layout.yaml
new file mode 100644
index 0000000000..41c4ee2585
--- /dev/null
+++ b/specification/proposals/templates/examples/two_column_layout.yaml
@@ -0,0 +1,56 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+name: TwoColumnLayout
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+description: Responsive two-column dashboard layout with banner header and split content regions.
+
+parameters:
+ headerChild:
+ type: child
+ title: Header Component Slot
+ description: Single child component ID mounted at the top banner.
+ leftChildren:
+ type: children
+ title: Left Column Children
+ description: Child components placed in the left primary region.
+ default: []
+ rightChildren:
+ type: children
+ title: Right Column Children
+ description: Child components placed in the right secondary region.
+ default: []
+
+layout:
+ component: Column
+ children:
+ - component: Column
+ children: "{{ headerChild }}"
+ - component: Divider
+ axis: horizontal
+ - component: Row
+ children:
+ - component: Column
+ children: "{{ leftChildren }}"
+ - component: Column
+ children: "{{ rightChildren }}"
+
+sampleData:
+ headerChild:
+ component: Text
+ text: Header Title
+ leftChildren: []
+ rightChildren: []
diff --git a/specification/proposals/templates/examples/user_profile.yaml b/specification/proposals/templates/examples/user_profile.yaml
new file mode 100644
index 0000000000..f73bb276dd
--- /dev/null
+++ b/specification/proposals/templates/examples/user_profile.yaml
@@ -0,0 +1,54 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+version: "0.1"
+name: UserProfile
+catalogs:
+ - "https://a2ui.org/specification/v0_9_1/catalogs/basic/catalog.json"
+description: User profile card displaying avatar, full name, and role.
+
+parameters:
+ userId:
+ type: string
+ title: User ID
+ description: Unique user account ID.
+ userName:
+ type: string
+ title: User Name
+ description: Full name of the user.
+ role:
+ type: string
+ title: Role
+ description: Job title or role.
+ default: Member
+
+layout:
+ component: Card
+ child:
+ component: Column
+ align: center
+ children:
+ - component: Icon
+ name: person
+ - component: Text
+ text: "{{ userName }}"
+ variant: h3
+ - component: Text
+ text: "{{ role }}"
+ variant: caption
+
+sampleData:
+ userId: usr_101
+ userName: Alice Smith
+ role: Lead Architect
diff --git a/specification/proposals/templates/schema/template_definition.json b/specification/proposals/templates/schema/template_definition.json
new file mode 100644
index 0000000000..0feb3f5886
--- /dev/null
+++ b/specification/proposals/templates/schema/template_definition.json
@@ -0,0 +1,312 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "title": "A2UI Template Definition",
+ "description": "Schema defining a parameterized A2UI declarative template authored in YAML with a nested layout tree and synthetic ID generation.",
+ "type": "object",
+ "required": ["version", "parameters", "catalogs"],
+ "properties": {
+ "version": {
+ "type": "string",
+ "const": "0.1",
+ "description": "Specification version of the template definition format. Forced to '0.1'."
+ },
+ "id": {
+ "type": "string",
+ "description": "Optional globally unique identifier or URI for the template."
+ },
+ "name": {
+ "type": "string",
+ "pattern": "^[A-Za-z][A-Za-z0-9_]*$",
+ "description": "Component tag name of the template used in layout trees and LLM prompts."
+ },
+ "templateId": {
+ "type": "string",
+ "pattern": "^[A-Za-z][A-Za-z0-9_]*$",
+ "description": "Deprecated alias for 'name'."
+ },
+ "catalogs": {
+ "description": "Catalog identifier (URI) or list of catalog identifiers against which components are resolved.",
+ "anyOf": [
+ {
+ "type": "array",
+ "items": {"type": "string"},
+ "minItems": 1
+ },
+ {"type": "string"}
+ ]
+ },
+ "imports": {
+ "description": "Optional list or mapping of dependent templates imported by global ID.",
+ "anyOf": [
+ {
+ "type": "array",
+ "items": {"type": "string"}
+ },
+ {
+ "type": "object",
+ "additionalProperties": {"type": "string"}
+ }
+ ]
+ },
+ "description": {
+ "type": "string",
+ "description": "Human-readable description of what this template represents."
+ },
+ "parameters": {
+ "type": "object",
+ "description": "Mapping of parameter names to their explicit A2UI type definitions.",
+ "additionalProperties": {
+ "$ref": "#/$defs/ParameterDefinition"
+ }
+ },
+ "requiredParameters": {
+ "type": "array",
+ "items": {"type": "string"},
+ "description": "Optional list of parameter names that are required when invoking the template."
+ },
+ "layout": {
+ "$ref": "#/$defs/NestedTemplateNode",
+ "description": "Root component of the nested layout tree."
+ },
+ "components": {
+ "type": "array",
+ "description": "Optional flattened component list for internal graph representation.",
+ "items": {
+ "$ref": "#/$defs/TemplateComponent"
+ }
+ },
+ "sampleData": {
+ "type": "object",
+ "description": "Sample parameter values used for previewing and testing template inflation."
+ }
+ },
+ "allOf": [
+ {
+ "anyOf": [{"required": ["name"]}, {"required": ["templateId"]}]
+ },
+ {
+ "anyOf": [{"required": ["layout"]}, {"required": ["components"]}]
+ }
+ ],
+ "additionalProperties": false,
+ "$defs": {
+ "ParameterDefinition": {
+ "type": "object",
+ "required": ["type"],
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "string",
+ "number",
+ "integer",
+ "boolean",
+ "enum",
+ "object",
+ "array",
+ "child",
+ "children",
+ "action"
+ ],
+ "description": "A2UI semantic parameter type."
+ },
+ "title": {
+ "type": "string",
+ "description": "Short human-readable title of the parameter."
+ },
+ "description": {
+ "type": "string",
+ "description": "Detailed explanation of the parameter's purpose and usage."
+ },
+ "default": {
+ "description": "Default fallback value if not specified."
+ },
+ "values": {
+ "type": "array",
+ "items": {"type": "string"},
+ "description": "Allowed string values when type is 'enum'."
+ },
+ "items": {
+ "description": "Item type definition when type is 'array'. Can be an A2UI type name or nested ParameterDefinition."
+ },
+ "properties": {
+ "type": "object",
+ "description": "Property definitions when type is 'object'.",
+ "additionalProperties": {
+ "$ref": "#/$defs/ParameterDefinition"
+ }
+ },
+ "required": {
+ "anyOf": [
+ {
+ "type": "boolean",
+ "description": "Whether this parameter is required when instantiating the template."
+ },
+ {
+ "type": "array",
+ "items": {"type": "string"},
+ "description": "List of required property names for object types."
+ }
+ ]
+ },
+ "minimum": {
+ "type": "number",
+ "description": "Minimum value constraint for numeric parameters."
+ },
+ "maximum": {
+ "type": "number",
+ "description": "Maximum value constraint for numeric parameters."
+ }
+ },
+ "additionalProperties": false
+ },
+ "ParamReference": {
+ "type": "object",
+ "required": ["param"],
+ "properties": {
+ "param": {
+ "type": "string",
+ "description": "Name or dot-separated path of the template parameter to substitute."
+ },
+ "template": {
+ "type": "string",
+ "description": "Child template identifier when mapping an array parameter to child component instances."
+ },
+ "default": {
+ "description": "Fallback value if the parameter path resolves to None."
+ }
+ },
+ "additionalProperties": false
+ },
+ "ConcatExpression": {
+ "type": "object",
+ "required": ["concat"],
+ "properties": {
+ "concat": {
+ "type": "array",
+ "description": "List of literal values and parameter references to concatenate into a string.",
+ "items": {
+ "anyOf": [{"type": "string"}, {"type": "number"}, {"$ref": "#/$defs/ParamReference"}]
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "FormatExpression": {
+ "type": "object",
+ "required": ["format"],
+ "properties": {
+ "format": {
+ "type": "string",
+ "description": "Format string containing {key} placeholders."
+ },
+ "args": {
+ "type": "object",
+ "description": "Mapping of placeholder keys to values or parameter references.",
+ "additionalProperties": {
+ "anyOf": [{"type": "string"}, {"type": "number"}, {"$ref": "#/$defs/ParamReference"}]
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "LoopDefinition": {
+ "type": "object",
+ "required": ["param"],
+ "anyOf": [{"required": ["template"]}, {"required": ["item"]}],
+ "properties": {
+ "param": {
+ "type": "string",
+ "description": "Parameter name holding the list/array data to iterate over."
+ },
+ "template": {
+ "type": "string",
+ "description": "Identifier of a named template to instantiate for each item."
+ },
+ "item": {
+ "$ref": "#/$defs/NestedTemplateNode",
+ "description": "Self-contained inline component layout to instantiate for each item."
+ },
+ "as": {
+ "type": "string",
+ "description": "Optional variable scope alias for accessing item fields in expressions."
+ }
+ },
+ "additionalProperties": false
+ },
+ "TemplateValue": {
+ "description": "A literal value, parameter substitution, or expression in a template component property.",
+ "anyOf": [
+ {"type": "string"},
+ {"type": "number"},
+ {"type": "boolean"},
+ {"type": "null"},
+ {"$ref": "#/$defs/ParamReference"},
+ {"$ref": "#/$defs/ConcatExpression"},
+ {"$ref": "#/$defs/FormatExpression"},
+ {"type": "array"},
+ {"type": "object"}
+ ]
+ },
+ "NestedTemplateNode": {
+ "type": "object",
+ "required": ["component"],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Optional explicit component ID within the template."
+ },
+ "component": {
+ "type": "string",
+ "description": "Catalog component tag name."
+ },
+ "catalogId": {
+ "type": "string",
+ "description": "Optional catalog ID to disambiguate if the component name exists in multiple declared catalogs."
+ },
+ "child": {
+ "anyOf": [{"$ref": "#/$defs/NestedTemplateNode"}, {"$ref": "#/$defs/TemplateValue"}]
+ },
+ "children": {
+ "anyOf": [
+ {
+ "type": "object",
+ "required": ["loop"],
+ "properties": {
+ "loop": {"$ref": "#/$defs/LoopDefinition"}
+ },
+ "additionalProperties": false
+ },
+ {"type": "array"},
+ {"$ref": "#/$defs/ParamReference"},
+ {"type": "string"}
+ ]
+ }
+ },
+ "additionalProperties": {
+ "$ref": "#/$defs/TemplateValue"
+ }
+ },
+ "TemplateComponent": {
+ "type": "object",
+ "required": ["id", "component"],
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Unique component ID within the template."
+ },
+ "component": {
+ "type": "string",
+ "description": "Catalog component tag name."
+ },
+ "catalogId": {
+ "type": "string",
+ "description": "Optional catalog ID to disambiguate if the component name exists in multiple declared catalogs."
+ }
+ },
+ "additionalProperties": {
+ "$ref": "#/$defs/TemplateValue"
+ }
+ }
+ }
+}
diff --git a/uv.lock b/uv.lock
index eda28872f6..2e95d522fd 100644
--- a/uv.lock
+++ b/uv.lock
@@ -68,6 +68,8 @@ dependencies = [
{ name = "google-genai" },
{ name = "httpx" },
{ name = "jsonschema" },
+ { name = "nest-asyncio" },
+ { name = "pyyaml" },
]
[package.dev-dependencies]
@@ -75,6 +77,7 @@ dev = [
{ name = "antlr4-tools" },
{ name = "hatchling" },
{ name = "types-jsonschema" },
+ { name = "types-pyyaml" },
]
[package.metadata]
@@ -86,6 +89,8 @@ requires-dist = [
{ name = "google-genai", specifier = ">=1.27.0" },
{ name = "httpx", specifier = ">=0.27.0" },
{ name = "jsonschema", specifier = ">=4.0.0" },
+ { name = "nest-asyncio", specifier = ">=1.6.0" },
+ { name = "pyyaml", specifier = ">=6.0" },
]
[package.metadata.requires-dev]
@@ -93,6 +98,7 @@ dev = [
{ name = "antlr4-tools", specifier = ">=0.2.1" },
{ name = "hatchling", specifier = ">=1.30.1" },
{ name = "types-jsonschema" },
+ { name = "types-pyyaml" },
]
[[package]]
@@ -3048,6 +3054,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" },
]
+[[package]]
+name = "nest-asyncio"
+version = "1.6.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418, upload-time = "2024-01-21T14:25:19.227Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195, upload-time = "2024-01-21T14:25:17.223Z" },
+]
+
[[package]]
name = "nest-asyncio2"
version = "1.7.2"