From 747c5a787971bb933ab9c3980bd4f82f98729c24 Mon Sep 17 00:00:00 2001 From: colombod Date: Tue, 23 Jun 2026 06:41:27 +0000 Subject: [PATCH 1/5] fix: resolve query-tool endpoint from destinations (explicit-first fallback) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The query tools (tool-graph-query, tool-blob-read) read only the top-level context_intelligence_server_url/api_key scalars and never inspected the hook's destinations: block. A user configuring ONLY destinations: got working uploads but a dead query tool failing with "context-intelligence server URL not configured". Adapt the resolver split from PR #27 (HookConfigResolver / ToolConfigResolver) and add a per-field, explicit-first query-endpoint fallback in a shared helper context_intelligence/tool_resolver.py::resolve_query_endpoint: 1. first entry of the tool's own sources mapping (explicit read override; absent => synthesized {"default": ...} from the tool's explicit top-level scalars, config+coordinator only) 2. first hook destination (HookConfigResolver.destinations) โ€” the bug-fix bridge 3. env AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL / _API_KEY (single canonical last-resort fallback; no *_PRIVATE_* names) else None. Each field (url, api_key) resolves independently; env never outranks the hook destination. Renamed ConfigResolver -> HookConfigResolver and the registered capability context_intelligence.config_resolver -> context_intelligence.hook_config_resolver (a ConfigResolver class alias is kept). Applied identically to graph-query and blob-read. Minimal port of PR #27's slice only (no skill-sync/fetcher machinery). Also add PYTHONPATH=${{ github.workspace }} to the module "Run tests" CI step so unit tests resolve the in-repo context_intelligence (incl. the new tool_resolver.py) by shadowing the @main-installed copy โ€” the convention introduced in PR #27. Docs: consolidated the repeated README destinations sections into one authoritative block + a thin Quick-Start teaser, added a "Query tools โ€” read-side endpoint" section documenting sources and the explicit-first/env model, fixed stale ConfigResolver/capability references, rewrote context/config-resolution.dot for the two-resolver model, and regenerated bundle.dot/bundle.png. Tests: full matrix (graph-query 44, blob-read 39, tool_resolver 19, hook 367) โ€” read-config hit wins over destination; destinations-only falls through to the hook destination (core bug fix); per-field independence; explicit-first precedence; env as true fallback; all-miss -> None; multi-entry ordering determinism; blob-read parity; legacy scalar synthesis. Proven end-to-end in a Digital Twin with a real destinations-only config (single private-home-server destination, working_dir unavailable): the query resolves from the hook destination and succeeds. ๐Ÿค– Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> --- .github/workflows/ci.yml | 12 +- README.md | 166 ++++---- bundle.dot | 33 +- bundle.png | Bin 113846 -> 174175 bytes context/config-resolution.dot | 93 ++++- context_intelligence/config.py | 49 +++ context_intelligence/tool_resolver.py | 267 +++++++++++++ .../__init__.py | 10 +- .../config_resolver.py | 8 +- .../tests/test_config_resolver.py | 6 +- .../tests/test_mount_dispatcher.py | 16 +- modules/hook-context-intelligence/uv.lock | 18 +- .../__init__.py | 2 +- .../blob_read_tool.py | 40 +- .../tests/test_blob_read_tool.py | 175 ++++++++- modules/tool-blob-read/uv.lock | 31 +- .../__init__.py | 2 +- .../graph_query_tool.py | 57 +-- .../tests/test_graph_query_tool.py | 362 +++++++++++++++++- modules/tool-graph-query/uv.lock | 31 +- tests/test_tool_resolver.py | 272 +++++++++++++ 21 files changed, 1427 insertions(+), 223 deletions(-) create mode 100644 context_intelligence/tool_resolver.py create mode 100644 tests/test_tool_resolver.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2420a3e..cf192db 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -90,10 +90,18 @@ jobs: - name: Install dependencies working-directory: modules/${{ matrix.module }} # --frozen: respect the module's own lockfile exactly as committed. - # The module's path dependency on `../..` is resolved from the - # checked-out root, so no special setup is needed. + # The module declares the shared bundle as a @main git ref (NOT a path + # source), so uv installs the *published* context_intelligence. The Run + # tests step shadows it with the in-repo source (below). run: uv sync --frozen - name: Run tests working-directory: modules/${{ matrix.module }} + # Test the module against the IN-REPO shared library, which may carry + # not-yet-published changes (e.g. context_intelligence/tool_resolver.py) + # that @main only gains when this PR merges. Put the checked-out root on + # PYTHONPATH to shadow the @main-installed copy โ€” the same convention + # AGENTS.md prescribes for local runs. + env: + PYTHONPATH: ${{ github.workspace }} run: uv run pytest tests/ -q --tb=short --ignore=tests/dtu diff --git a/README.md b/README.md index 5c46fc7..1c62621 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ overrides: include: ["**"] # every session (the default) ``` -That single-destination block is the common case. To route different projects to different servers โ€” or to exclude some entirely โ€” add more named destinations; see [Multi-server fan-out](#multi-server-fan-out-destinations). For the full routing model and pattern rules, see the [Configuration reference](#configuration-reference). +That single-destination block is the common case. To route different projects to different servers โ€” or to exclude some entirely โ€” add more named destinations; for the full routing model and pattern rules, see [Server forwarding โ€” `destinations`](#server-forwarding--destinations) in the Configuration reference. > **Never write a literal API key into `settings.yaml`.** That file is version-controllable configuration; a secret written there is one accidental commit away from exposure. Always reference it via `${VAR}` from `keys.env`. @@ -134,78 +134,7 @@ When this bundle is loaded through the [Amplifier app-cli](https://github.com/mi `~/.amplifier/settings.yaml` is the app-cli's knob for bundle configuration. It is safe to commit to version control **as long as secrets are referenced via `${VAR_NAME}` interpolation**, never as literal values. The actual secrets stay exclusively in `~/.amplifier/keys.env`. The `${...}` placeholder is resolved by the app-cli **before** the value reaches the hook โ€” the hook reads only its mount config dict and never the environment directly, so the variable name in `keys.env` is entirely your choice (it never has to match any `AMPLIFIER_*` convention). -### Configuring servers with `destinations` (current shape) - -`destinations` is a named map of servers under `overrides.hook-context-intelligence.config`. Each entry has a `url`, an `api_key`, and optional `.gitignore`-style `include`/`exclude` patterns that decide which sessions route to it (by working directory). This is the canonical configuration shape: - -```bash -# ~/.amplifier/keys.env โ€” secrets only, never commit this file -PERSONAL_CI_KEY= -TEAM_CI_KEY= -``` - -```yaml -# ~/.amplifier/settings.yaml -overrides: - hook-context-intelligence: - config: - workspace: "my-project" # optional โ€” auto-resolved if omitted - destinations: - personal: - url: "http://localhost:8000" - api_key: "${PERSONAL_CI_KEY}" - include: ["**"] # all sessions... - exclude: ["**/client-*/"] # ...except any client-* project dir and below - team: - url: "https://ci.team.example" - api_key: "${TEAM_CI_KEY}" - include: ["**/work/"] # only sessions under a "work" directory -``` - -A session's events are sent to **every** destination it matches (true fan-out โ€” zero, one, or several), and **local JSONL is always written** regardless. The per-destination `api_key` becomes the `Authorization: Bearer ` header on that server's POSTs; because each destination references its own `${VAR}`, distinct keys never cross between servers. For the full routing model and pattern semantics see [Multi-server fan-out](#multi-server-fan-out-destinations) and the [Configuration reference](#configuration-reference). - -### Multi-server fan-out (`destinations`) - -The example above already shows two servers. This section documents the full routing model. - -`destinations` is a dict keyed by name, under the `overrides.hook-context-intelligence.config` block: - -```yaml -# ~/.amplifier/settings.yaml -overrides: - hook-context-intelligence: - config: - destinations: - personal: - url: "${PERSONAL_CI_URL}" - api_key: "${PERSONAL_CI_KEY}" # secret lives in keys.env, referenced here - include: ["**"] # all sessions... - exclude: ["**/client-*/"] # ...except any client-* project dir and everything under it - team: - url: "${TEAM_CI_URL}" - api_key: "${TEAM_CI_KEY}" - include: ["**/work/"] # only sessions under a "work" directory -``` - -**How routing is decided.** For each session the hook derives a match key from the session's working directory (the `session.working_dir` capability) and tests it against every destination. A destination is **active** for a session iff the working dir matches an `include` pattern **and** does not match an `exclude` pattern โ€” **exclude wins, per destination**. The session's events are sent to **every** active destination (true fan-out): a session can match zero, one, or several. **Local JSONL is always written**, regardless of how many destinations match. - -**Pattern semantics โ€” `.gitignore` rules.** `include` / `exclude` patterns use `.gitignore` (gitwildmatch) semantics, matched against the session's working **directory**: - -| Pattern | Matches | -|---------|---------| -| `foo/`, `foo`, `**/foo/`, `**/foo` | the directory `foo` **and everything beneath it** | -| `**` | every session | -| empty `include` list | nothing (the destination is inactive) | - -Prefer the trailing-slash directory form (e.g. `**/work/`) to mean "this project and all its sessions" โ€” it matches whether the session is launched from the project **root** or any subdirectory. (A pattern that targets only contents, like `**/work/**`, still also matches the directory itself here, because the match key is a directory.) - -**Defaults & validation.** Omitted `include` defaults to `["**"]` (match everything); omitted `exclude` defaults to none. After `${VAR}` expansion, a `destinations` entry whose `url` **or** `api_key` is empty is a **mount error** (fail-fast, naming the offending destination). With no `destinations` and no legacy url, the hook is local-JSONL-only. - -**Legacy single-server behavior differs on one point.** When only the legacy scalars are set (no `destinations`) and the `url` is present but the `api_key` is empty โ€” e.g. an unset `${AMPLIFIER_CONTEXT_INTELLIGENCE_API_KEY:}` โ€” the hook **degrades to local-only and logs a WARNING; it does not fail to mount**. (A `destinations` entry with an empty url/api_key is a hard error; the legacy scalar path is intentionally lenient for back-compat.) - -**Per-project override.** Because `destinations` is keyed by name, a project `.amplifier/settings.yaml` can override a single destination's `include`/`exclude` (e.g. `destinations.team.include`) without restating the others โ€” the app-cli deep-merges user โ†’ project settings. - -> **Secrets:** keep `api_key` values in `~/.amplifier/keys.env` and reference them via `${VAR}` in `settings.yaml`. Never write a literal key into `settings.yaml`. +The actual `destinations` configuration โ€” its sub-keys, routing rules, pattern semantics, defaults, validation, and per-project overrides โ€” lives in one place: [Server forwarding โ€” `destinations`](#server-forwarding--destinations) in the Configuration reference. --- @@ -278,10 +207,10 @@ cleanup = await mount(coordinator, config={ ### Accessing resolved values -`mount()` registers a `ConfigResolver` as the `context_intelligence.config_resolver` capability: +`mount()` registers a `HookConfigResolver` as the `context_intelligence.hook_config_resolver` capability: ```python -resolver = coordinator.get_capability("context_intelligence.config_resolver") +resolver = coordinator.get_capability("context_intelligence.hook_config_resolver") resolver.workspace # resolved workspace string resolver.base_path # resolved Path object resolver.session_dir("abc-123") # Path to a session's CI directory @@ -293,18 +222,52 @@ resolver.session_dir("abc-123") # Path to a session's CI directory The `config` dict passed to `mount()` uses the same keys as the `overrides.hook-context-intelligence.config` block in `settings.yaml`. The hook is a **pure mount-config consumer**: it reads only this config dict (plus coordinator capabilities) and does **not** read environment variables or `settings.yaml` itself. Environment variables reach the config only because the shipped behavior YAML (and any `settings.yaml` override) reference them through `${VAR}` / `${VAR:default}` placeholders, which the Amplifier app-cli expands before `mount()` is called. There is **no** automatic `AMPLIFIER_CONTEXT_INTELLIGENCE_` โ†’ config-key mapping โ€” an env var with no corresponding `${VAR}` placeholder in the active config never reaches the hook. The **Env var** column below names the variable each shipped placeholder reads. -#### Server forwarding โ€” `destinations` (current shape) +#### Server forwarding โ€” `destinations` -`destinations` is a dict keyed by destination name. Each value is a dict with these keys: +`destinations` is a dict keyed by destination name, under `overrides.hook-context-intelligence.config`. Each value is a dict with these keys: | Sub-key | Required | Default | Description | |---------|----------|---------|-------------| | `url` | yes | โ€” | Base URL of the CI server for this destination. | -| `api_key` | yes | โ€” | Bearer token for this destination. Sent as `Authorization: Bearer ` on that destination's POSTs only. | +| `api_key` | yes | โ€” | Bearer token for this destination. Sent as `Authorization: Bearer ` on that destination's POSTs only โ€” because each destination references its own `${VAR}`, distinct keys never cross between servers. | | `include` | no | `["**"]` | `.gitignore`-style patterns matched against the session's working directory. The destination is a candidate when any pattern matches. | | `exclude` | no | `[]` | `.gitignore`-style patterns; if any matches, the destination is dropped for that session (**exclude wins**). | -Routing: a session is sent to **every** destination where `include` matches **and** `exclude` does not. **Local JSONL is always written**, even when no destination matches. After `${VAR}` expansion, a destination with an empty `url` **or** `api_key` is a **mount error** (fail-fast, naming the offending destination). With no `destinations` configured, the hook is local-JSONL-only. See [Multi-server fan-out](#multi-server-fan-out-destinations) for the full pattern semantics. +```yaml +# ~/.amplifier/settings.yaml โ€” route different projects to different servers +overrides: + hook-context-intelligence: + config: + workspace: "my-project" # optional โ€” auto-resolved if omitted + destinations: + personal: + url: "http://localhost:8000" + api_key: "${PERSONAL_CI_KEY}" # secret lives in keys.env, referenced here + include: ["**"] # all sessions... + exclude: ["**/client-*/"] # ...except any client-* project dir and below + team: + url: "https://ci.team.example" + api_key: "${TEAM_CI_KEY}" + include: ["**/work/"] # only sessions under a "work" directory +``` + +**Routing.** For each session the hook derives a match key from the session's working directory (the `session.working_dir` capability) and tests it against every destination. A destination is **active** for a session iff the working dir matches an `include` pattern **and** does not match an `exclude` pattern โ€” **exclude wins, per destination**. The session's events are sent to **every** active destination (true fan-out): a session can match zero, one, or several. **Local JSONL is always written**, regardless of how many destinations match. + +**Pattern semantics โ€” `.gitignore` rules.** `include` / `exclude` patterns use `.gitignore` (gitwildmatch) semantics, matched against the session's working **directory**: + +| Pattern | Matches | +|---------|---------| +| `foo/`, `foo`, `**/foo/`, `**/foo` | the directory `foo` **and everything beneath it** | +| `**` | every session | +| empty `include` list | nothing (the destination is inactive) | + +Prefer the trailing-slash directory form (e.g. `**/work/`) to mean "this project and all its sessions" โ€” it matches whether the session is launched from the project **root** or any subdirectory. (A pattern that targets only contents, like `**/work/**`, still also matches the directory itself here, because the match key is a directory.) + +**Defaults & validation.** Omitted `include` defaults to `["**"]` (match everything); omitted `exclude` defaults to none. After `${VAR}` expansion, a `destinations` entry whose `url` **or** `api_key` is empty is a **mount error** (fail-fast, naming the offending destination). With no `destinations` configured, the hook is local-JSONL-only. (The legacy scalar path is intentionally more lenient โ€” see [Deprecated โ€” legacy single-server scalars](#deprecated--legacy-single-server-scalars) below.) + +**Per-project override.** Because `destinations` is keyed by name, a project `.amplifier/settings.yaml` can override a single destination's `include`/`exclude` (e.g. `destinations.team.include`) without restating the others โ€” the app-cli deep-merges user โ†’ project settings. + +> **Secrets:** keep `api_key` values in `~/.amplifier/keys.env` and reference them via `${VAR}` in `settings.yaml`. Never write a literal key into `settings.yaml`. #### Other config keys @@ -334,6 +297,49 @@ Legacy degradation (differs from `destinations`): if `context_intelligence_serve --- +#### Query tools (`graph-query`, `blob-read`) โ€” read-side endpoint + +The hook config above governs **where events are written** (the upload / fan-out side). The **query tools** `tool-graph-query` and `tool-blob-read` are the **read side** โ€” they call a Context Intelligence server to answer graph queries and fetch blobs. They resolve their `(server_url, api_key)` independently per field, **explicit-read-config first**, and the chain is designed so that **configuring `destinations` alone is enough** โ€” you do **not** have to repeat the endpoint for queries: + +| Order | Source | Notes | +|-------|--------|-------| +| **1** | First entry of `read_destinations` on the tool's own config (`overrides.tool-graph-query.config` / `overrides.tool-blob-read.config`) | The explicit read override. Wins when set. | +| **2** | First entry of the hook's `destinations` block | **The common case** โ€” queries follow the same server you upload to, with zero extra config. This is the bridge that makes a `destinations`-only setup "just work" for reads. | +| **3** | Env `AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL` / `AMPLIFIER_CONTEXT_INTELLIGENCE_API_KEY` | Single canonical last-resort fallback (reached via `${VAR}` placeholders in the shipped YAML, same convention as everywhere else). | +| โ€” | else | `configuration_error: "context-intelligence server URL not configured"`. | + +Each field walks the chain independently (a tier that supplies a `url` but no `api_key` lets `api_key` fall through). **Env is a true fallback โ€” it never outranks the hook destination** (tier 2). There are **no** `*_PRIVATE_*` environment variables; the only env names consulted are the canonical `AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL` / `_API_KEY`. + +**`read_destinations`** is a dict keyed by name, mirroring the hook's `destinations` shape. The **first** entry (declaration / insertion order) is used. Reach for it only when the read endpoint must differ from the upload destination (e.g. a read replica or a debugging override) โ€” it overrides the **read path only** and does not change where the hook uploads: + +```yaml +# ~/.amplifier/settings.yaml โ€” only needed when queries must hit a DIFFERENT server than uploads +overrides: + tool-graph-query: + config: + read_destinations: + default: + url: "http://read-replica.example.com" + api_key: "${CI_READ_KEY}" # secret lives in keys.env, referenced here + tool-blob-read: + config: + read_destinations: + default: + url: "http://read-replica.example.com" + api_key: "${CI_READ_KEY}" +``` + +| Sub-key | Required | Default | Description | +|---------|----------|---------|-------------| +| `url` | yes | โ€” | Base URL of the CI server the query tool reads from. | +| `api_key` | yes | โ€” | Bearer token for read requests to that server. | + +**Legacy back-compat (read side):** with no `read_destinations` key present, explicit top-level scalars on the tool config (`context_intelligence_server_url` + `context_intelligence_api_key`, **both** required) synthesize a single `default` read entry at tier 1 โ€” symmetric to the hook's legacy synthesis. With neither set, resolution falls through to the hook destination (tier 2) and then env (tier 3). + +> **Most users configure nothing here.** A single hook `destinations` entry already powers both upload and query. `read_destinations` exists only for the read-replica / split-endpoint case. + +--- + ## Server dispatch ### Dispatch isolation @@ -483,7 +489,7 @@ amplifier-bundle-context-intelligence/ โ”‚ โ”œโ”€โ”€ event-schema.md โ† all 51+ Amplifier events โ”‚ โ”œโ”€โ”€ graph-model-reference.md โ† Neo4j graph model for Cypher queries โ”‚ โ”œโ”€โ”€ safe-extraction-patterns.md โ† JSONL navigation patterns -โ”‚ โ”œโ”€โ”€ config-resolution.dot โ† ConfigResolver fallback chain diagram +โ”‚ โ”œโ”€โ”€ config-resolution.dot โ† HookConfigResolver fallback chain diagram โ”‚ โ”œโ”€โ”€ session-disk-layout.dot โ† on-disk session directory structure โ”‚ โ”œโ”€โ”€ delegation-strategy.dot โ† graph-analyst โ†’ session-navigator delegation logic โ”‚ โ”œโ”€โ”€ agents/ diff --git a/bundle.dot b/bundle.dot index c7d8b5b..4c741b0 100644 --- a/bundle.dot +++ b/bundle.dot @@ -1,51 +1,52 @@ +// This repository packages "Context Intelligence" โ€” a toolkit that automatically records and lets you explore what happened during AI work sessions. digraph context_intelligence { rankdir=LR fontname="Helvetica" fontsize=12 - label="context-intelligence v0.1.0 โ€” bundle repo" + label="Context Intelligence โ€” Session Recording & Exploration Toolkit\nv0.1.0 ยท a bundle of AI helpers, tools, and skills" labelloc=t labeljust=c nodesep=0.6 ranksep=0.7 bgcolor="white" - source_hash="dba7ae999a5fd095337bcd9ede4c54b866044c0b31d63d20c4b0ef4483abaf6c" + source_hash="7758e3d982ed1c85e71f0883ab4ac4596d336fd517ba1192e2580fbe98c220d2" node [fontname="Helvetica", fontsize=11, style="filled,rounded"] edge [fontname="Helvetica", fontsize=9] - root_context_intelligence [label="context-intelligence v0.1.0\n0 tools ยท 0 agents\n~98 tok aggregate", shape=box, fillcolor="#80cbc4", style="filled,rounded,bold", penwidth=2] + root_context_intelligence [label="Context Intelligence (Main Package)\nv0.1.0\n0 tools ยท 0 agents\n~98 tok aggregate", shape=box, fillcolor="#80cbc4", style="filled,rounded,bold", penwidth=2] subgraph cluster_behaviors { - label="Behaviors" + label="Behaviors (Reusable Skill Bundles)" style="filled" fillcolor="#f9f9f9" color="#999999" - beh_context_intelligence_behavior [label="context-intelligence-behavior\n4 tools\n~1832 tok", shape=box, fillcolor="#e0f2f1", style="filled,rounded"] + beh_context_intelligence_behavior [label="Core Skill Bundle\ncontext-intelligence-behavior\n4 tools\n~2549 tok", shape=box, fillcolor="#e0f2f1", style="filled,rounded"] } subgraph cluster_agents { - label="Agents" + label="Agents (Specialized AI Helpers)" style="filled" fillcolor="#f9f9f9" color="#999999" - agt_context_intelligence_design_facilitator [label="context-intelligence-design-facilitator\n~187 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] - agt_context_intelligence_tool_designer [label="context-intelligence-tool-designer\n~198 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] - agt_graph_analyst [label="graph-analyst\n~543 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] - agt_session_navigator [label="session-navigator\n~366 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] + agt_context_intelligence_design_facilitator [label="Guides Designing New Tools\ncontext-intelligence-design-facilitator\n~187 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] + agt_context_intelligence_tool_designer [label="Designs Tool Blueprints\ncontext-intelligence-tool-designer\n~198 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] + agt_graph_analyst [label="Analyzes Session Data\ngraph-analyst\n~543 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] + agt_session_navigator [label="Browses Past Sessions\nsession-navigator\n~366 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] } subgraph cluster_modules { - label="Modules" + label="Modules (Building-Block Tools)" style="filled" fillcolor="#f9f9f9" color="#999999" - mod_hook_context_intelligence [label="hook-context-intelligence", shape=box, fillcolor="#bbdefb", style="filled,rounded"] - mod_tool_blob_read [label="tool-blob-read", shape=box, fillcolor="#bbdefb", style="filled,rounded"] - mod_tool_context_intelligence_upload [label="tool-context-intelligence-upload", shape=box, fillcolor="#bbdefb", style="filled,rounded"] - mod_tool_graph_query [label="tool-graph-query", shape=box, fillcolor="#bbdefb", style="filled,rounded"] + mod_hook_context_intelligence [label="Records Activity Automatically\nhook-context-intelligence", shape=box, fillcolor="#bbdefb", style="filled,rounded"] + mod_tool_blob_read [label="Reads Stored Data\ntool-blob-read", shape=box, fillcolor="#bbdefb", style="filled,rounded"] + mod_tool_context_intelligence_upload [label="Uploads Session Data\ntool-context-intelligence-upload", shape=box, fillcolor="#bbdefb", style="filled,rounded"] + mod_tool_graph_query [label="Searches the Data Graph\ntool-graph-query", shape=box, fillcolor="#bbdefb", style="filled,rounded"] } subgraph cluster_legend { @@ -69,7 +70,7 @@ digraph context_intelligence { disclaimer [label="Token estimates: ~4 chars/token\nSolid border = local (counted)\nDashed + red = external, hidden cost (not counted)\nDashed + muted = external, no cost\nExcludes: sub-session costs, runtime-dynamic", shape=note, fillcolor="#eceff1", style="filled", fontsize=9] - ext_githttps___github_com_microsoft_amplifier_foundation_main [label="amplifier-foundation\n(external, cost)", shape=box, fillcolor="#80cbc4", style="dashed", color="red", penwidth=2] + ext_githttps___github_com_microsoft_amplifier_foundation_main [label="Shared Foundation (External)\namplifier-foundation\n(external, cost)", shape=box, fillcolor="#80cbc4", style="dashed", color="red", penwidth=2] root_context_intelligence -> ext_githttps___github_com_microsoft_amplifier_foundation_main [style=dashed] root_context_intelligence -> beh_context_intelligence_behavior [label="composes"] diff --git a/bundle.png b/bundle.png index b0b34e1a199186d8c4dae02d3b047107bd26bb68..fde63e932b8a3d8aa5c49a173abe545bca99e372 100644 GIT binary patch literal 174175 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 diff --git a/context/config-resolution.dot b/context/config-resolution.dot index 83c06f7..8cfbd48 100644 --- a/context/config-resolution.dot +++ b/context/config-resolution.dot @@ -20,7 +20,7 @@ digraph ConfigResolution { // --- Central nodes --- hook_resolver [label="HookConfigResolver\n(hook / write side)", shape=component, fillcolor="#d4e6f1", style="filled"]; - tool_resolver [label="ToolConfigResolver\n(graph_query / blob_read โ€” read side)", shape=component, fillcolor="#d1f2d4", style="filled"]; + tool_resolver [label="ToolConfigResolver\n(tool-context-intelligence-query\ngraph_query + blob_read โ€” read side)", shape=component, fillcolor="#d1f2d4", style="filled"]; // --- Input sources --- subgraph cluster_inputs { @@ -29,7 +29,7 @@ digraph ConfigResolution { color="#999999"; hook_config [label="hook config\n(behavior YAML)"]; - tool_config [label="tool config\n(overrides.tool-graph-query.config /\n overrides.tool-blob-read.config)"]; + tool_config [label="tool config\n(overrides.tool-context-intelligence-query.config)"]; coord_config [label="coordinator.config\n(set by app at session creation)"]; session_cap [label="session.working_dir\ncapability\n(set by foundation bundle.py)"]; env_vars [label="Environment Variables\nAMPLIFIER_CONTEXT_INTELLIGENCE_*\n(expanded in YAML before mount)", shape=note, fillcolor="#fff3cd"]; @@ -132,7 +132,7 @@ digraph ConfigResolution { fillcolor="#e0f2f1"; color="#009688"; - q1 [label="1. read_destinations[first]\n.url / .api_key\n(explicit read override;\n absent โ‡’ synthesize default from\n tool's explicit scalars)"]; + q1 [label="1. sources[first]\n.url / .api_key\n(explicit read override;\n absent โ‡’ synthesize default from\n tool's explicit scalars)"]; q2 [label="2. hook destinations[first]\n.url / .api_key\n(bug-fix bridge: destinations-only\n setups 'just work' for reads)"]; q3 [label="3. env\nAMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL /\n_API_KEY\n(single canonical last-resort fallback)"]; q_none [label="else โ†’ None\nโ†’ configuration_error", shape=note, fillcolor="#ffcdd2"]; diff --git a/context_intelligence/tool_resolver.py b/context_intelligence/tool_resolver.py index e3c26f4..b64435b 100644 --- a/context_intelligence/tool_resolver.py +++ b/context_intelligence/tool_resolver.py @@ -1,7 +1,7 @@ """ToolConfigResolver โ€” lazy config resolver for CI tools in analytics-only mode. -Used by tool-graph-query and tool-blob-read when the hook-context-intelligence -module is NOT mounted. Constructed **eagerly** inside the tool's ``__init__`` +Used by the tool-context-intelligence-query module (graph_query + blob_read tools) +when the hook-context-intelligence module is NOT mounted. Constructed **eagerly** inside the tool's ``__init__`` (both tools always create a ``ToolConfigResolver`` at construction time). Its properties mirror HookConfigResolver for the shared config keys. @@ -41,7 +41,7 @@ # --------------------------------------------------------------------------- -class ReadEndpoint(NamedTuple): +class Source(NamedTuple): """A single read-config entry (mirrors Destination shape, minus upload fields). url and api_key may be empty strings (โ†’ falsy โ†’ that field falls through @@ -62,8 +62,9 @@ def _first_entry(mapping: Any) -> Any | None: """First value of an insertion-ordered ``dict``, or None. Defensive: returns None when *mapping* is not a non-empty dict (e.g. a test - double, or an unset attribute). Used for BOTH read_destinations and the hook's - destinations so the 'first' rule is identical on both sides. + double, or an unset attribute). Used for BOTH the tool's own ``sources`` + mapping and the hook's destinations so the 'first' rule is identical on + both sides. """ if not isinstance(mapping, dict) or not mapping: return None @@ -92,23 +93,23 @@ def resolve_query_endpoint( """Resolve (server_url, api_key) for the query path. Per-field independent. Explicit-first order (each field, first non-empty wins): - 1. first entry of tool_resolver.read_destinations (.url / .api_key) + 1. first entry of tool_resolver.sources (.url / .api_key) 2. first upload destination on the hook resolver (.url / .api_key) 3. AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL / AMPLIFIER_CONTEXT_INTELLIGENCE_API_KEY Returns (None, None)-able per field; each is None only if all three miss. Emits one DEBUG line naming which tier supplied each field. """ - read = _first_entry(tool_resolver.read_destinations) + read = _first_entry(tool_resolver.sources) dest = _first_destination(hook_resolver) url, url_src = _pick( - ((read.url if read else None), f"read_destinations:{read.name}" if read else None), + ((read.url if read else None), f"source:{read.name}" if read else None), ((dest.url if dest else None), f"destination:{dest.name}" if dest else None), (_env("SERVER_URL"), "env:SERVER_URL"), ) api_key, key_src = _pick( - ((read.api_key if read else None), f"read_destinations:{read.name}" if read else None), + ((read.api_key if read else None), f"source:{read.name}" if read else None), ((dest.api_key if dest else None), f"destination:{dest.name}" if dest else None), (_env("API_KEY"), "env:API_KEY"), ) @@ -131,14 +132,14 @@ class ToolConfigResolver: Created eagerly at tool construction time alongside ``_hook_resolver = None``. Provides scalar config properties that mirror HookConfigResolver and a new - ``read_destinations`` mapping property for the explicit read-config model. + ``sources`` mapping property for the explicit read-config model. """ def __init__(self, config: dict[str, Any], coordinator: Any) -> None: self._config = config self._coordinator = coordinator self._workspace: str | None = None - self._read_destinations: dict[str, ReadEndpoint] | None = None + self._sources: dict[str, Source] | None = None # ------------------------------------------------------------------ # Private helpers @@ -156,7 +157,7 @@ def _coordinator_config_get(self, key: str) -> Any: return coord_config.get(key) # ------------------------------------------------------------------ - # Scalar properties (used by legacy synthesis in read_destinations) + # Scalar properties (used by legacy synthesis in sources) # ------------------------------------------------------------------ @property @@ -213,40 +214,40 @@ def workspace(self) -> str: # ------------------------------------------------------------------ @property - def read_destinations(self) -> dict[str, ReadEndpoint]: - """Parsed ``read_destinations`` mapping, or legacy-synthesized ``{"default": ...}``. + def sources(self) -> dict[str, Source]: + """Parsed ``sources`` mapping, or legacy-synthesized ``{"default": ...}``. Parsing rules: - - If ``config["read_destinations"]`` key is **present**: parse it + - If ``config["sources"]`` key is **present**: parse it (may be empty dict {}). Each value must be a dict; ``url``/``api_key`` are ``str(...).strip()``; non-dict entries are skipped. - If key is **absent**: apply legacy synthesis. If BOTH explicit ``context_intelligence_server_url`` and ``context_intelligence_api_key`` are non-empty (from ``config`` dict or coordinator.config **only** โ€” env and settings.yaml are excluded so env cannot enter tier 1), synthesize - ``{"default": ReadEndpoint(...)}``. Otherwise return ``{}``. + ``{"default": Source(...)}``. Otherwise return ``{}``. (Mirrors the hook's destinations D10 synthesis.) Cached after first access. """ - if self._read_destinations is not None: - return self._read_destinations + if self._sources is not None: + return self._sources _sentinel = object() - raw = self._config.get("read_destinations", _sentinel) + raw = self._config.get("sources", _sentinel) key_present = raw is not _sentinel if key_present: - result: dict[str, ReadEndpoint] = {} + result: dict[str, Source] = {} if isinstance(raw, dict): for name, spec in raw.items(): if not isinstance(spec, dict): continue url = str(spec.get("url", "") or "").strip() api_key = str(spec.get("api_key", "") or "").strip() - result[name] = ReadEndpoint(name=name, url=url, api_key=api_key) - self._read_destinations = result - return self._read_destinations + result[name] = Source(name=name, url=url, api_key=api_key) + self._sources = result + return self._sources # Key absent: legacy synthesis from EXPLICIT config only. # env and settings.yaml are intentionally excluded โ€” env is consulted only @@ -259,9 +260,7 @@ def read_destinations(self) -> dict[str, ReadEndpoint]: "context_intelligence_api_key" ) or self._coordinator_config_get("context_intelligence_api_key") if legacy_url and legacy_key: - self._read_destinations = { - "default": ReadEndpoint(name="default", url=legacy_url, api_key=legacy_key) - } + self._sources = {"default": Source(name="default", url=legacy_url, api_key=legacy_key)} else: - self._read_destinations = {} - return self._read_destinations + self._sources = {} + return self._sources diff --git a/modules/tool-blob-read/amplifier_module_tool_blob_read/__init__.py b/modules/tool-blob-read/amplifier_module_tool_blob_read/__init__.py deleted file mode 100644 index 5266003..0000000 --- a/modules/tool-blob-read/amplifier_module_tool_blob_read/__init__.py +++ /dev/null @@ -1,20 +0,0 @@ -"""Blob read tool module โ€” reads binary/text blobs from the context-intelligence server. - -Implements the Amplifier Tool protocol. Configuration is resolved lazily -via the ``context_intelligence.config_resolver`` coordinator capability -registered by the hook-context-intelligence module. -""" - -from __future__ import annotations - -from typing import Any - -__amplifier_module_type__ = "tool" - - -async def mount(coordinator: Any, config: Any) -> dict[str, Any]: # noqa: ARG001 - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool - - tool = BlobReadTool(coordinator, config) - await coordinator.mount("tools", tool, name=tool.name) - return {"tool": tool.name, "status": "mounted"} diff --git a/modules/tool-blob-read/tests/test_mount.py b/modules/tool-blob-read/tests/test_mount.py deleted file mode 100644 index 738be38..0000000 --- a/modules/tool-blob-read/tests/test_mount.py +++ /dev/null @@ -1,73 +0,0 @@ -"""Tests for tool-blob-read module mount contract.""" - -from __future__ import annotations - -import inspect -from unittest.mock import AsyncMock, MagicMock - - -class TestModuleContract: - """Module-level contract for a tool module.""" - - def test_module_type_is_tool(self) -> None: - from amplifier_module_tool_blob_read import __amplifier_module_type__ - - assert __amplifier_module_type__ == "tool" - - def test_mount_is_coroutine(self) -> None: - from amplifier_module_tool_blob_read import mount - - assert inspect.iscoroutinefunction(mount) - - def test_mount_signature_has_coordinator_and_config(self) -> None: - from amplifier_module_tool_blob_read import mount - - sig = inspect.signature(mount) - params = list(sig.parameters.keys()) - assert params[0] == "coordinator" - assert params[1] == "config" - - -class TestMountBehavior: - """mount() registers a Tool-protocol-compliant object via coordinator.mount().""" - - async def test_mount_calls_coordinator_mount_with_tools_category(self) -> None: - from amplifier_module_tool_blob_read import mount - - coordinator = MagicMock() - coordinator.mount = AsyncMock() - await mount(coordinator, config={}) - coordinator.mount.assert_called_once() - assert coordinator.mount.call_args.args[0] == "tools" - - async def test_mounted_tool_has_name_blob_read(self) -> None: - from amplifier_module_tool_blob_read import mount - - coordinator = MagicMock() - coordinator.mount = AsyncMock() - await mount(coordinator, config={}) - assert coordinator.mount.call_args.kwargs["name"] == "blob_read" - - async def test_mounted_tool_is_protocol_compliant(self) -> None: - from amplifier_module_tool_blob_read import mount - - coordinator = MagicMock() - coordinator.mount = AsyncMock() - await mount(coordinator, config={}) - tool = coordinator.mount.call_args.args[1] - assert hasattr(tool, "name") - assert hasattr(tool, "description") - assert hasattr(tool, "input_schema") - assert hasattr(tool, "execute") - assert isinstance(tool.input_schema, dict) - assert inspect.iscoroutinefunction(tool.execute) - - async def test_mount_returns_metadata_dict(self) -> None: - from amplifier_module_tool_blob_read import mount - - coordinator = MagicMock() - coordinator.mount = AsyncMock() - result = await mount(coordinator, config={}) - assert isinstance(result, dict) - assert "tool" in result - assert "status" in result diff --git a/modules/tool-blob-read/uv.lock b/modules/tool-blob-read/uv.lock deleted file mode 100644 index 4e71a98..0000000 --- a/modules/tool-blob-read/uv.lock +++ /dev/null @@ -1,515 +0,0 @@ -version = 1 -revision = 3 -requires-python = ">=3.11" - -[[package]] -name = "amplifier-bundle-context-intelligence" -version = "0.1.1" -source = { git = "https://github.com/microsoft/amplifier-bundle-context-intelligence?rev=main#2e47dc7c331b60210814f711129a10fdffd76ee4" } - -[[package]] -name = "amplifier-core" -version = "1.6.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "pydantic" }, - { name = "pyyaml" }, - { name = "tomli" }, - { name = "typing-extensions" }, -] -wheels = [ - { url = "https://files.pythonhosted.org/packages/32/90/d520390cd91aae3d02db53653f828046089c79203dbb142e9bda346fa1d6/amplifier_core-1.6.0-cp311-abi3-macosx_10_12_x86_64.whl", hash = "sha256:d35130e4262cf0db2d6c5f7e65e244a9ef2c7397bfe2a9853bc9b0d9fd05be64", size = 8113151, upload-time = "2026-05-18T16:13:46.825Z" }, - { url = "https://files.pythonhosted.org/packages/94/75/3ab3126ba5a6f2fc6051a4d08e42364899e4c9ac4daa9d0a60947bf8acd1/amplifier_core-1.6.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:387a2c58fcf4caefdb45c52ec228307bc225e73606897f242154782bc3e123da", size = 7268223, upload-time = "2026-05-18T16:13:48.749Z" }, - { url = "https://files.pythonhosted.org/packages/21/22/5a36160b3487170bcba0cbc61535101ff624e8314ed38fd35e561cb711a1/amplifier_core-1.6.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8344fccdedd725a51c018de17867cdf1c35abb571dabc0bbccdb5c1242324a47", size = 7532259, upload-time = "2026-05-18T16:13:50.614Z" }, - { url = "https://files.pythonhosted.org/packages/bd/d7/3874c2308523209411367cf3b8b690e14e869f5f6bfb64cb1b1971e06a96/amplifier_core-1.6.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a8e0103242a2e2a975c880b1de0e5a02501e0421c1e5386dadae3f111e1d2b5", size = 8507642, upload-time = "2026-05-18T16:13:52.977Z" }, - { url = "https://files.pythonhosted.org/packages/86/59/3646a89537b4556274183519f6db9c354fb3d183f52ef4a2179af12dd386/amplifier_core-1.6.0-cp311-abi3-win_amd64.whl", hash = "sha256:5113aa2d88038776eb257af9e7d9de7af13b3cd9097d2ac67aef5730fa0678e3", size = 8910313, upload-time = "2026-05-18T16:13:55.249Z" }, - { url = "https://files.pythonhosted.org/packages/9f/9e/58b141115e5eea65703f0b01459eefed36b561e9642ba96d48542345cd8f/amplifier_core-1.6.0-cp311-abi3-win_arm64.whl", hash = "sha256:e1b2731dc09d1cbc668b411007e7f9a2c7edbd75b2525407cae1e6b4a4de0b83", size = 7661416, upload-time = "2026-05-18T16:13:57.513Z" }, -] - -[[package]] -name = "amplifier-module-tool-blob-read" -version = "0.1.0" -source = { editable = "." } -dependencies = [ - { name = "amplifier-bundle-context-intelligence" }, - { name = "httpx" }, - { name = "idna" }, -] - -[package.dev-dependencies] -dev = [ - { name = "amplifier-core" }, - { name = "pyright" }, - { name = "pytest" }, - { name = "pytest-asyncio" }, - { name = "ruff" }, -] - -[package.metadata] -requires-dist = [ - { name = "amplifier-bundle-context-intelligence", git = "https://github.com/microsoft/amplifier-bundle-context-intelligence?rev=main" }, - { name = "httpx", specifier = ">=0.28.1" }, - { name = "idna", specifier = ">=3.15" }, -] - -[package.metadata.requires-dev] -dev = [ - { name = "amplifier-core", specifier = ">=1.6.0" }, - { name = "pyright", specifier = ">=1.1" }, - { name = "pytest", specifier = ">=9.0.3" }, - { name = "pytest-asyncio", specifier = ">=0.24" }, - { name = "ruff", specifier = ">=0.4" }, -] - -[[package]] -name = "annotated-types" -version = "0.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, -] - -[[package]] -name = "anyio" -version = "4.12.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "idna" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/96/f0/5eb65b2bb0d09ac6776f2eb54adee6abe8228ea05b20a5ad0e4945de8aac/anyio-4.12.1.tar.gz", hash = "sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703", size = 228685, upload-time = "2026-01-06T11:45:21.246Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl", hash = "sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c", size = 113592, upload-time = "2026-01-06T11:45:19.497Z" }, -] - -[[package]] -name = "certifi" -version = "2026.2.25" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, -] - -[[package]] -name = "click" -version = "8.3.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, -] - -[[package]] -name = "colorama" -version = "0.4.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, -] - -[[package]] -name = "h11" -version = "0.16.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, -] - -[[package]] -name = "httpcore" -version = "1.0.9" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "h11" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, -] - -[[package]] -name = "httpx" -version = "0.28.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "certifi" }, - { name = "httpcore" }, - { name = "idna" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, -] - -[[package]] -name = "idna" -version = "3.15" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/77/7b3966d0b9d1d31a36ddf1746926a11dface89a83409bf1483f0237aa758/idna-3.15.tar.gz", hash = "sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc", size = 199245, upload-time = "2026-05-12T22:45:57.011Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/23/408243171aa9aaba178d3e2559159c24c1171a641aa83b67bdd3394ead8e/idna-3.15-py3-none-any.whl", hash = "sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8", size = 72340, upload-time = "2026-05-12T22:45:55.733Z" }, -] - -[[package]] -name = "iniconfig" -version = "2.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, -] - -[[package]] -name = "nodeenv" -version = "1.10.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, -] - -[[package]] -name = "packaging" -version = "26.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, -] - -[[package]] -name = "pluggy" -version = "1.6.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, -] - -[[package]] -name = "pydantic" -version = "2.12.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "annotated-types" }, - { name = "pydantic-core" }, - { name = "typing-extensions" }, - { name = "typing-inspection" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, -] - -[[package]] -name = "pydantic-core" -version = "2.41.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e8/72/74a989dd9f2084b3d9530b0915fdda64ac48831c30dbf7c72a41a5232db8/pydantic_core-2.41.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6", size = 2105873, upload-time = "2025-11-04T13:39:31.373Z" }, - { url = "https://files.pythonhosted.org/packages/12/44/37e403fd9455708b3b942949e1d7febc02167662bf1a7da5b78ee1ea2842/pydantic_core-2.41.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b", size = 1899826, upload-time = "2025-11-04T13:39:32.897Z" }, - { url = "https://files.pythonhosted.org/packages/33/7f/1d5cab3ccf44c1935a359d51a8a2a9e1a654b744b5e7f80d41b88d501eec/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a", size = 1917869, upload-time = "2025-11-04T13:39:34.469Z" }, - { url = "https://files.pythonhosted.org/packages/6e/6a/30d94a9674a7fe4f4744052ed6c5e083424510be1e93da5bc47569d11810/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8", size = 2063890, upload-time = "2025-11-04T13:39:36.053Z" }, - { url = "https://files.pythonhosted.org/packages/50/be/76e5d46203fcb2750e542f32e6c371ffa9b8ad17364cf94bb0818dbfb50c/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e", size = 2229740, upload-time = "2025-11-04T13:39:37.753Z" }, - { url = "https://files.pythonhosted.org/packages/d3/ee/fed784df0144793489f87db310a6bbf8118d7b630ed07aa180d6067e653a/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1", size = 2350021, upload-time = "2025-11-04T13:39:40.94Z" }, - { url = "https://files.pythonhosted.org/packages/c8/be/8fed28dd0a180dca19e72c233cbf58efa36df055e5b9d90d64fd1740b828/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b", size = 2066378, upload-time = "2025-11-04T13:39:42.523Z" }, - { url = "https://files.pythonhosted.org/packages/b0/3b/698cf8ae1d536a010e05121b4958b1257f0b5522085e335360e53a6b1c8b/pydantic_core-2.41.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b", size = 2175761, upload-time = "2025-11-04T13:39:44.553Z" }, - { url = "https://files.pythonhosted.org/packages/b8/ba/15d537423939553116dea94ce02f9c31be0fa9d0b806d427e0308ec17145/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284", size = 2146303, upload-time = "2025-11-04T13:39:46.238Z" }, - { url = "https://files.pythonhosted.org/packages/58/7f/0de669bf37d206723795f9c90c82966726a2ab06c336deba4735b55af431/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594", size = 2340355, upload-time = "2025-11-04T13:39:48.002Z" }, - { url = "https://files.pythonhosted.org/packages/e5/de/e7482c435b83d7e3c3ee5ee4451f6e8973cff0eb6007d2872ce6383f6398/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e", size = 2319875, upload-time = "2025-11-04T13:39:49.705Z" }, - { url = "https://files.pythonhosted.org/packages/fe/e6/8c9e81bb6dd7560e33b9053351c29f30c8194b72f2d6932888581f503482/pydantic_core-2.41.5-cp311-cp311-win32.whl", hash = "sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b", size = 1987549, upload-time = "2025-11-04T13:39:51.842Z" }, - { url = "https://files.pythonhosted.org/packages/11/66/f14d1d978ea94d1bc21fc98fcf570f9542fe55bfcc40269d4e1a21c19bf7/pydantic_core-2.41.5-cp311-cp311-win_amd64.whl", hash = "sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe", size = 2011305, upload-time = "2025-11-04T13:39:53.485Z" }, - { url = "https://files.pythonhosted.org/packages/56/d8/0e271434e8efd03186c5386671328154ee349ff0354d83c74f5caaf096ed/pydantic_core-2.41.5-cp311-cp311-win_arm64.whl", hash = "sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f", size = 1972902, upload-time = "2025-11-04T13:39:56.488Z" }, - { url = "https://files.pythonhosted.org/packages/5f/5d/5f6c63eebb5afee93bcaae4ce9a898f3373ca23df3ccaef086d0233a35a7/pydantic_core-2.41.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7", size = 2110990, upload-time = "2025-11-04T13:39:58.079Z" }, - { url = "https://files.pythonhosted.org/packages/aa/32/9c2e8ccb57c01111e0fd091f236c7b371c1bccea0fa85247ac55b1e2b6b6/pydantic_core-2.41.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0", size = 1896003, upload-time = "2025-11-04T13:39:59.956Z" }, - { url = "https://files.pythonhosted.org/packages/68/b8/a01b53cb0e59139fbc9e4fda3e9724ede8de279097179be4ff31f1abb65a/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69", size = 1919200, upload-time = "2025-11-04T13:40:02.241Z" }, - { url = "https://files.pythonhosted.org/packages/38/de/8c36b5198a29bdaade07b5985e80a233a5ac27137846f3bc2d3b40a47360/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75", size = 2052578, upload-time = "2025-11-04T13:40:04.401Z" }, - { url = "https://files.pythonhosted.org/packages/00/b5/0e8e4b5b081eac6cb3dbb7e60a65907549a1ce035a724368c330112adfdd/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05", size = 2208504, upload-time = "2025-11-04T13:40:06.072Z" }, - { url = "https://files.pythonhosted.org/packages/77/56/87a61aad59c7c5b9dc8caad5a41a5545cba3810c3e828708b3d7404f6cef/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc", size = 2335816, upload-time = "2025-11-04T13:40:07.835Z" }, - { url = "https://files.pythonhosted.org/packages/0d/76/941cc9f73529988688a665a5c0ecff1112b3d95ab48f81db5f7606f522d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c", size = 2075366, upload-time = "2025-11-04T13:40:09.804Z" }, - { url = "https://files.pythonhosted.org/packages/d3/43/ebef01f69baa07a482844faaa0a591bad1ef129253ffd0cdaa9d8a7f72d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5", size = 2171698, upload-time = "2025-11-04T13:40:12.004Z" }, - { url = "https://files.pythonhosted.org/packages/b1/87/41f3202e4193e3bacfc2c065fab7706ebe81af46a83d3e27605029c1f5a6/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c", size = 2132603, upload-time = "2025-11-04T13:40:13.868Z" }, - { url = "https://files.pythonhosted.org/packages/49/7d/4c00df99cb12070b6bccdef4a195255e6020a550d572768d92cc54dba91a/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294", size = 2329591, upload-time = "2025-11-04T13:40:15.672Z" }, - { url = "https://files.pythonhosted.org/packages/cc/6a/ebf4b1d65d458f3cda6a7335d141305dfa19bdc61140a884d165a8a1bbc7/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1", size = 2319068, upload-time = "2025-11-04T13:40:17.532Z" }, - { url = "https://files.pythonhosted.org/packages/49/3b/774f2b5cd4192d5ab75870ce4381fd89cf218af999515baf07e7206753f0/pydantic_core-2.41.5-cp312-cp312-win32.whl", hash = "sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d", size = 1985908, upload-time = "2025-11-04T13:40:19.309Z" }, - { url = "https://files.pythonhosted.org/packages/86/45/00173a033c801cacf67c190fef088789394feaf88a98a7035b0e40d53dc9/pydantic_core-2.41.5-cp312-cp312-win_amd64.whl", hash = "sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815", size = 2020145, upload-time = "2025-11-04T13:40:21.548Z" }, - { url = "https://files.pythonhosted.org/packages/f9/22/91fbc821fa6d261b376a3f73809f907cec5ca6025642c463d3488aad22fb/pydantic_core-2.41.5-cp312-cp312-win_arm64.whl", hash = "sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3", size = 1976179, upload-time = "2025-11-04T13:40:23.393Z" }, - { url = "https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", size = 2120403, upload-time = "2025-11-04T13:40:25.248Z" }, - { url = "https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", size = 1896206, upload-time = "2025-11-04T13:40:27.099Z" }, - { url = "https://files.pythonhosted.org/packages/15/df/a4c740c0943e93e6500f9eb23f4ca7ec9bf71b19e608ae5b579678c8d02f/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", size = 1919307, upload-time = "2025-11-04T13:40:29.806Z" }, - { url = "https://files.pythonhosted.org/packages/9a/e3/6324802931ae1d123528988e0e86587c2072ac2e5394b4bc2bc34b61ff6e/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", size = 2063258, upload-time = "2025-11-04T13:40:33.544Z" }, - { url = "https://files.pythonhosted.org/packages/c9/d4/2230d7151d4957dd79c3044ea26346c148c98fbf0ee6ebd41056f2d62ab5/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", size = 2214917, upload-time = "2025-11-04T13:40:35.479Z" }, - { url = "https://files.pythonhosted.org/packages/e6/9f/eaac5df17a3672fef0081b6c1bb0b82b33ee89aa5cec0d7b05f52fd4a1fa/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", size = 2332186, upload-time = "2025-11-04T13:40:37.436Z" }, - { url = "https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", size = 2073164, upload-time = "2025-11-04T13:40:40.289Z" }, - { url = "https://files.pythonhosted.org/packages/bf/e3/f6e262673c6140dd3305d144d032f7bd5f7497d3871c1428521f19f9efa2/pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", size = 2179146, upload-time = "2025-11-04T13:40:42.809Z" }, - { url = "https://files.pythonhosted.org/packages/75/c7/20bd7fc05f0c6ea2056a4565c6f36f8968c0924f19b7d97bbfea55780e73/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", size = 2137788, upload-time = "2025-11-04T13:40:44.752Z" }, - { url = "https://files.pythonhosted.org/packages/3a/8d/34318ef985c45196e004bc46c6eab2eda437e744c124ef0dbe1ff2c9d06b/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", size = 2340133, upload-time = "2025-11-04T13:40:46.66Z" }, - { url = "https://files.pythonhosted.org/packages/9c/59/013626bf8c78a5a5d9350d12e7697d3d4de951a75565496abd40ccd46bee/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", size = 2324852, upload-time = "2025-11-04T13:40:48.575Z" }, - { url = "https://files.pythonhosted.org/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679, upload-time = "2025-11-04T13:40:50.619Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766, upload-time = "2025-11-04T13:40:52.631Z" }, - { url = "https://files.pythonhosted.org/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005, upload-time = "2025-11-04T13:40:54.734Z" }, - { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" }, - { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" }, - { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" }, - { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" }, - { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" }, - { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" }, - { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" }, - { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" }, - { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" }, - { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" }, - { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" }, - { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" }, - { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" }, - { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" }, - { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" }, - { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" }, - { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" }, - { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" }, - { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" }, - { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" }, - { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" }, - { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" }, - { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" }, - { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" }, - { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" }, - { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, - { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, - { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, - { url = "https://files.pythonhosted.org/packages/11/72/90fda5ee3b97e51c494938a4a44c3a35a9c96c19bba12372fb9c634d6f57/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034", size = 2115441, upload-time = "2025-11-04T13:42:39.557Z" }, - { url = "https://files.pythonhosted.org/packages/1f/53/8942f884fa33f50794f119012dc6a1a02ac43a56407adaac20463df8e98f/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c", size = 1930291, upload-time = "2025-11-04T13:42:42.169Z" }, - { url = "https://files.pythonhosted.org/packages/79/c8/ecb9ed9cd942bce09fc888ee960b52654fbdbede4ba6c2d6e0d3b1d8b49c/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2", size = 1948632, upload-time = "2025-11-04T13:42:44.564Z" }, - { url = "https://files.pythonhosted.org/packages/2e/1b/687711069de7efa6af934e74f601e2a4307365e8fdc404703afc453eab26/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad", size = 2138905, upload-time = "2025-11-04T13:42:47.156Z" }, - { url = "https://files.pythonhosted.org/packages/09/32/59b0c7e63e277fa7911c2fc70ccfb45ce4b98991e7ef37110663437005af/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd", size = 2110495, upload-time = "2025-11-04T13:42:49.689Z" }, - { url = "https://files.pythonhosted.org/packages/aa/81/05e400037eaf55ad400bcd318c05bb345b57e708887f07ddb2d20e3f0e98/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc", size = 1915388, upload-time = "2025-11-04T13:42:52.215Z" }, - { url = "https://files.pythonhosted.org/packages/6e/0d/e3549b2399f71d56476b77dbf3cf8937cec5cd70536bdc0e374a421d0599/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56", size = 1942879, upload-time = "2025-11-04T13:42:56.483Z" }, - { url = "https://files.pythonhosted.org/packages/f7/07/34573da085946b6a313d7c42f82f16e8920bfd730665de2d11c0c37a74b5/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b", size = 2139017, upload-time = "2025-11-04T13:42:59.471Z" }, - { url = "https://files.pythonhosted.org/packages/5f/9b/1b3f0e9f9305839d7e84912f9e8bfbd191ed1b1ef48083609f0dabde978c/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26", size = 2101980, upload-time = "2025-11-04T13:43:25.97Z" }, - { url = "https://files.pythonhosted.org/packages/a4/ed/d71fefcb4263df0da6a85b5d8a7508360f2f2e9b3bf5814be9c8bccdccc1/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808", size = 1923865, upload-time = "2025-11-04T13:43:28.763Z" }, - { url = "https://files.pythonhosted.org/packages/ce/3a/626b38db460d675f873e4444b4bb030453bbe7b4ba55df821d026a0493c4/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc", size = 2134256, upload-time = "2025-11-04T13:43:31.71Z" }, - { url = "https://files.pythonhosted.org/packages/83/d9/8412d7f06f616bbc053d30cb4e5f76786af3221462ad5eee1f202021eb4e/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1", size = 2174762, upload-time = "2025-11-04T13:43:34.744Z" }, - { url = "https://files.pythonhosted.org/packages/55/4c/162d906b8e3ba3a99354e20faa1b49a85206c47de97a639510a0e673f5da/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84", size = 2143141, upload-time = "2025-11-04T13:43:37.701Z" }, - { url = "https://files.pythonhosted.org/packages/1f/f2/f11dd73284122713f5f89fc940f370d035fa8e1e078d446b3313955157fe/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770", size = 2330317, upload-time = "2025-11-04T13:43:40.406Z" }, - { url = "https://files.pythonhosted.org/packages/88/9d/b06ca6acfe4abb296110fb1273a4d848a0bfb2ff65f3ee92127b3244e16b/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f", size = 2316992, upload-time = "2025-11-04T13:43:43.602Z" }, - { url = "https://files.pythonhosted.org/packages/36/c7/cfc8e811f061c841d7990b0201912c3556bfeb99cdcb7ed24adc8d6f8704/pydantic_core-2.41.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51", size = 2145302, upload-time = "2025-11-04T13:43:46.64Z" }, -] - -[[package]] -name = "pygments" -version = "2.20.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, -] - -[[package]] -name = "pyright" -version = "1.1.408" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "nodeenv" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/74/b2/5db700e52554b8f025faa9c3c624c59f1f6c8841ba81ab97641b54322f16/pyright-1.1.408.tar.gz", hash = "sha256:f28f2321f96852fa50b5829ea492f6adb0e6954568d1caa3f3af3a5f555eb684", size = 4400578, upload-time = "2026-01-08T08:07:38.795Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/82/a2c93e32800940d9573fb28c346772a14778b84ba7524e691b324620ab89/pyright-1.1.408-py3-none-any.whl", hash = "sha256:090b32865f4fdb1e0e6cd82bf5618480d48eecd2eb2e70f960982a3d9a4c17c1", size = 6399144, upload-time = "2026-01-08T08:07:37.082Z" }, -] - -[[package]] -name = "pytest" -version = "9.0.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "iniconfig" }, - { name = "packaging" }, - { name = "pluggy" }, - { name = "pygments" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, -] - -[[package]] -name = "pytest-asyncio" -version = "1.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pytest" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5", size = 50087, upload-time = "2025-11-10T16:07:47.256Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075, upload-time = "2025-11-10T16:07:45.537Z" }, -] - -[[package]] -name = "pyyaml" -version = "6.0.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, - { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, - { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, - { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, - { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, - { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, - { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, - { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, - { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, - { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, - { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, - { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, - { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, - { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, - { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, - { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, - { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, - { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, - { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, - { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, - { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, - { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, - { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, - { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, - { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, - { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, - { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, - { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, - { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, - { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, - { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, - { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, - { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, - { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, - { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, - { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, - { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, - { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, - { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, - { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, - { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, - { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, - { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, - { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, - { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, - { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, - { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, -] - -[[package]] -name = "ruff" -version = "0.15.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/51/df/f8629c19c5318601d3121e230f74cbee7a3732339c52b21daa2b82ef9c7d/ruff-0.15.6.tar.gz", hash = "sha256:8394c7bb153a4e3811a4ecdacd4a8e6a4fa8097028119160dffecdcdf9b56ae4", size = 4597916, upload-time = "2026-03-12T23:05:47.51Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/2f/4e03a7e5ce99b517e98d3b4951f411de2b0fa8348d39cf446671adcce9a2/ruff-0.15.6-py3-none-linux_armv6l.whl", hash = "sha256:7c98c3b16407b2cf3d0f2b80c80187384bc92c6774d85fefa913ecd941256fff", size = 10508953, upload-time = "2026-03-12T23:05:17.246Z" }, - { url = "https://files.pythonhosted.org/packages/70/60/55bcdc3e9f80bcf39edf0cd272da6fa511a3d94d5a0dd9e0adf76ceebdb4/ruff-0.15.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ee7dcfaad8b282a284df4aa6ddc2741b3f4a18b0555d626805555a820ea181c3", size = 10942257, upload-time = "2026-03-12T23:05:23.076Z" }, - { url = "https://files.pythonhosted.org/packages/e7/f9/005c29bd1726c0f492bfa215e95154cf480574140cb5f867c797c18c790b/ruff-0.15.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3bd9967851a25f038fc8b9ae88a7fbd1b609f30349231dffaa37b6804923c4bb", size = 10322683, upload-time = "2026-03-12T23:05:33.738Z" }, - { url = "https://files.pythonhosted.org/packages/5f/74/2f861f5fd7cbb2146bddb5501450300ce41562da36d21868c69b7a828169/ruff-0.15.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13f4594b04e42cd24a41da653886b04d2ff87adbf57497ed4f728b0e8a4866f8", size = 10660986, upload-time = "2026-03-12T23:05:53.245Z" }, - { url = "https://files.pythonhosted.org/packages/c1/a1/309f2364a424eccb763cdafc49df843c282609f47fe53aa83f38272389e0/ruff-0.15.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e2ed8aea2f3fe57886d3f00ea5b8aae5bf68d5e195f487f037a955ff9fbaac9e", size = 10332177, upload-time = "2026-03-12T23:05:56.145Z" }, - { url = "https://files.pythonhosted.org/packages/30/41/7ebf1d32658b4bab20f8ac80972fb19cd4e2c6b78552be263a680edc55ac/ruff-0.15.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70789d3e7830b848b548aae96766431c0dc01a6c78c13381f423bf7076c66d15", size = 11170783, upload-time = "2026-03-12T23:06:01.742Z" }, - { url = "https://files.pythonhosted.org/packages/76/be/6d488f6adca047df82cd62c304638bcb00821c36bd4881cfca221561fdfc/ruff-0.15.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:542aaf1de3154cea088ced5a819ce872611256ffe2498e750bbae5247a8114e9", size = 12044201, upload-time = "2026-03-12T23:05:28.697Z" }, - { url = "https://files.pythonhosted.org/packages/71/68/e6f125df4af7e6d0b498f8d373274794bc5156b324e8ab4bf5c1b4fc0ec7/ruff-0.15.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c22e6f02c16cfac3888aa636e9eba857254d15bbacc9906c9689fdecb1953ab", size = 11421561, upload-time = "2026-03-12T23:05:31.236Z" }, - { url = "https://files.pythonhosted.org/packages/f1/9f/f85ef5fd01a52e0b472b26dc1b4bd228b8f6f0435975442ffa4741278703/ruff-0.15.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98893c4c0aadc8e448cfa315bd0cc343a5323d740fe5f28ef8a3f9e21b381f7e", size = 11310928, upload-time = "2026-03-12T23:05:45.288Z" }, - { url = "https://files.pythonhosted.org/packages/8c/26/b75f8c421f5654304b89471ed384ae8c7f42b4dff58fa6ce1626d7f2b59a/ruff-0.15.6-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:70d263770d234912374493e8cc1e7385c5d49376e41dfa51c5c3453169dc581c", size = 11235186, upload-time = "2026-03-12T23:05:50.677Z" }, - { url = "https://files.pythonhosted.org/packages/fc/d4/d5a6d065962ff7a68a86c9b4f5500f7d101a0792078de636526c0edd40da/ruff-0.15.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:55a1ad63c5a6e54b1f21b7514dfadc0c7fb40093fa22e95143cf3f64ebdcd512", size = 10635231, upload-time = "2026-03-12T23:05:37.044Z" }, - { url = "https://files.pythonhosted.org/packages/d6/56/7c3acf3d50910375349016cf33de24be021532042afbed87942858992491/ruff-0.15.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8dc473ba093c5ec238bb1e7429ee676dca24643c471e11fbaa8a857925b061c0", size = 10340357, upload-time = "2026-03-12T23:06:04.748Z" }, - { url = "https://files.pythonhosted.org/packages/06/54/6faa39e9c1033ff6a3b6e76b5df536931cd30caf64988e112bbf91ef5ce5/ruff-0.15.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:85b042377c2a5561131767974617006f99f7e13c63c111b998f29fc1e58a4cfb", size = 10860583, upload-time = "2026-03-12T23:05:58.978Z" }, - { url = "https://files.pythonhosted.org/packages/cb/1e/509a201b843b4dfb0b32acdedf68d951d3377988cae43949ba4c4133a96a/ruff-0.15.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cef49e30bc5a86a6a92098a7fbf6e467a234d90b63305d6f3ec01225a9d092e0", size = 11410976, upload-time = "2026-03-12T23:05:39.955Z" }, - { url = "https://files.pythonhosted.org/packages/6c/25/3fc9114abf979a41673ce877c08016f8e660ad6cf508c3957f537d2e9fa9/ruff-0.15.6-py3-none-win32.whl", hash = "sha256:bbf67d39832404812a2d23020dda68fee7f18ce15654e96fb1d3ad21a5fe436c", size = 10616872, upload-time = "2026-03-12T23:05:42.451Z" }, - { url = "https://files.pythonhosted.org/packages/89/7a/09ece68445ceac348df06e08bf75db72d0e8427765b96c9c0ffabc1be1d9/ruff-0.15.6-py3-none-win_amd64.whl", hash = "sha256:aee25bc84c2f1007ecb5037dff75cef00414fdf17c23f07dc13e577883dca406", size = 11787271, upload-time = "2026-03-12T23:05:20.168Z" }, - { url = "https://files.pythonhosted.org/packages/7f/d0/578c47dd68152ddddddf31cd7fc67dc30b7cdf639a86275fda821b0d9d98/ruff-0.15.6-py3-none-win_arm64.whl", hash = "sha256:c34de3dd0b0ba203be50ae70f5910b17188556630e2178fd7d79fc030eb0d837", size = 11060497, upload-time = "2026-03-12T23:05:25.968Z" }, -] - -[[package]] -name = "tomli" -version = "2.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/30/31573e9457673ab10aa432461bee537ce6cef177667deca369efb79df071/tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c", size = 17477, upload-time = "2026-01-11T11:22:38.165Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/d9/3dc2289e1f3b32eb19b9785b6a006b28ee99acb37d1d47f78d4c10e28bf8/tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867", size = 153663, upload-time = "2026-01-11T11:21:45.27Z" }, - { url = "https://files.pythonhosted.org/packages/51/32/ef9f6845e6b9ca392cd3f64f9ec185cc6f09f0a2df3db08cbe8809d1d435/tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9", size = 148469, upload-time = "2026-01-11T11:21:46.873Z" }, - { url = "https://files.pythonhosted.org/packages/d6/c2/506e44cce89a8b1b1e047d64bd495c22c9f71f21e05f380f1a950dd9c217/tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95", size = 236039, upload-time = "2026-01-11T11:21:48.503Z" }, - { url = "https://files.pythonhosted.org/packages/b3/40/e1b65986dbc861b7e986e8ec394598187fa8aee85b1650b01dd925ca0be8/tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76", size = 243007, upload-time = "2026-01-11T11:21:49.456Z" }, - { url = "https://files.pythonhosted.org/packages/9c/6f/6e39ce66b58a5b7ae572a0f4352ff40c71e8573633deda43f6a379d56b3e/tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d", size = 240875, upload-time = "2026-01-11T11:21:50.755Z" }, - { url = "https://files.pythonhosted.org/packages/aa/ad/cb089cb190487caa80204d503c7fd0f4d443f90b95cf4ef5cf5aa0f439b0/tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576", size = 246271, upload-time = "2026-01-11T11:21:51.81Z" }, - { url = "https://files.pythonhosted.org/packages/0b/63/69125220e47fd7a3a27fd0de0c6398c89432fec41bc739823bcc66506af6/tomli-2.4.0-cp311-cp311-win32.whl", hash = "sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a", size = 96770, upload-time = "2026-01-11T11:21:52.647Z" }, - { url = "https://files.pythonhosted.org/packages/1e/0d/a22bb6c83f83386b0008425a6cd1fa1c14b5f3dd4bad05e98cf3dbbf4a64/tomli-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa", size = 107626, upload-time = "2026-01-11T11:21:53.459Z" }, - { url = "https://files.pythonhosted.org/packages/2f/6d/77be674a3485e75cacbf2ddba2b146911477bd887dda9d8c9dfb2f15e871/tomli-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614", size = 94842, upload-time = "2026-01-11T11:21:54.831Z" }, - { url = "https://files.pythonhosted.org/packages/3c/43/7389a1869f2f26dba52404e1ef13b4784b6b37dac93bac53457e3ff24ca3/tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1", size = 154894, upload-time = "2026-01-11T11:21:56.07Z" }, - { url = "https://files.pythonhosted.org/packages/e9/05/2f9bf110b5294132b2edf13fe6ca6ae456204f3d749f623307cbb7a946f2/tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8", size = 149053, upload-time = "2026-01-11T11:21:57.467Z" }, - { url = "https://files.pythonhosted.org/packages/e8/41/1eda3ca1abc6f6154a8db4d714a4d35c4ad90adc0bcf700657291593fbf3/tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a", size = 243481, upload-time = "2026-01-11T11:21:58.661Z" }, - { url = "https://files.pythonhosted.org/packages/d2/6d/02ff5ab6c8868b41e7d4b987ce2b5f6a51d3335a70aa144edd999e055a01/tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1", size = 251720, upload-time = "2026-01-11T11:22:00.178Z" }, - { url = "https://files.pythonhosted.org/packages/7b/57/0405c59a909c45d5b6f146107c6d997825aa87568b042042f7a9c0afed34/tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b", size = 247014, upload-time = "2026-01-11T11:22:01.238Z" }, - { url = "https://files.pythonhosted.org/packages/2c/0e/2e37568edd944b4165735687cbaf2fe3648129e440c26d02223672ee0630/tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51", size = 251820, upload-time = "2026-01-11T11:22:02.727Z" }, - { url = "https://files.pythonhosted.org/packages/5a/1c/ee3b707fdac82aeeb92d1a113f803cf6d0f37bdca0849cb489553e1f417a/tomli-2.4.0-cp312-cp312-win32.whl", hash = "sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729", size = 97712, upload-time = "2026-01-11T11:22:03.777Z" }, - { url = "https://files.pythonhosted.org/packages/69/13/c07a9177d0b3bab7913299b9278845fc6eaaca14a02667c6be0b0a2270c8/tomli-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da", size = 108296, upload-time = "2026-01-11T11:22:04.86Z" }, - { url = "https://files.pythonhosted.org/packages/18/27/e267a60bbeeee343bcc279bb9e8fbed0cbe224bc7b2a3dc2975f22809a09/tomli-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3", size = 94553, upload-time = "2026-01-11T11:22:05.854Z" }, - { url = "https://files.pythonhosted.org/packages/34/91/7f65f9809f2936e1f4ce6268ae1903074563603b2a2bd969ebbda802744f/tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0", size = 154915, upload-time = "2026-01-11T11:22:06.703Z" }, - { url = "https://files.pythonhosted.org/packages/20/aa/64dd73a5a849c2e8f216b755599c511badde80e91e9bc2271baa7b2cdbb1/tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e", size = 149038, upload-time = "2026-01-11T11:22:07.56Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8a/6d38870bd3d52c8d1505ce054469a73f73a0fe62c0eaf5dddf61447e32fa/tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4", size = 242245, upload-time = "2026-01-11T11:22:08.344Z" }, - { url = "https://files.pythonhosted.org/packages/59/bb/8002fadefb64ab2669e5b977df3f5e444febea60e717e755b38bb7c41029/tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e", size = 250335, upload-time = "2026-01-11T11:22:09.951Z" }, - { url = "https://files.pythonhosted.org/packages/a5/3d/4cdb6f791682b2ea916af2de96121b3cb1284d7c203d97d92d6003e91c8d/tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c", size = 245962, upload-time = "2026-01-11T11:22:11.27Z" }, - { url = "https://files.pythonhosted.org/packages/f2/4a/5f25789f9a460bd858ba9756ff52d0830d825b458e13f754952dd15fb7bb/tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f", size = 250396, upload-time = "2026-01-11T11:22:12.325Z" }, - { url = "https://files.pythonhosted.org/packages/aa/2f/b73a36fea58dfa08e8b3a268750e6853a6aac2a349241a905ebd86f3047a/tomli-2.4.0-cp313-cp313-win32.whl", hash = "sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86", size = 97530, upload-time = "2026-01-11T11:22:13.865Z" }, - { url = "https://files.pythonhosted.org/packages/3b/af/ca18c134b5d75de7e8dc551c5234eaba2e8e951f6b30139599b53de9c187/tomli-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87", size = 108227, upload-time = "2026-01-11T11:22:15.224Z" }, - { url = "https://files.pythonhosted.org/packages/22/c3/b386b832f209fee8073c8138ec50f27b4460db2fdae9ffe022df89a57f9b/tomli-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132", size = 94748, upload-time = "2026-01-11T11:22:16.009Z" }, - { url = "https://files.pythonhosted.org/packages/f3/c4/84047a97eb1004418bc10bdbcfebda209fca6338002eba2dc27cc6d13563/tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6", size = 154725, upload-time = "2026-01-11T11:22:17.269Z" }, - { url = "https://files.pythonhosted.org/packages/a8/5d/d39038e646060b9d76274078cddf146ced86dc2b9e8bbf737ad5983609a0/tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc", size = 148901, upload-time = "2026-01-11T11:22:18.287Z" }, - { url = "https://files.pythonhosted.org/packages/73/e5/383be1724cb30f4ce44983d249645684a48c435e1cd4f8b5cded8a816d3c/tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66", size = 243375, upload-time = "2026-01-11T11:22:19.154Z" }, - { url = "https://files.pythonhosted.org/packages/31/f0/bea80c17971c8d16d3cc109dc3585b0f2ce1036b5f4a8a183789023574f2/tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d", size = 250639, upload-time = "2026-01-11T11:22:20.168Z" }, - { url = "https://files.pythonhosted.org/packages/2c/8f/2853c36abbb7608e3f945d8a74e32ed3a74ee3a1f468f1ffc7d1cb3abba6/tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702", size = 246897, upload-time = "2026-01-11T11:22:21.544Z" }, - { url = "https://files.pythonhosted.org/packages/49/f0/6c05e3196ed5337b9fe7ea003e95fd3819a840b7a0f2bf5a408ef1dad8ed/tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8", size = 254697, upload-time = "2026-01-11T11:22:23.058Z" }, - { url = "https://files.pythonhosted.org/packages/f3/f5/2922ef29c9f2951883525def7429967fc4d8208494e5ab524234f06b688b/tomli-2.4.0-cp314-cp314-win32.whl", hash = "sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776", size = 98567, upload-time = "2026-01-11T11:22:24.033Z" }, - { url = "https://files.pythonhosted.org/packages/7b/31/22b52e2e06dd2a5fdbc3ee73226d763b184ff21fc24e20316a44ccc4d96b/tomli-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475", size = 108556, upload-time = "2026-01-11T11:22:25.378Z" }, - { url = "https://files.pythonhosted.org/packages/48/3d/5058dff3255a3d01b705413f64f4306a141a8fd7a251e5a495e3f192a998/tomli-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2", size = 96014, upload-time = "2026-01-11T11:22:26.138Z" }, - { url = "https://files.pythonhosted.org/packages/b8/4e/75dab8586e268424202d3a1997ef6014919c941b50642a1682df43204c22/tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9", size = 163339, upload-time = "2026-01-11T11:22:27.143Z" }, - { url = "https://files.pythonhosted.org/packages/06/e3/b904d9ab1016829a776d97f163f183a48be6a4deb87304d1e0116a349519/tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0", size = 159490, upload-time = "2026-01-11T11:22:28.399Z" }, - { url = "https://files.pythonhosted.org/packages/e3/5a/fc3622c8b1ad823e8ea98a35e3c632ee316d48f66f80f9708ceb4f2a0322/tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df", size = 269398, upload-time = "2026-01-11T11:22:29.345Z" }, - { url = "https://files.pythonhosted.org/packages/fd/33/62bd6152c8bdd4c305ad9faca48f51d3acb2df1f8791b1477d46ff86e7f8/tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d", size = 276515, upload-time = "2026-01-11T11:22:30.327Z" }, - { url = "https://files.pythonhosted.org/packages/4b/ff/ae53619499f5235ee4211e62a8d7982ba9e439a0fb4f2f351a93d67c1dd2/tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f", size = 273806, upload-time = "2026-01-11T11:22:32.56Z" }, - { url = "https://files.pythonhosted.org/packages/47/71/cbca7787fa68d4d0a9f7072821980b39fbb1b6faeb5f5cf02f4a5559fa28/tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b", size = 281340, upload-time = "2026-01-11T11:22:33.505Z" }, - { url = "https://files.pythonhosted.org/packages/f5/00/d595c120963ad42474cf6ee7771ad0d0e8a49d0f01e29576ee9195d9ecdf/tomli-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087", size = 108106, upload-time = "2026-01-11T11:22:34.451Z" }, - { url = "https://files.pythonhosted.org/packages/de/69/9aa0c6a505c2f80e519b43764f8b4ba93b5a0bbd2d9a9de6e2b24271b9a5/tomli-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd", size = 120504, upload-time = "2026-01-11T11:22:35.764Z" }, - { url = "https://files.pythonhosted.org/packages/b3/9f/f1668c281c58cfae01482f7114a4b88d345e4c140386241a1a24dcc9e7bc/tomli-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4", size = 99561, upload-time = "2026-01-11T11:22:36.624Z" }, - { url = "https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a", size = 14477, upload-time = "2026-01-11T11:22:37.446Z" }, -] - -[[package]] -name = "typing-extensions" -version = "4.15.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, -] - -[[package]] -name = "typing-inspection" -version = "0.4.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, -] diff --git a/modules/tool-context-intelligence-query/amplifier_module_tool_context_intelligence_query/__init__.py b/modules/tool-context-intelligence-query/amplifier_module_tool_context_intelligence_query/__init__.py new file mode 100644 index 0000000..836682f --- /dev/null +++ b/modules/tool-context-intelligence-query/amplifier_module_tool_context_intelligence_query/__init__.py @@ -0,0 +1,41 @@ +"""Context Intelligence read tools โ€” graph_query and blob_read. + +Both tools share one ToolConfigResolver, so sources has a single +config namespace: overrides.tool-context-intelligence-query.config.sources. + +Two tools, one mount(): idiomatic multi-tool module (same as tool-filesystem +which mounts read_file / write_file / edit_file from one mount() call). +""" + +from __future__ import annotations + +from typing import Any + +__amplifier_module_type__ = "tool" + + +async def mount(coordinator: Any, config: Any) -> None: + """Mount both CI read tools, sharing one ToolConfigResolver. + + The resolver is built ONCE from the module's config and injected into + both tools. Tool constructors no longer accept config โ€” the resolver IS + the config surface. + + The hook resolver is NOT fetched here; each tool fetches it lazily at + first execute() because tools mount before hooks (kernel phase order is + orchestrator โ†’ context โ†’ providers โ†’ tools โ†’ hooks โ€” CONTRACTS.md ยงModule + Lifecycle Methods). Using on_session_ready() here would force cross-callback + instance references (multi-session anti-pattern), so lazy fetch is the + correct and intentional design. + """ + from context_intelligence.tool_resolver import ToolConfigResolver + + from .blob_read_tool import BlobReadTool + from .graph_query_tool import GraphQueryTool + + resolver = ToolConfigResolver(config or {}, coordinator) # built ONCE + gq = GraphQueryTool(coordinator, resolver) + br = BlobReadTool(coordinator, resolver) + await coordinator.mount("tools", gq, name=gq.name) # "graph_query" + await coordinator.mount("tools", br, name=br.name) # "blob_read" + return None # kernel ignores non-callable returns; resolver is pure โ†’ no cleanup diff --git a/modules/tool-blob-read/amplifier_module_tool_blob_read/blob_read_tool.py b/modules/tool-context-intelligence-query/amplifier_module_tool_context_intelligence_query/blob_read_tool.py similarity index 92% rename from modules/tool-blob-read/amplifier_module_tool_blob_read/blob_read_tool.py rename to modules/tool-context-intelligence-query/amplifier_module_tool_context_intelligence_query/blob_read_tool.py index 974b99c..9572684 100644 --- a/modules/tool-blob-read/amplifier_module_tool_blob_read/blob_read_tool.py +++ b/modules/tool-context-intelligence-query/amplifier_module_tool_context_intelligence_query/blob_read_tool.py @@ -4,10 +4,13 @@ ``resolve_query_endpoint`` (same as GraphQueryTool โ€” parity guaranteed by the shared helper): - 1. Explicit read-config (``read_destinations:`` in mount config, if set). + 1. Explicit read-config (``sources:`` in mount config, if set). 2. Upload destinations from ``context_intelligence.hook_config_resolver`` capability (fixes the destinations-only config bug). 3. ``AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL`` env var (canonical last-resort). + +The ``ToolConfigResolver`` is injected at construction time by ``mount()`` +(one shared instance for both CI read tools โ€” single config namespace). """ from __future__ import annotations @@ -18,6 +21,7 @@ from typing import Any from amplifier_core import ToolResult + from context_intelligence.client import AsyncCIClient from context_intelligence.tool_resolver import ToolConfigResolver, resolve_query_endpoint @@ -33,11 +37,10 @@ def _sanitize_path_component(s: str) -> str: class BlobReadTool: """Tool that fetches a ci-blob:// URI from the server and writes it to disk.""" - def __init__(self, coordinator: Any, config: dict[str, Any] | None = None) -> None: + def __init__(self, coordinator: Any, resolver: ToolConfigResolver | None = None) -> None: self._coordinator = coordinator - self._config = config or {} + self._tool_resolver = resolver or ToolConfigResolver({}, coordinator) self._hook_resolver: Any | None = None - self._tool_resolver = ToolConfigResolver(self._config, coordinator) @property def name(self) -> str: diff --git a/modules/tool-graph-query/amplifier_module_tool_graph_query/graph_query_tool.py b/modules/tool-context-intelligence-query/amplifier_module_tool_context_intelligence_query/graph_query_tool.py similarity index 93% rename from modules/tool-graph-query/amplifier_module_tool_graph_query/graph_query_tool.py rename to modules/tool-context-intelligence-query/amplifier_module_tool_context_intelligence_query/graph_query_tool.py index 8eb1579..2016f38 100644 --- a/modules/tool-graph-query/amplifier_module_tool_graph_query/graph_query_tool.py +++ b/modules/tool-context-intelligence-query/amplifier_module_tool_context_intelligence_query/graph_query_tool.py @@ -3,13 +3,16 @@ Implements the Amplifier Tool protocol. Configuration is resolved via the three-tier fallback chain in ``resolve_query_endpoint``: - 1. Explicit read-config (``read_destinations:`` in mount config, if set). + 1. Explicit read-config (``sources:`` in mount config, if set). 2. Upload destinations from ``context_intelligence.hook_config_resolver`` capability (fixes the destinations-only config bug). 3. ``AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL`` env var (canonical last-resort). The hook resolver is fetched lazily at first ``execute()`` call so that late mount order is handled correctly (tools mount before hooks). + +The ``ToolConfigResolver`` is injected at construction time by ``mount()`` +(one shared instance for both CI read tools โ€” single config namespace). """ from __future__ import annotations @@ -30,11 +33,10 @@ class GraphQueryTool: execute() time, consulting the hook's upload destinations as a fallback. """ - def __init__(self, coordinator: Any, config: dict[str, Any] | None = None) -> None: + def __init__(self, coordinator: Any, resolver: ToolConfigResolver | None = None) -> None: self._coordinator = coordinator - self._config = config or {} + self._tool_resolver = resolver or ToolConfigResolver({}, coordinator) self._hook_resolver: Any | None = None - self._tool_resolver = ToolConfigResolver(self._config, coordinator) @property def name(self) -> str: diff --git a/modules/tool-blob-read/pyproject.toml b/modules/tool-context-intelligence-query/pyproject.toml similarity index 73% rename from modules/tool-blob-read/pyproject.toml rename to modules/tool-context-intelligence-query/pyproject.toml index c6e935f..2aeb2bb 100644 --- a/modules/tool-blob-read/pyproject.toml +++ b/modules/tool-context-intelligence-query/pyproject.toml @@ -1,7 +1,7 @@ [project] -name = "amplifier-module-tool-blob-read" +name = "amplifier-module-tool-context-intelligence-query" version = "0.1.0" -description = "Blob read tool โ€” reads binary/text blobs from the context-intelligence server" +description = "CI read tools โ€” graph_query (Cypher) and blob_read from the context-intelligence server" requires-python = ">=3.11" license = "MIT" @@ -12,7 +12,7 @@ dependencies = [ ] [project.entry-points."amplifier.modules"] -tool-blob-read = "amplifier_module_tool_blob_read:mount" +tool-context-intelligence-query = "amplifier_module_tool_context_intelligence_query:mount" [build-system] requires = ["hatchling"] @@ -22,7 +22,7 @@ build-backend = "hatchling.build" package = true [tool.hatch.build.targets.wheel] -packages = ["amplifier_module_tool_blob_read"] +packages = ["amplifier_module_tool_context_intelligence_query"] [tool.hatch.metadata] # Required to build a wheel that carries a PEP 508 direct-reference (git+https) dependency. @@ -46,6 +46,7 @@ pythonVersion = "3.11" typeCheckingMode = "basic" venvPath = "." venv = ".venv" +extraPaths = ["../.."] [tool.ruff] target-version = "py311" diff --git a/modules/tool-blob-read/tests/__init__.py b/modules/tool-context-intelligence-query/tests/__init__.py similarity index 100% rename from modules/tool-blob-read/tests/__init__.py rename to modules/tool-context-intelligence-query/tests/__init__.py diff --git a/modules/tool-blob-read/tests/test_blob_read_tool.py b/modules/tool-context-intelligence-query/tests/test_blob_read_tool.py similarity index 74% rename from modules/tool-blob-read/tests/test_blob_read_tool.py rename to modules/tool-context-intelligence-query/tests/test_blob_read_tool.py index 29b8b66..7a27146 100644 --- a/modules/tool-blob-read/tests/test_blob_read_tool.py +++ b/modules/tool-context-intelligence-query/tests/test_blob_read_tool.py @@ -1,7 +1,8 @@ -"""Tests for BlobReadTool implementation. +"""Tests for BlobReadTool โ€” ported from tool-blob-read, updated for merged module. -All tests mock ``amplifier_module_tool_blob_read.blob_read_tool.AsyncCIClient`` -so HTTP transport is never exercised in unit tests. +Constructor change: BlobReadTool(coordinator, resolver=None). +Tests that previously passed config= now inject a ToolConfigResolver directly. +Patch path updated to amplifier_module_tool_context_intelligence_query.blob_read_tool. """ from __future__ import annotations @@ -20,7 +21,7 @@ from amplifier_core import ToolResult # --------------------------------------------------------------------------- -# Module-level helper functions (NO conftest.py, NO pytest fixtures) +# Module-level helper functions # --------------------------------------------------------------------------- @@ -32,8 +33,8 @@ def _make_coordinator(resolver: Any) -> MagicMock: return coordinator -def _make_resolver(server_url: str | None, api_key: str | None = None) -> MagicMock: - """Return a MagicMock resolver with context_intelligence_server_url set. +def _make_hook_resolver(server_url: str | None, api_key: str | None = None) -> MagicMock: + """Return a MagicMock hook resolver (returned by get_capability). api_key defaults to None so tests that don't exercise auth get a clean mock. Also sets destinations so _first_destination() can iterate it safely. @@ -51,6 +52,15 @@ def _make_resolver(server_url: str | None, api_key: str | None = None) -> MagicM return resolver +def _make_tool_resolver(config: dict = None) -> Any: + """Build a real ToolConfigResolver from config for injection.""" + from context_intelligence.tool_resolver import ToolConfigResolver + + coord = MagicMock() + coord.config = {} + return ToolConfigResolver(config or {}, coord) + + @contextmanager def _patch_async_client( fetch_blob_return: Any = None, @@ -65,7 +75,7 @@ def _patch_async_client( mock_instance.fetch_blob = AsyncMock(return_value=fetch_blob_return) mock_cls = MagicMock(return_value=mock_instance) with patch( - "amplifier_module_tool_blob_read.blob_read_tool.AsyncCIClient", + "amplifier_module_tool_context_intelligence_query.blob_read_tool.AsyncCIClient", mock_cls, ): yield mock_cls, mock_instance @@ -95,44 +105,44 @@ class TestBlobReadToolProtocol: """Tool protocol surface: name, description, schema, execute return type.""" def test_name_is_blob_read(self) -> None: - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool tool = BlobReadTool(_make_coordinator(None)) assert tool.name == "blob_read" def test_description_mentions_ci_blob_scheme(self) -> None: - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool tool = BlobReadTool(_make_coordinator(None)) assert "ci-blob://" in tool.description def test_description_mentions_file_path(self) -> None: - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool tool = BlobReadTool(_make_coordinator(None)) assert "file path" in tool.description.lower() assert "disk path" not in tool.description.lower() def test_schema_type_is_object(self) -> None: - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool tool = BlobReadTool(_make_coordinator(None)) assert tool.input_schema["type"] == "object" def test_schema_has_uri_required(self) -> None: - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool tool = BlobReadTool(_make_coordinator(None)) assert "uri" in tool.input_schema["required"] def test_schema_uri_is_string(self) -> None: - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool tool = BlobReadTool(_make_coordinator(None)) assert tool.input_schema["properties"]["uri"]["type"] == "string" async def test_execute_returns_tool_result(self) -> None: - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool tool = BlobReadTool(_make_coordinator(None)) result = await tool.execute({"uri": "ci-blob://session/key"}) @@ -148,7 +158,7 @@ class TestLazyCapabilityResolution: """execute() must resolve the config capability lazily and cache it.""" async def test_capability_not_found_returns_configuration_error(self) -> None: - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool # get_capability returns None โ†’ capability not registered tool = BlobReadTool(_make_coordinator(None)) @@ -163,10 +173,10 @@ async def test_capability_not_found_returns_configuration_error(self) -> None: assert "not configured" in result.error["message"].lower() async def test_server_url_none_returns_configuration_error_with_url(self) -> None: - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool - resolver = _make_resolver(None) - tool = BlobReadTool(_make_coordinator(resolver)) + hook_resolver = _make_hook_resolver(None) + tool = BlobReadTool(_make_coordinator(hook_resolver)) # Clear CI env vars so tier-3 fallback does not accidentally succeed clean = {k: "" for k in os.environ if k.startswith("AMPLIFIER_CONTEXT_INTELLIGENCE_")} with patch.dict(os.environ, clean): @@ -178,10 +188,10 @@ async def test_server_url_none_returns_configuration_error_with_url(self) -> Non assert "url" in result.error["message"].lower() async def test_server_url_empty_returns_configuration_error(self) -> None: - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool - resolver = _make_resolver("") - tool = BlobReadTool(_make_coordinator(resolver)) + hook_resolver = _make_hook_resolver("") + tool = BlobReadTool(_make_coordinator(hook_resolver)) # Clear CI env vars so tier-3 fallback does not accidentally succeed clean = {k: "" for k in os.environ if k.startswith("AMPLIFIER_CONTEXT_INTELLIGENCE_")} with patch.dict(os.environ, clean): @@ -193,10 +203,10 @@ async def test_server_url_empty_returns_configuration_error(self) -> None: async def test_resolver_cached_after_first_lookup(self) -> None: """get_capability should be called exactly once across two execute() calls.""" - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool - resolver = _make_resolver("http://localhost:8080") - coordinator = _make_coordinator(resolver) + hook_resolver = _make_hook_resolver("http://localhost:8080") + coordinator = _make_coordinator(hook_resolver) tool = BlobReadTool(coordinator) with _patch_async_client(fetch_blob_return={"data": "first"}): @@ -215,10 +225,10 @@ class TestURIParsing: """execute() must validate and parse ci-blob:// URIs before fetching.""" async def test_missing_scheme_returns_uri_error(self) -> None: - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool - resolver = _make_resolver("http://localhost:8080") - tool = BlobReadTool(_make_coordinator(resolver)) + hook_resolver = _make_hook_resolver("http://localhost:8080") + tool = BlobReadTool(_make_coordinator(hook_resolver)) # No "ci-blob://" prefix at all result = await tool.execute({"uri": "session/key"}) @@ -228,10 +238,10 @@ async def test_missing_scheme_returns_uri_error(self) -> None: assert "ci-blob://" in result.error["message"] async def test_no_slash_after_scheme_returns_uri_error(self) -> None: - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool - resolver = _make_resolver("http://localhost:8080") - tool = BlobReadTool(_make_coordinator(resolver)) + hook_resolver = _make_hook_resolver("http://localhost:8080") + tool = BlobReadTool(_make_coordinator(hook_resolver)) # Scheme present but no "/" separating session_id from key result = await tool.execute({"uri": "ci-blob://sessiononly"}) @@ -242,10 +252,10 @@ async def test_no_slash_after_scheme_returns_uri_error(self) -> None: async def test_valid_uri_extracts_session_and_key(self) -> None: """A well-formed URI must call fetch_blob with correct session_id and key.""" - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool - resolver = _make_resolver("http://localhost:8080") - tool = BlobReadTool(_make_coordinator(resolver)) + hook_resolver = _make_hook_resolver("http://localhost:8080") + tool = BlobReadTool(_make_coordinator(hook_resolver)) with _patch_async_client(fetch_blob_return={"ok": True}) as (_, mock_instance): await tool.execute({"uri": "ci-blob://my-session/my-key"}) @@ -263,10 +273,10 @@ class TestPathSanitization: async def test_slashes_sanitized(self) -> None: """Slashes in the key must not create unexpected subdirectory depth.""" - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool - resolver = _make_resolver("http://localhost:8080") - tool = BlobReadTool(_make_coordinator(resolver)) + hook_resolver = _make_hook_resolver("http://localhost:8080") + tool = BlobReadTool(_make_coordinator(hook_resolver)) with _patch_async_client(fetch_blob_return={"data": "test"}): result = await tool.execute({"uri": "ci-blob://my-session/path/with/slashes"}) @@ -279,10 +289,10 @@ async def test_slashes_sanitized(self) -> None: async def test_special_chars_sanitized(self) -> None: """Path traversal sequences in the key must be neutralized in the output path.""" - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool - resolver = _make_resolver("http://localhost:8080") - tool = BlobReadTool(_make_coordinator(resolver)) + hook_resolver = _make_hook_resolver("http://localhost:8080") + tool = BlobReadTool(_make_coordinator(hook_resolver)) with _patch_async_client(fetch_blob_return={"data": "test"}): result = await tool.execute({"uri": "ci-blob://my-session/../../etc/passwd"}) @@ -294,10 +304,10 @@ async def test_special_chars_sanitized(self) -> None: async def test_path_traversal_neutralized(self) -> None: """Output path must always stay under /tmp/ci-blobs/ even with traversal key.""" - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool - resolver = _make_resolver("http://localhost:8080") - tool = BlobReadTool(_make_coordinator(resolver)) + hook_resolver = _make_hook_resolver("http://localhost:8080") + tool = BlobReadTool(_make_coordinator(hook_resolver)) with _patch_async_client(fetch_blob_return={"data": "test"}): result = await tool.execute({"uri": "ci-blob://my-session/../../etc/passwd"}) @@ -321,11 +331,11 @@ class TestBlobReadSuccess: async def test_successful_fetch_writes_file_and_returns_path(self) -> None: """Dict blob must be written as json.dumps(data); output is the file path.""" - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool blob_data = {"session": "test", "data": [1, 2, 3]} - resolver = _make_resolver("http://localhost:8080") - tool = BlobReadTool(_make_coordinator(resolver)) + hook_resolver = _make_hook_resolver("http://localhost:8080") + tool = BlobReadTool(_make_coordinator(hook_resolver)) with _patch_async_client(fetch_blob_return=blob_data): result = await tool.execute({"uri": "ci-blob://my-session/my-key"}) @@ -338,10 +348,10 @@ async def test_successful_fetch_writes_file_and_returns_path(self) -> None: async def test_output_path_structure(self) -> None: """Parent directory name == session_id, filename == key.json.""" - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool - resolver = _make_resolver("http://localhost:8080") - tool = BlobReadTool(_make_coordinator(resolver)) + hook_resolver = _make_hook_resolver("http://localhost:8080") + tool = BlobReadTool(_make_coordinator(hook_resolver)) with _patch_async_client(fetch_blob_return={"ok": True}): result = await tool.execute({"uri": "ci-blob://my-session/my-key"}) @@ -354,10 +364,10 @@ async def test_output_path_structure(self) -> None: async def test_string_blob_written_directly(self) -> None: """String blob must be written as raw text, NOT wrapped in json.dumps.""" - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool - resolver = _make_resolver("http://localhost:8080") - tool = BlobReadTool(_make_coordinator(resolver)) + hook_resolver = _make_hook_resolver("http://localhost:8080") + tool = BlobReadTool(_make_coordinator(hook_resolver)) raw_string = "hello world, this is raw text" @@ -381,10 +391,10 @@ class TestBlobReadErrors: """execute() maps fetch_blob returning None to a typed http_error.""" async def test_fetch_blob_none_returns_http_error(self) -> None: - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool - resolver = _make_resolver("http://localhost:8080") - tool = BlobReadTool(_make_coordinator(resolver)) + hook_resolver = _make_hook_resolver("http://localhost:8080") + tool = BlobReadTool(_make_coordinator(hook_resolver)) with _patch_async_client(fetch_blob_return=None): result = await tool.execute({"uri": "ci-blob://my-session/my-key"}) @@ -404,10 +414,10 @@ class TestAuthHeader: async def test_api_key_passed_to_async_ci_client(self) -> None: """When api_key is set the AsyncCIClient must be constructed with it.""" - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool - resolver = _make_resolver("http://localhost:8080", api_key="my-secret") - tool = BlobReadTool(_make_coordinator(resolver)) + hook_resolver = _make_hook_resolver("http://localhost:8080", api_key="my-secret") + tool = BlobReadTool(_make_coordinator(hook_resolver)) with _patch_async_client(fetch_blob_return={"ok": True}) as (mock_cls, _): await tool.execute({"uri": "ci-blob://my-session/my-key"}) @@ -416,10 +426,10 @@ async def test_api_key_passed_to_async_ci_client(self) -> None: async def test_none_api_key_passes_empty_string(self) -> None: """When api_key is None the AsyncCIClient must receive an empty string.""" - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool - resolver = _make_resolver("http://localhost:8080", api_key=None) - tool = BlobReadTool(_make_coordinator(resolver)) + hook_resolver = _make_hook_resolver("http://localhost:8080", api_key=None) + tool = BlobReadTool(_make_coordinator(hook_resolver)) with _patch_async_client(fetch_blob_return={"ok": True}) as (mock_cls, _): await tool.execute({"uri": "ci-blob://my-session/my-key"}) @@ -444,6 +454,15 @@ def _make_dest_br(url: str, api_key: str) -> SimpleNamespace: return SimpleNamespace(name="default", url=url, api_key=api_key) +def _tool_resolver_br(config: dict = None) -> Any: + """Build a ToolConfigResolver for blob-read config-fallback tests.""" + from context_intelligence.tool_resolver import ToolConfigResolver + + coord = MagicMock() + coord.config = {} + return ToolConfigResolver(config or {}, coord) + + # --------------------------------------------------------------------------- # TestBlobReadConfigFallback โ€” ยง7 case #8 parity tests # --------------------------------------------------------------------------- @@ -455,21 +474,22 @@ class TestBlobReadConfigFallback: Re-runs cases #1, #2, #5, #6 against BlobReadTool to prove identical resolution. """ - # Case #8/#1 โ€” read_destinations wins over destination + # Case #8/#1 โ€” sources wins over destination async def test_read_config_wins_over_destination(self) -> None: - """BlobReadTool case #8/#1: explicit read_destinations wins over hook destinations.""" - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + """BlobReadTool case #8/#1: explicit sources wins over hook destinations.""" + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool hook_resolver = _make_hook_resolver_br( destinations={"default": _make_dest_br("http://upload.example.com", "upload-key")} ) coordinator = _make_coordinator(hook_resolver) config = { - "read_destinations": { + "sources": { "default": {"url": "http://read.example.com", "api_key": "read-key"}, } } - tool = BlobReadTool(coordinator, config) + resolver = _tool_resolver_br(config) + tool = BlobReadTool(coordinator, resolver) with _patch_async_client(fetch_blob_return={"ok": True}) as (mock_cls, _): result = await tool.execute({"uri": "ci-blob://my-session/my-key"}) @@ -481,14 +501,15 @@ async def test_read_config_wins_over_destination(self) -> None: # Case #8/#2 โ€” destinations-only falls through to tier 2 async def test_destinations_only_falls_through_to_tier2(self) -> None: - """BlobReadTool case #8/#2: no read_destinations โ†’ uses hook destination.""" - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + """BlobReadTool case #8/#2: no sources key โ†’ uses hook destination.""" + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool hook_resolver = _make_hook_resolver_br( destinations={"default": _make_dest_br("http://dest.example.com", "dest-key")} ) coordinator = _make_coordinator(hook_resolver) - tool = BlobReadTool(coordinator, config={}) + resolver = _tool_resolver_br({}) + tool = BlobReadTool(coordinator, resolver) with _patch_async_client(fetch_blob_return={"ok": True}) as (mock_cls, _): result = await tool.execute({"uri": "ci-blob://my-session/my-key"}) @@ -501,11 +522,12 @@ async def test_destinations_only_falls_through_to_tier2(self) -> None: # Case #8/#5 โ€” env hit async def test_env_hit(self) -> None: """BlobReadTool case #8/#5: canonical env vars work as tier-3 fallback.""" - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool hook_resolver = _make_hook_resolver_br(destinations={}) coordinator = _make_coordinator(hook_resolver) - tool = BlobReadTool(coordinator, config={}) + resolver = _tool_resolver_br({}) + tool = BlobReadTool(coordinator, resolver) env_patch = { "AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL": "http://env.example.com", @@ -525,13 +547,14 @@ async def test_env_hit(self) -> None: # Regression: env is below hook destination (tier 2 beats tier 3) async def test_env_does_not_override_hook_destination(self) -> None: """BlobReadTool regression: canonical env + hook destination โ†’ destination wins.""" - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool hook_resolver = _make_hook_resolver_br( destinations={"default": _make_dest_br("http://dest.example.com", "dest-key")} ) coordinator = _make_coordinator(hook_resolver) - tool = BlobReadTool(coordinator, config={}) + resolver = _tool_resolver_br({}) + tool = BlobReadTool(coordinator, resolver) # Canonical env set โ€” must NOT override the hook destination env_patch = { @@ -553,11 +576,12 @@ async def test_env_does_not_override_hook_destination(self) -> None: # Case #8/#6 โ€” all miss โ†’ configuration_error async def test_all_miss_returns_configuration_error(self) -> None: """BlobReadTool case #8/#6: no config, no destinations, no env โ†’ configuration_error.""" - from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool hook_resolver = _make_hook_resolver_br(destinations={}) coordinator = _make_coordinator(hook_resolver) - tool = BlobReadTool(coordinator, config={}) + resolver = _tool_resolver_br({}) + tool = BlobReadTool(coordinator, resolver) # Exclude ALL CI env vars (including canonical SERVER_URL / API_KEY) clean_env = { diff --git a/modules/tool-graph-query/tests/test_graph_query_tool.py b/modules/tool-context-intelligence-query/tests/test_graph_query_tool.py similarity index 61% rename from modules/tool-graph-query/tests/test_graph_query_tool.py rename to modules/tool-context-intelligence-query/tests/test_graph_query_tool.py index c7908b2..c7af25c 100644 --- a/modules/tool-graph-query/tests/test_graph_query_tool.py +++ b/modules/tool-context-intelligence-query/tests/test_graph_query_tool.py @@ -1,4 +1,9 @@ -"""Tests for GraphQueryTool โ€” migrated to AsyncCIClient (Task 10).""" +"""Tests for GraphQueryTool โ€” ported from tool-graph-query, updated for merged module. + +Constructor change: GraphQueryTool(coordinator, resolver=None). +Tests that previously passed config= now inject a ToolConfigResolver directly. +Patch path updated to amplifier_module_tool_context_intelligence_query.graph_query_tool. +""" from __future__ import annotations @@ -20,11 +25,12 @@ def _make_coordinator(resolver: Any = None) -> MagicMock: return coordinator -def _make_resolver( +def _make_hook_resolver( server_url: str | None = "http://localhost:8080", workspace: str = "test-workspace", api_key: str | None = "test-api-key", ) -> MagicMock: + """Create a hook resolver mock (returned by get_capability).""" resolver = MagicMock() resolver.context_intelligence_server_url = server_url resolver.workspace = workspace @@ -47,6 +53,13 @@ def _make_mock_async_ci_client(return_value: Any = None): return mock_instance, mock_cls +def _make_tool_resolver(config: dict) -> Any: + """Build a real ToolConfigResolver from a config dict (for injection).""" + from context_intelligence.tool_resolver import ToolConfigResolver + + return ToolConfigResolver(config, MagicMock()) + + # --------------------------------------------------------------------------- # TestGraphQueryToolProtocol # --------------------------------------------------------------------------- @@ -56,39 +69,39 @@ class TestGraphQueryToolProtocol: """Tool protocol surface tests.""" def test_name_is_graph_query(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - tool = GraphQueryTool(coordinator=_make_coordinator()) + tool = GraphQueryTool(_make_coordinator()) assert tool.name == "graph_query" def test_description_mentions_cypher(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - tool = GraphQueryTool(coordinator=_make_coordinator()) + tool = GraphQueryTool(_make_coordinator()) assert "Cypher" in tool.description def test_description_mentions_context_intelligence(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - tool = GraphQueryTool(coordinator=_make_coordinator()) + tool = GraphQueryTool(_make_coordinator()) assert "context-intelligence" in tool.description def test_input_schema_returns_object_type(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - tool = GraphQueryTool(coordinator=_make_coordinator()) + tool = GraphQueryTool(_make_coordinator()) assert tool.input_schema["type"] == "object" def test_input_schema_has_query_as_required(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - tool = GraphQueryTool(coordinator=_make_coordinator()) + tool = GraphQueryTool(_make_coordinator()) assert "query" in tool.input_schema["required"] def test_input_schema_has_optional_params_and_workspace(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - tool = GraphQueryTool(coordinator=_make_coordinator()) + tool = GraphQueryTool(_make_coordinator()) props = tool.input_schema["properties"] assert "params" in props assert "workspace" in props @@ -99,14 +112,17 @@ def test_input_schema_has_optional_params_and_workspace(self) -> None: async def test_execute_returns_tool_result(self) -> None: from amplifier_core.models import ToolResult - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - resolver = _make_resolver() - coordinator = _make_coordinator(resolver=resolver) - tool = GraphQueryTool(coordinator=coordinator) + hook_resolver = _make_hook_resolver() + coordinator = _make_coordinator(resolver=hook_resolver) + tool = GraphQueryTool(coordinator) _, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): result = await tool.execute({"query": "MATCH (n) RETURN n LIMIT 1"}) assert isinstance(result, ToolResult) @@ -121,10 +137,10 @@ class TestLazyCapabilityResolution: """Lazy resolver lookup and caching behaviour.""" async def test_capability_not_found_returns_configuration_error(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool coordinator = _make_coordinator(resolver=None) - tool = GraphQueryTool(coordinator=coordinator) + tool = GraphQueryTool(coordinator) # Clear all CI env vars so tier-3 fallback does not accidentally succeed clean = {k: "" for k in os.environ if k.startswith("AMPLIFIER_CONTEXT_INTELLIGENCE_")} with patch.dict(os.environ, clean): @@ -135,11 +151,11 @@ async def test_capability_not_found_returns_configuration_error(self) -> None: assert result.error["type"] == "configuration_error" async def test_server_url_none_returns_configuration_error(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - resolver = _make_resolver(server_url=None) - coordinator = _make_coordinator(resolver=resolver) - tool = GraphQueryTool(coordinator=coordinator) + hook_resolver = _make_hook_resolver(server_url=None) + coordinator = _make_coordinator(resolver=hook_resolver) + tool = GraphQueryTool(coordinator) # Clear all CI env vars so tier-3 fallback does not accidentally succeed clean = {k: "" for k in os.environ if k.startswith("AMPLIFIER_CONTEXT_INTELLIGENCE_")} with patch.dict(os.environ, clean): @@ -150,14 +166,17 @@ async def test_server_url_none_returns_configuration_error(self) -> None: assert result.error["type"] == "configuration_error" async def test_resolver_cached_after_first_lookup(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - resolver = _make_resolver() - coordinator = _make_coordinator(resolver=resolver) - tool = GraphQueryTool(coordinator=coordinator) + hook_resolver = _make_hook_resolver() + coordinator = _make_coordinator(resolver=hook_resolver) + tool = GraphQueryTool(coordinator) _, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): await tool.execute({"query": "MATCH (n) RETURN n LIMIT 1"}) await tool.execute({"query": "MATCH (n) RETURN n LIMIT 2"}) @@ -167,14 +186,17 @@ async def test_resolver_cached_after_first_lookup(self) -> None: ) async def test_configured_resolver_succeeds(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - resolver = _make_resolver() - coordinator = _make_coordinator(resolver=resolver) - tool = GraphQueryTool(coordinator=coordinator) + hook_resolver = _make_hook_resolver() + coordinator = _make_coordinator(resolver=hook_resolver) + tool = GraphQueryTool(coordinator) _, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): result = await tool.execute({"query": "MATCH (n) RETURN n"}) assert result.success is True @@ -189,14 +211,17 @@ class TestGraphQuery: """AsyncCIClient construction and delegation tests.""" async def test_client_constructed_with_server_url_and_api_key(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - resolver = _make_resolver(server_url="http://ci-server:9000", api_key="my-key") - coordinator = _make_coordinator(resolver=resolver) - tool = GraphQueryTool(coordinator=coordinator) + hook_resolver = _make_hook_resolver(server_url="http://ci-server:9000", api_key="my-key") + coordinator = _make_coordinator(resolver=hook_resolver) + tool = GraphQueryTool(coordinator) _, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): await tool.execute({"query": "MATCH (n) RETURN n"}) mock_cls.assert_called_once() @@ -205,14 +230,17 @@ async def test_client_constructed_with_server_url_and_api_key(self) -> None: assert call_kwargs.get("api_key") == "my-key" async def test_workspace_injected_into_cypher_call(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - resolver = _make_resolver(workspace="my-workspace") - coordinator = _make_coordinator(resolver=resolver) - tool = GraphQueryTool(coordinator=coordinator) + hook_resolver = _make_hook_resolver(workspace="my-workspace") + coordinator = _make_coordinator(resolver=hook_resolver) + tool = GraphQueryTool(coordinator) mock_instance, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): await tool.execute({"query": "MATCH (n) RETURN n"}) cypher_args = mock_instance.cypher.call_args @@ -222,15 +250,18 @@ async def test_workspace_injected_into_cypher_call(self) -> None: assert "my-workspace" in all_args async def test_result_forwarded_from_cypher_call(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - resolver = _make_resolver() - coordinator = _make_coordinator(resolver=resolver) - tool = GraphQueryTool(coordinator=coordinator) + hook_resolver = _make_hook_resolver() + coordinator = _make_coordinator(resolver=hook_resolver) + tool = GraphQueryTool(coordinator) expected = [{"n": {"id": "session-1"}}] mock_instance, mock_cls = _make_mock_async_ci_client(return_value=expected) - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): result = await tool.execute({"query": "MATCH (n:Session) RETURN n LIMIT 10"}) assert result.success is True @@ -246,14 +277,17 @@ class TestGraphQueryWorkspaceOverride: """Per-call workspace override behaviour.""" async def test_per_call_workspace_override(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - resolver = _make_resolver(workspace="default-workspace") - coordinator = _make_coordinator(resolver=resolver) - tool = GraphQueryTool(coordinator=coordinator) + hook_resolver = _make_hook_resolver(workspace="default-workspace") + coordinator = _make_coordinator(resolver=hook_resolver) + tool = GraphQueryTool(coordinator) mock_instance, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): await tool.execute({"query": "MATCH (n) RETURN n", "workspace": "override-workspace"}) cypher_args = mock_instance.cypher.call_args @@ -261,14 +295,17 @@ async def test_per_call_workspace_override(self) -> None: assert "override-workspace" in all_args async def test_wildcard_workspace_override(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - resolver = _make_resolver(workspace="default-workspace") - coordinator = _make_coordinator(resolver=resolver) - tool = GraphQueryTool(coordinator=coordinator) + hook_resolver = _make_hook_resolver(workspace="default-workspace") + coordinator = _make_coordinator(resolver=hook_resolver) + tool = GraphQueryTool(coordinator) mock_instance, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): await tool.execute({"query": "MATCH (n) RETURN n", "workspace": "*"}) cypher_args = mock_instance.cypher.call_args @@ -276,14 +313,17 @@ async def test_wildcard_workspace_override(self) -> None: assert "*" in all_args async def test_default_workspace_from_resolver(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - resolver = _make_resolver(workspace="resolver-workspace") - coordinator = _make_coordinator(resolver=resolver) - tool = GraphQueryTool(coordinator=coordinator) + hook_resolver = _make_hook_resolver(workspace="resolver-workspace") + coordinator = _make_coordinator(resolver=hook_resolver) + tool = GraphQueryTool(coordinator) mock_instance, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): # No workspace key in input โ€” should fall back to resolver's workspace await tool.execute({"query": "MATCH (n) RETURN n"}) @@ -301,29 +341,35 @@ class TestGraphQueryErrors: """Error path tests โ€” AsyncCIClient.cypher() returns [] on HTTP failure (graceful degradation).""" async def test_server_error_returns_success_with_empty_result(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - resolver = _make_resolver() - coordinator = _make_coordinator(resolver=resolver) - tool = GraphQueryTool(coordinator=coordinator) + hook_resolver = _make_hook_resolver() + coordinator = _make_coordinator(resolver=hook_resolver) + tool = GraphQueryTool(coordinator) # AsyncCIClient.cypher() returns [] on HTTP error (graceful degradation) mock_instance, mock_cls = _make_mock_async_ci_client(return_value=[]) - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): result = await tool.execute({"query": "MATCH (n) RETURN n"}) assert result.success is True assert result.output == [] async def test_none_api_key_passed_as_empty_string(self) -> None: - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - resolver = _make_resolver(api_key=None) - coordinator = _make_coordinator(resolver=resolver) - tool = GraphQueryTool(coordinator=coordinator) + hook_resolver = _make_hook_resolver(api_key=None) + coordinator = _make_coordinator(resolver=hook_resolver) + tool = GraphQueryTool(coordinator) _, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): result = await tool.execute({"query": "MATCH (n) RETURN n"}) # Should succeed and pass empty string as api_key @@ -342,14 +388,17 @@ class TestGraphQueryParamsForwarding: async def test_params_are_forwarded_to_async_client_cypher(self) -> None: """params={...} from tool input must be forwarded as a kwarg to cypher().""" - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - resolver = _make_resolver() - coordinator = _make_coordinator(resolver=resolver) - tool = GraphQueryTool(coordinator=coordinator) + hook_resolver = _make_hook_resolver() + coordinator = _make_coordinator(resolver=hook_resolver) + tool = GraphQueryTool(coordinator) mock_instance, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): result = await tool.execute( { "query": "MATCH (s:Session {id: $session_id}) RETURN s", @@ -365,14 +414,17 @@ async def test_params_are_forwarded_to_async_client_cypher(self) -> None: async def test_none_params_sends_empty_dict_to_cypher(self) -> None: """Omitting params from tool input must default to {} at cypher().""" - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - resolver = _make_resolver() - coordinator = _make_coordinator(resolver=resolver) - tool = GraphQueryTool(coordinator=coordinator) + hook_resolver = _make_hook_resolver() + coordinator = _make_coordinator(resolver=hook_resolver) + tool = GraphQueryTool(coordinator) mock_instance, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): await tool.execute({"query": "MATCH (n) RETURN n"}) cypher_call = mock_instance.cypher.call_args @@ -381,14 +433,17 @@ async def test_none_params_sends_empty_dict_to_cypher(self) -> None: async def test_non_dict_params_returns_validation_error(self) -> None: """Passing params as a non-dict must return a validation_error ToolResult.""" - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - resolver = _make_resolver() - coordinator = _make_coordinator(resolver=resolver) - tool = GraphQueryTool(coordinator=coordinator) + hook_resolver = _make_hook_resolver() + coordinator = _make_coordinator(resolver=hook_resolver) + tool = GraphQueryTool(coordinator) _, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): result = await tool.execute({"query": "MATCH (n) RETURN n", "params": "not-a-dict"}) assert result.success is False @@ -401,7 +456,13 @@ async def test_non_dict_params_returns_validation_error(self) -> None: # --------------------------------------------------------------------------- -def _make_hook_resolver(destinations: dict) -> MagicMock: +def _make_dest(url: str, api_key: str) -> SimpleNamespace: + """Quick Destination-like SimpleNamespace for test doubles.""" + name = "default" + return SimpleNamespace(name=name, url=url, api_key=api_key) + + +def _make_hook_resolver_with_dests(destinations: dict) -> MagicMock: """Hook resolver mock with specific destinations dict.""" resolver = MagicMock() resolver.workspace = "test-workspace" @@ -409,10 +470,13 @@ def _make_hook_resolver(destinations: dict) -> MagicMock: return resolver -def _make_dest(url: str, api_key: str) -> SimpleNamespace: - """Quick Destination-like SimpleNamespace for test doubles.""" - name = "default" - return SimpleNamespace(name=name, url=url, api_key=api_key) +def _tool_resolver_with_config(config: dict, coordinator: Any = None) -> Any: + """Build a real ToolConfigResolver from config for injection.""" + from context_intelligence.tool_resolver import ToolConfigResolver + + coord = coordinator or MagicMock() + coord.config = {} + return ToolConfigResolver(config, coord) # --------------------------------------------------------------------------- @@ -427,25 +491,29 @@ class TestConfigFallback: precedence order โ€” the core bug fix and its coherent read-config model. """ - # --- Case #1 / #4: read_destinations wins over hook destination --- + # --- Case #1 / #4: sources wins over hook destination --- async def test_case1_read_config_wins_over_destination(self) -> None: - """Case #1: explicit read_destinations wins over upload destination (tier 1 > tier 2).""" - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + """Case #1: explicit sources wins over upload destination (tier 1 > tier 2).""" + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - dest_resolver = _make_hook_resolver( + dest_resolver = _make_hook_resolver_with_dests( destinations={"default": _make_dest("http://upload.example.com", "upload-key")} ) coordinator = _make_coordinator(resolver=dest_resolver) config = { - "read_destinations": { + "sources": { "default": {"url": "http://read.example.com", "api_key": "read-key"}, } } - tool = GraphQueryTool(coordinator=coordinator, config=config) + resolver = _tool_resolver_with_config(config) + tool = GraphQueryTool(coordinator, resolver) _, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): result = await tool.execute({"query": "MATCH (n) RETURN n"}) assert result.success is True @@ -456,18 +524,22 @@ async def test_case1_read_config_wins_over_destination(self) -> None: # --- Case #2: CORE BUG FIX โ€” destinations-only config succeeds --- async def test_case2_destinations_only_falls_through_to_tier2(self) -> None: - """Case #2: no read_destinations + no legacy scalar โ†’ falls through to hook destinations.""" - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + """Case #2: no sources key + no legacy scalar โ†’ falls through to hook destinations.""" + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - dest_resolver = _make_hook_resolver( + dest_resolver = _make_hook_resolver_with_dests( destinations={"default": _make_dest("http://dest.example.com", "dest-key")} ) coordinator = _make_coordinator(resolver=dest_resolver) - # Tool config is empty โ€” no read_destinations, no legacy scalars - tool = GraphQueryTool(coordinator=coordinator, config={}) + # Tool resolver with empty config โ€” no sources key, no legacy scalars + resolver = _tool_resolver_with_config({}) + tool = GraphQueryTool(coordinator, resolver) _, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): result = await tool.execute({"query": "MATCH (n) RETURN n"}) assert result.success is True @@ -478,22 +550,26 @@ async def test_case2_destinations_only_falls_through_to_tier2(self) -> None: # --- Case #3: per-field independence --- async def test_case3_read_config_url_empty_falls_to_destination_for_url(self) -> None: - """Case #3: read_destinations url="" โ†’ url falls to destination; api_key stays at tier 1.""" - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + """Case #3: sources url="" โ†’ url falls to destination; api_key stays at tier 1.""" + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - dest_resolver = _make_hook_resolver( + dest_resolver = _make_hook_resolver_with_dests( destinations={"default": _make_dest("http://dest.example.com", "dest-key")} ) coordinator = _make_coordinator(resolver=dest_resolver) config = { - "read_destinations": { + "sources": { "default": {"url": "", "api_key": "read-key"}, # url is empty } } - tool = GraphQueryTool(coordinator=coordinator, config=config) + resolver = _tool_resolver_with_config(config) + tool = GraphQueryTool(coordinator, resolver) _, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): result = await tool.execute({"query": "MATCH (n) RETURN n"}) assert result.success is True @@ -506,22 +582,26 @@ async def test_case3_read_config_url_empty_falls_to_destination_for_url(self) -> # --- Case #4: explicit-first precedence assertion --- async def test_case4_explicit_read_config_wins_both_fields(self) -> None: - """Case #4: BOTH url and api_key come from tier 1 when read_destinations is set.""" - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + """Case #4: BOTH url and api_key come from tier 1 when sources is set.""" + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - dest_resolver = _make_hook_resolver( + dest_resolver = _make_hook_resolver_with_dests( destinations={"default": _make_dest("http://upload.example.com", "upload-key")} ) coordinator = _make_coordinator(resolver=dest_resolver) config = { - "read_destinations": { + "sources": { "default": {"url": "http://read.example.com", "api_key": "read-key"}, } } - tool = GraphQueryTool(coordinator=coordinator, config=config) + resolver = _tool_resolver_with_config(config) + tool = GraphQueryTool(coordinator, resolver) _, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): result = await tool.execute({"query": "MATCH (n) RETURN n"}) assert result.success is True @@ -534,11 +614,12 @@ async def test_case4_explicit_read_config_wins_both_fields(self) -> None: async def test_case5_env_hit_when_no_config_or_destinations(self) -> None: """Case #5: canonical env vars work as tier-3 fallback (below hook destination).""" - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - dest_resolver = _make_hook_resolver(destinations={}) # no destinations + dest_resolver = _make_hook_resolver_with_dests(destinations={}) # no destinations coordinator = _make_coordinator(resolver=dest_resolver) - tool = GraphQueryTool(coordinator=coordinator, config={}) + resolver = _tool_resolver_with_config({}) + tool = GraphQueryTool(coordinator, resolver) env_patch = { "AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL": "http://env.example.com", @@ -547,7 +628,10 @@ async def test_case5_env_hit_when_no_config_or_destinations(self) -> None: _, mock_cls = _make_mock_async_ci_client() with ( patch.dict(os.environ, env_patch), - patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls), + patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ), ): result = await tool.execute({"query": "MATCH (n) RETURN n"}) @@ -563,13 +647,14 @@ async def test_case5b_env_does_not_override_hook_destination(self) -> None: Locks in that env (tier 3) never outranks the hook destination (tier 2). """ - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - dest_resolver = _make_hook_resolver( + dest_resolver = _make_hook_resolver_with_dests( destinations={"default": _make_dest("http://dest.example.com", "dest-key")} ) coordinator = _make_coordinator(resolver=dest_resolver) - tool = GraphQueryTool(coordinator=coordinator, config={}) + resolver = _tool_resolver_with_config({}) + tool = GraphQueryTool(coordinator, resolver) # Canonical env set โ€” must NOT override the hook destination env_patch = { @@ -579,7 +664,10 @@ async def test_case5b_env_does_not_override_hook_destination(self) -> None: _, mock_cls = _make_mock_async_ci_client() with ( patch.dict(os.environ, env_patch), - patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls), + patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ), ): result = await tool.execute({"query": "MATCH (n) RETURN n"}) @@ -592,12 +680,13 @@ async def test_case5b_env_does_not_override_hook_destination(self) -> None: # --- Case #6: all miss โ†’ configuration_error --- async def test_case6_all_miss_returns_configuration_error(self) -> None: - """Case #6: no read_destinations, no destinations, no env โ†’ configuration_error.""" - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + """Case #6: no sources key, no destinations, no env โ†’ configuration_error.""" + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - dest_resolver = _make_hook_resolver(destinations={}) + dest_resolver = _make_hook_resolver_with_dests(destinations={}) coordinator = _make_coordinator(resolver=dest_resolver) - tool = GraphQueryTool(coordinator=coordinator, config={}) + resolver = _tool_resolver_with_config({}) + tool = GraphQueryTool(coordinator, resolver) # Exclude ALL CI env vars (including canonical SERVER_URL / API_KEY) clean_env = { @@ -608,7 +697,10 @@ async def test_case6_all_miss_returns_configuration_error(self) -> None: _, mock_cls = _make_mock_async_ci_client() with ( patch.dict(os.environ, clean_env, clear=True), - patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls), + patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ), ): result = await tool.execute({"query": "MATCH (n) RETURN n"}) @@ -619,10 +711,10 @@ async def test_case6_all_miss_returns_configuration_error(self) -> None: # --- Case #7: multi-entry ordering determinism --- async def test_case7_multi_entry_ordering_first_read_entry_wins(self) -> None: - """Case #7: first entry in read_destinations (insertion order) wins.""" - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + """Case #7: first entry in sources (insertion order) wins.""" + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - dest_resolver = _make_hook_resolver( + dest_resolver = _make_hook_resolver_with_dests( destinations={ "d1": SimpleNamespace(name="d1", url="http://d1.example.com", api_key="d1-key"), "d2": SimpleNamespace(name="d2", url="http://d2.example.com", api_key="d2-key"), @@ -630,42 +722,50 @@ async def test_case7_multi_entry_ordering_first_read_entry_wins(self) -> None: ) coordinator = _make_coordinator(resolver=dest_resolver) config = { - "read_destinations": { + "sources": { "alpha": {"url": "http://alpha.example.com", "api_key": "alpha-key"}, "beta": {"url": "http://beta.example.com", "api_key": "beta-key"}, } } - tool = GraphQueryTool(coordinator=coordinator, config=config) + resolver = _tool_resolver_with_config(config) + tool = GraphQueryTool(coordinator, resolver) _, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): result = await tool.execute({"query": "MATCH (n) RETURN n"}) assert result.success is True call_kwargs = mock_cls.call_args.kwargs - # First read_destinations entry ("alpha") wins + # First sources entry ("alpha") wins assert call_kwargs["server_url"] == "http://alpha.example.com" assert call_kwargs["api_key"] == "alpha-key" async def test_case7_second_execute_same_result_deterministic(self) -> None: """Case #7: repeated executes give the same endpoint (deterministic order).""" - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - dest_resolver = _make_hook_resolver( + dest_resolver = _make_hook_resolver_with_dests( destinations={ "d1": SimpleNamespace(name="d1", url="http://d1.example.com", api_key="d1") } ) coordinator = _make_coordinator(resolver=dest_resolver) config = { - "read_destinations": { + "sources": { "alpha": {"url": "http://alpha.example.com", "api_key": "alpha-key"}, } } - tool = GraphQueryTool(coordinator=coordinator, config=config) + resolver = _tool_resolver_with_config(config) + tool = GraphQueryTool(coordinator, resolver) _, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): r1 = await tool.execute({"query": "MATCH (n) RETURN n"}) r2 = await tool.execute({"query": "MATCH (n) RETURN n"}) @@ -682,22 +782,26 @@ async def test_case7_second_execute_same_result_deterministic(self) -> None: # --- Case #9: legacy top-level scalar synthesizes default --- async def test_case9_legacy_scalars_synthesize_read_default_wins_tier1(self) -> None: - """Case #9: legacy context_intelligence_server_url+api_key synthesize read_destinations.""" - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + """Case #9: legacy context_intelligence_server_url+api_key synthesize sources.""" + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - dest_resolver = _make_hook_resolver( + dest_resolver = _make_hook_resolver_with_dests( destinations={"default": _make_dest("http://upload.example.com", "upload-key")} ) coordinator = _make_coordinator(resolver=dest_resolver) - # Legacy scalars in tool config โ€” no read_destinations key + # Legacy scalars in tool config โ€” no sources key config = { "context_intelligence_server_url": "http://legacy.example.com", "context_intelligence_api_key": "legacy-key", } - tool = GraphQueryTool(coordinator=coordinator, config=config) + resolver = _tool_resolver_with_config(config) + tool = GraphQueryTool(coordinator, resolver) _, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): result = await tool.execute({"query": "MATCH (n) RETURN n"}) assert result.success is True @@ -709,10 +813,10 @@ async def test_case9_legacy_scalars_synthesize_read_default_wins_tier1(self) -> # --- Case #10: legacy url-only โ†’ no synthesis, falls through --- async def test_case10_legacy_url_only_no_synthesis_falls_through_to_destination(self) -> None: - """Case #10: legacy url-only (no api_key) โ†’ read_destinations={}, falls to tier 2.""" - from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + """Case #10: legacy url-only (no api_key) โ†’ sources={}, falls to tier 2.""" + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool - dest_resolver = _make_hook_resolver( + dest_resolver = _make_hook_resolver_with_dests( destinations={"default": _make_dest("http://upload.example.com", "upload-key")} ) coordinator = _make_coordinator(resolver=dest_resolver) @@ -721,14 +825,18 @@ async def test_case10_legacy_url_only_no_synthesis_falls_through_to_destination( "context_intelligence_server_url": "http://legacy.example.com", # no context_intelligence_api_key } - tool = GraphQueryTool(coordinator=coordinator, config=config) + resolver = _tool_resolver_with_config(config) + tool = GraphQueryTool(coordinator, resolver) _, mock_cls = _make_mock_async_ci_client() - with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): result = await tool.execute({"query": "MATCH (n) RETURN n"}) assert result.success is True call_kwargs = mock_cls.call_args.kwargs - # No synthesis โ†’ read_destinations={} โ†’ falls through to tier 2 + # No synthesis โ†’ sources={} โ†’ falls through to tier 2 assert call_kwargs["server_url"] == "http://upload.example.com" assert call_kwargs["api_key"] == "upload-key" diff --git a/modules/tool-context-intelligence-query/tests/test_module.py b/modules/tool-context-intelligence-query/tests/test_module.py new file mode 100644 index 0000000..a5a32a8 --- /dev/null +++ b/modules/tool-context-intelligence-query/tests/test_module.py @@ -0,0 +1,519 @@ +"""Module-level contract tests for tool-context-intelligence-query. + +Tests for the merged two-tool module: mount registers both tools from one call, +the ToolConfigResolver is shared (one instance, identical resolution), the lazy +hook lookup stays lazy (not cached at mount time), and malformed/empty destination +inputs fail loud or fall through correctly. +""" + +from __future__ import annotations + +import asyncio +import inspect +import os +from types import SimpleNamespace +from typing import Any +from unittest.mock import AsyncMock, MagicMock, patch + + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + + +def _make_coordinator(hook_resolver: Any = None) -> MagicMock: + """Coordinator whose get_capability returns hook_resolver.""" + coordinator = MagicMock() + coordinator.config = {} + coordinator.get_capability = MagicMock(return_value=hook_resolver) + coordinator.mount = AsyncMock() + return coordinator + + +def _make_dest(url: str, api_key: str) -> SimpleNamespace: + return SimpleNamespace(name="default", url=url, api_key=api_key) + + +def _make_hook_resolver(url: str | None = None, api_key: str | None = None) -> MagicMock: + """Minimal hook resolver mock with a destinations dict.""" + resolver = MagicMock() + resolver.workspace = "test-workspace" + if url: + resolver.destinations = {"default": _make_dest(url, api_key or "")} + else: + resolver.destinations = {} + return resolver + + +def _graph_tool(coordinator: Any, resolver: Any = None) -> Any: + from context_intelligence.tool_resolver import ToolConfigResolver + + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool + + if resolver is None: + resolver = ToolConfigResolver({}, coordinator) + return GraphQueryTool(coordinator, resolver) + + +def _blob_tool(coordinator: Any, resolver: Any = None) -> Any: + from context_intelligence.tool_resolver import ToolConfigResolver + + from amplifier_module_tool_context_intelligence_query.blob_read_tool import BlobReadTool + + if resolver is None: + resolver = ToolConfigResolver({}, coordinator) + return BlobReadTool(coordinator, resolver) + + +# --------------------------------------------------------------------------- +# TestModuleContract +# --------------------------------------------------------------------------- + + +class TestModuleContract: + """Module-level contract (type marker + mount signature).""" + + def test_module_type_is_tool(self) -> None: + from amplifier_module_tool_context_intelligence_query import __amplifier_module_type__ + + assert __amplifier_module_type__ == "tool" + + def test_mount_is_coroutine(self) -> None: + from amplifier_module_tool_context_intelligence_query import mount + + assert inspect.iscoroutinefunction(mount) + + def test_mount_signature_has_coordinator_and_config(self) -> None: + from amplifier_module_tool_context_intelligence_query import mount + + sig = inspect.signature(mount) + params = list(sig.parameters.keys()) + assert params[0] == "coordinator" + assert params[1] == "config" + + +# --------------------------------------------------------------------------- +# TestMountRegistersExactlyTwoTools +# --------------------------------------------------------------------------- + + +class TestMountRegistersExactlyTwoTools: + """mount() must register exactly two tools with distinct names.""" + + async def test_mount_registers_exactly_two_tools(self) -> None: + from amplifier_module_tool_context_intelligence_query import mount + + coordinator = _make_coordinator() + await mount(coordinator, config={}) + + assert coordinator.mount.call_count == 2 + + async def test_both_tool_calls_use_tools_category(self) -> None: + from amplifier_module_tool_context_intelligence_query import mount + + coordinator = _make_coordinator() + await mount(coordinator, config={}) + + for call in coordinator.mount.call_args_list: + assert call.args[0] == "tools" + + async def test_tool_names_are_graph_query_and_blob_read(self) -> None: + from amplifier_module_tool_context_intelligence_query import mount + + coordinator = _make_coordinator() + await mount(coordinator, config={}) + + registered_names = {call.kwargs["name"] for call in coordinator.mount.call_args_list} + assert registered_names == {"graph_query", "blob_read"} + + async def test_mounted_tools_are_protocol_compliant(self) -> None: + from amplifier_module_tool_context_intelligence_query import mount + + coordinator = _make_coordinator() + await mount(coordinator, config={}) + + for call in coordinator.mount.call_args_list: + tool = call.args[1] + assert hasattr(tool, "name") + assert hasattr(tool, "description") + assert hasattr(tool, "input_schema") + assert hasattr(tool, "execute") + assert isinstance(tool.input_schema, dict) + assert inspect.iscoroutinefunction(tool.execute) + + async def test_mount_returns_none(self) -> None: + """mount() returns None โ€” the kernel ignores non-callable returns.""" + from amplifier_module_tool_context_intelligence_query import mount + + coordinator = _make_coordinator() + result = await mount(coordinator, config={}) + assert result is None + + +# --------------------------------------------------------------------------- +# TestSharedResolverInvariant +# --------------------------------------------------------------------------- + + +class TestSharedResolverInvariant: + """The ToolConfigResolver is shared: one instance, identical resolution.""" + + async def test_both_tools_have_same_resolver_instance(self) -> None: + """gq._tool_resolver is br._tool_resolver: same object from mount().""" + from amplifier_module_tool_context_intelligence_query import mount + + coordinator = _make_coordinator() + await mount(coordinator, config={}) + + tools = {call.kwargs["name"]: call.args[1] for call in coordinator.mount.call_args_list} + gq = tools["graph_query"] + br = tools["blob_read"] + assert gq._tool_resolver is br._tool_resolver + + async def test_shared_resolver_consistency_same_url_and_api_key(self) -> None: + """Both tools resolve to the SAME (url, api_key) from sources. + + This is the load-bearing correctness invariant: with a shared resolver, + divergent read-endpoint config is structurally impossible. + """ + from amplifier_module_tool_context_intelligence_query import mount + from context_intelligence.tool_resolver import resolve_query_endpoint + + config = { + "sources": { + "primary": {"url": "http://read.example.com", "api_key": "shared-key"}, + } + } + coordinator = _make_coordinator() + await mount(coordinator, config=config) + + tools = {call.kwargs["name"]: call.args[1] for call in coordinator.mount.call_args_list} + gq = tools["graph_query"] + br = tools["blob_read"] + + # Resolve using the shared resolver (no hook resolver needed for tier-1 hit) + gq_url, gq_key = resolve_query_endpoint(None, gq._tool_resolver) + br_url, br_key = resolve_query_endpoint(None, br._tool_resolver) + + assert gq_url == br_url == "http://read.example.com" + assert gq_key == br_key == "shared-key" + + async def test_concurrent_resolution_is_consistent(self) -> None: + """Execute both tools 'concurrently'; both resolve to the same endpoint. + + ToolConfigResolver.sources is synchronous (no await between + cache-check and cache-set), so under asyncio there is no interleaving. + This test confirms identical results when both tools run concurrently. + """ + from unittest.mock import AsyncMock as AM + + from amplifier_module_tool_context_intelligence_query import mount + + config = { + "sources": { + "primary": {"url": "http://shared.example.com", "api_key": "shared-key"}, + } + } + hook_resolver = _make_hook_resolver(url="http://hook.example.com", api_key="hook-key") + coordinator = _make_coordinator(hook_resolver=hook_resolver) + await mount(coordinator, config=config) + + tools = {call.kwargs["name"]: call.args[1] for call in coordinator.mount.call_args_list} + gq = tools["graph_query"] + br = tools["blob_read"] + + # Mock the AsyncCIClient for both tools + gq_client = MagicMock() + gq_client.cypher = AM(return_value=[]) + br_client = MagicMock() + br_client.fetch_blob = AM(return_value=None) # None โ†’ http_error, but url is resolved + + gq_results = [] + br_results = [] + + with ( + patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + return_value=gq_client, + ) as gq_cls, + patch( + "amplifier_module_tool_context_intelligence_query.blob_read_tool.AsyncCIClient", + return_value=br_client, + ) as br_cls, + ): + gq_task = asyncio.create_task(gq.execute({"query": "MATCH (n) RETURN n"})) + br_task = asyncio.create_task(br.execute({"uri": "ci-blob://s/k"})) + gq_result, br_result = await asyncio.gather(gq_task, br_task) + gq_results.append(gq_cls.call_args) + br_results.append(br_cls.call_args) + + # Both tools must resolve to the shared read-destinations URL (tier 1) + assert gq_results[0] is not None + assert br_results[0] is not None + # AsyncCIClient is always called with keyword args (server_url=, api_key=) + gq_url = gq_results[0].kwargs.get("server_url") + br_url = br_results[0].kwargs.get("server_url") + # Read-destinations (tier 1) wins over hook destination (tier 2) + assert gq_url == "http://shared.example.com" + assert br_url == "http://shared.example.com" + + +# --------------------------------------------------------------------------- +# TestLateMount_TimingInvariant +# --------------------------------------------------------------------------- + + +class TestLateMountTimingInvariant: + """The lazy hook-resolver lookup must NOT be cached at mount() time. + + Catches any regression where the hook capability is fetched eagerly in mount() + rather than lazily in execute() (which would break when the hook mounts later). + """ + + async def test_late_mount_graph_query_resolves_destination_after_hook_registers( + self, + ) -> None: + """Mount with NO hook โ†’ register hook AFTER โ†’ execute() sees the hook's destination.""" + from amplifier_module_tool_context_intelligence_query import mount + + # Step 1: mount with no hook registered + coordinator = _make_coordinator(hook_resolver=None) + await mount(coordinator, config={}) + tools = {call.kwargs["name"]: call.args[1] for call in coordinator.mount.call_args_list} + gq = tools["graph_query"] + + # Confirm hook resolver is None after mount (lazy, not fetched yet) + assert gq._hook_resolver is None + + # Step 2: register the hook resolver AFTER mount + hook_resolver = _make_hook_resolver(url="http://late-hook.example.com", api_key="late-key") + coordinator.get_capability.return_value = hook_resolver + + # Step 3: execute() must now see the late-registered hook destination + mock_client = MagicMock() + mock_client.cypher = AsyncMock(return_value=[]) + mock_cls = MagicMock(return_value=mock_client) + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): + result = await gq.execute({"query": "MATCH (n) RETURN n"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + # Tier 2 (hook destination) resolved because no sources key in config + assert call_kwargs["server_url"] == "http://late-hook.example.com" + assert call_kwargs["api_key"] == "late-key" + + async def test_late_mount_blob_read_resolves_destination_after_hook_registers( + self, + ) -> None: + """BlobReadTool: mount with no hook โ†’ register hook โ†’ execute sees destination.""" + import pathlib + import shutil + + from amplifier_module_tool_context_intelligence_query import mount + + # Cleanup blob dir + blob_dir = pathlib.Path("/tmp/ci-blobs") + if blob_dir.exists(): + shutil.rmtree(blob_dir) + + # Step 1: mount with no hook + coordinator = _make_coordinator(hook_resolver=None) + await mount(coordinator, config={}) + tools = {call.kwargs["name"]: call.args[1] for call in coordinator.mount.call_args_list} + br = tools["blob_read"] + + assert br._hook_resolver is None + + # Step 2: register hook AFTER mount + hook_resolver = _make_hook_resolver(url="http://late-hook.example.com", api_key="late-key") + coordinator.get_capability.return_value = hook_resolver + + # Step 3: execute resolves from the hook destination + mock_client = MagicMock() + mock_client.fetch_blob = AsyncMock(return_value={"ok": True}) + mock_cls = MagicMock(return_value=mock_client) + with patch( + "amplifier_module_tool_context_intelligence_query.blob_read_tool.AsyncCIClient", + mock_cls, + ): + result = await br.execute({"uri": "ci-blob://my-session/my-key"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + assert call_kwargs["server_url"] == "http://late-hook.example.com" + assert call_kwargs["api_key"] == "late-key" + + +# --------------------------------------------------------------------------- +# TestMalformedDestinationInputs +# --------------------------------------------------------------------------- + + +class TestMalformedDestinationInputs: + """Malformed / empty destination inputs must fail loud or fall through correctly.""" + + async def test_empty_sources_list_falls_through(self) -> None: + """sources: [] (a list, not dict) โ€” _first_entry() returns None โ†’ falls to tier 2.""" + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool + from context_intelligence.tool_resolver import ToolConfigResolver + + coord = MagicMock() + coord.config = {} + # sources as a list (malformed โ€” _first_entry guards isinstance(mapping, dict)) + config = {"sources": []} + resolver = ToolConfigResolver(config, coord) + + hook_resolver = _make_hook_resolver( + url="http://fallback.example.com", api_key="fallback-key" + ) + coordinator = _make_coordinator(hook_resolver=hook_resolver) + tool = GraphQueryTool(coordinator, resolver) + + mock_client = MagicMock() + mock_client.cypher = AsyncMock(return_value=[]) + mock_cls = MagicMock(return_value=mock_client) + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): + result = await tool.execute({"query": "MATCH (n) RETURN n"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + # Falls through to tier 2 (hook destination) + assert call_kwargs["server_url"] == "http://fallback.example.com" + + async def test_empty_sources_dict_falls_through(self) -> None: + """sources: {} (empty dict) โ†’ first entry is None โ†’ falls to tier 2.""" + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool + from context_intelligence.tool_resolver import ToolConfigResolver + + coord = MagicMock() + coord.config = {} + config = {"sources": {}} + resolver = ToolConfigResolver(config, coord) + + hook_resolver = _make_hook_resolver( + url="http://fallback.example.com", api_key="fallback-key" + ) + coordinator = _make_coordinator(hook_resolver=hook_resolver) + tool = GraphQueryTool(coordinator, resolver) + + mock_client = MagicMock() + mock_client.cypher = AsyncMock(return_value=[]) + mock_cls = MagicMock(return_value=mock_client) + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): + result = await tool.execute({"query": "MATCH (n) RETURN n"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + assert call_kwargs["server_url"] == "http://fallback.example.com" + + async def test_entry_with_empty_url_falls_through_url_field(self) -> None: + """Entry with url: '' โ†’ url is falsy โ†’ _pick skips it โ†’ tier 2 wins for url.""" + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool + from context_intelligence.tool_resolver import ToolConfigResolver + + coord = MagicMock() + coord.config = {} + config = { + "sources": { + "primary": {"url": "", "api_key": "read-key"}, + } + } + resolver = ToolConfigResolver(config, coord) + + hook_resolver = _make_hook_resolver(url="http://fallback.example.com", api_key="hook-key") + coordinator = _make_coordinator(hook_resolver=hook_resolver) + tool = GraphQueryTool(coordinator, resolver) + + mock_client = MagicMock() + mock_client.cypher = AsyncMock(return_value=[]) + mock_cls = MagicMock(return_value=mock_client) + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): + result = await tool.execute({"query": "MATCH (n) RETURN n"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + # url is empty in tier 1 โ†’ falls through to tier 2 (hook destination) + assert call_kwargs["server_url"] == "http://fallback.example.com" + # api_key stays at tier 1 (non-empty "read-key") + assert call_kwargs["api_key"] == "read-key" + + async def test_all_tiers_miss_returns_loud_configuration_error(self) -> None: + """No config, no destinations, no env โ†’ configuration_error (loud, not silent empty).""" + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool + from context_intelligence.tool_resolver import ToolConfigResolver + + coord = MagicMock() + coord.config = {} + resolver = ToolConfigResolver({}, coord) + + hook_resolver = _make_hook_resolver(url=None) # empty destinations + coordinator = _make_coordinator(hook_resolver=hook_resolver) + tool = GraphQueryTool(coordinator, resolver) + + clean_env = { + k: v + for k, v in os.environ.items() + if not k.startswith("AMPLIFIER_CONTEXT_INTELLIGENCE_") + } + mock_client = MagicMock() + mock_cls = MagicMock(return_value=mock_client) + with ( + patch.dict(os.environ, clean_env, clear=True), + patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ), + ): + result = await tool.execute({"query": "MATCH (n) RETURN n"}) + + assert result.success is False + assert result.error is not None + assert result.error["type"] == "configuration_error" + # Must not have called the client (fails before reaching that point) + mock_cls.assert_not_called() + + async def test_none_sources_treated_as_absent(self) -> None: + """If sources is explicitly None/null โ†’ absent-key semantics (legacy synthesis). + + The ToolConfigResolver treats None as a non-dict โ†’ falls to legacy synthesis. + With no legacy scalars either, result is {} โ†’ falls through. + """ + from amplifier_module_tool_context_intelligence_query.graph_query_tool import GraphQueryTool + from context_intelligence.tool_resolver import ToolConfigResolver + + coord = MagicMock() + coord.config = {} + # sources: null โ€” the sentinel detection in ToolConfigResolver checks + # 'raw is not _sentinel' โ†’ key IS present (None). isinstance(None, dict) is False โ†’ {} + config = {"sources": None} + resolver = ToolConfigResolver(config, coord) + + hook_resolver = _make_hook_resolver(url="http://hook.example.com", api_key="hook-key") + coordinator = _make_coordinator(hook_resolver=hook_resolver) + tool = GraphQueryTool(coordinator, resolver) + + mock_client = MagicMock() + mock_client.cypher = AsyncMock(return_value=[]) + mock_cls = MagicMock(return_value=mock_client) + with patch( + "amplifier_module_tool_context_intelligence_query.graph_query_tool.AsyncCIClient", + mock_cls, + ): + result = await tool.execute({"query": "MATCH (n) RETURN n"}) + + # Nsources โ†’ {} โ†’ falls to tier 2 (hook destination) + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + assert call_kwargs["server_url"] == "http://hook.example.com" diff --git a/modules/tool-blob-read/tests/test_tool_dependencies.py b/modules/tool-context-intelligence-query/tests/test_tool_dependencies.py similarity index 64% rename from modules/tool-blob-read/tests/test_tool_dependencies.py rename to modules/tool-context-intelligence-query/tests/test_tool_dependencies.py index 147bf00..abd543c 100644 --- a/modules/tool-blob-read/tests/test_tool_dependencies.py +++ b/modules/tool-context-intelligence-query/tests/test_tool_dependencies.py @@ -1,15 +1,14 @@ -"""Test that the blob-read tool pyproject.toml declares the bundle dependency in a -form that installs standalone (outside the monorepo). - -The tool imports from the `context_intelligence` package shipped by the parent -bundle. For the tool to install standalone under the Amplifier agent's -`uv pip install --no-sources` policy, the bundle MUST be referenced as a PEP 508 -direct git reference inside [project.dependencies] (which survives --no-sources), -NOT via a [tool.uv.sources] `path = "../.."` entry (which --no-sources strips). - -This guard mirrors hook-context-intelligence/tests/test_hook_dependencies.py so -that every module references the parent bundle uniformly and cannot regress to a -uv path source (the original cause of the uv conflicting-URLs co-install failure). +"""Test that tool-context-intelligence-query pyproject.toml declares the bundle dependency +in a form that installs standalone (outside the monorepo). + +The tools import from the `context_intelligence` package shipped by the parent bundle. +For the module to install standalone under the Amplifier agent's `uv pip install +--no-sources` policy, the bundle MUST be referenced as a PEP 508 direct git reference +inside [project.dependencies] (which survives --no-sources), NOT via a +[tool.uv.sources] `path = "../.."` entry (which --no-sources strips). + +Merged from tool-graph-query and tool-blob-read versions (both were identical except +for module name) โ€” now a single guard for the merged module. """ from __future__ import annotations @@ -37,7 +36,7 @@ def _dep_name(dep: str) -> str: class TestToolDependencies: - """Verify the tool declares the bundle as a standalone-installable dependency.""" + """Verify the module declares the bundle as a standalone-installable dependency.""" def test_bundle_declared_as_direct_git_reference(self) -> None: """The bundle must be a PEP 508 direct git reference in [project.dependencies]. @@ -59,8 +58,6 @@ def test_bundle_is_not_a_uv_path_source(self) -> None: The `path = '../..'` assumption is exactly what breaks standalone install: --no-sources strips [tool.uv.sources], leaving an unresolvable reference. - Two modules referencing the bundle via path while others use a git URL is - what produced uv's "conflicting URLs" abort on a single co-install command. """ data = _load_pyproject() sources: dict = data.get("tool", {}).get("uv", {}).get("sources", {}) @@ -94,3 +91,24 @@ def test_allow_direct_references_enabled(self) -> None: "tool.hatch.metadata.allow-direct-references must be true to build a wheel " f"carrying the direct git reference, got: {allow!r}" ) + + def test_entry_point_module_id_is_correct(self) -> None: + """Entry point key must match the module ID used in graph-analyst.md.""" + data = _load_pyproject() + eps = data.get("project", {}).get("entry-points", {}).get("amplifier.modules", {}) + assert "tool-context-intelligence-query" in eps, ( + f"Entry point 'tool-context-intelligence-query' not found in " + f"[project.entry-points.'amplifier.modules']: {eps}" + ) + assert ( + "amplifier_module_tool_context_intelligence_query" + in eps["tool-context-intelligence-query"] + ) + + def test_asyncio_mode_is_auto(self) -> None: + """pytest-asyncio must be in auto mode for the test suite to run correctly.""" + data = _load_pyproject() + asyncio_mode = ( + data.get("tool", {}).get("pytest", {}).get("ini_options", {}).get("asyncio_mode") + ) + assert asyncio_mode == "auto", f"asyncio_mode must be 'auto', got: {asyncio_mode!r}" diff --git a/modules/tool-context-intelligence-query/uv.lock b/modules/tool-context-intelligence-query/uv.lock new file mode 100644 index 0000000..3dd2c90 --- /dev/null +++ b/modules/tool-context-intelligence-query/uv.lock @@ -0,0 +1,520 @@ +version = 1 +revision = 3 +requires-python = ">=3.11" + +[[package]] +name = "amplifier-bundle-context-intelligence" +version = "0.1.1" +source = { git = "https://github.com/microsoft/amplifier-bundle-context-intelligence?rev=main#2e47dc7c331b60210814f711129a10fdffd76ee4" } + +[[package]] +name = "amplifier-core" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "pydantic" }, + { name = "pyyaml" }, + { name = "tomli" }, + { name = "typing-extensions" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/90/d520390cd91aae3d02db53653f828046089c79203dbb142e9bda346fa1d6/amplifier_core-1.6.0-cp311-abi3-macosx_10_12_x86_64.whl", hash = "sha256:d35130e4262cf0db2d6c5f7e65e244a9ef2c7397bfe2a9853bc9b0d9fd05be64", size = 8113151, upload-time = "2026-05-18T16:13:46.825Z" }, + { url = "https://files.pythonhosted.org/packages/94/75/3ab3126ba5a6f2fc6051a4d08e42364899e4c9ac4daa9d0a60947bf8acd1/amplifier_core-1.6.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:387a2c58fcf4caefdb45c52ec228307bc225e73606897f242154782bc3e123da", size = 7268223, upload-time = "2026-05-18T16:13:48.749Z" }, + { url = "https://files.pythonhosted.org/packages/21/22/5a36160b3487170bcba0cbc61535101ff624e8314ed38fd35e561cb711a1/amplifier_core-1.6.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8344fccdedd725a51c018de17867cdf1c35abb571dabc0bbccdb5c1242324a47", size = 7532259, upload-time = "2026-05-18T16:13:50.614Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d7/3874c2308523209411367cf3b8b690e14e869f5f6bfb64cb1b1971e06a96/amplifier_core-1.6.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a8e0103242a2e2a975c880b1de0e5a02501e0421c1e5386dadae3f111e1d2b5", size = 8507642, upload-time = "2026-05-18T16:13:52.977Z" }, + { url = "https://files.pythonhosted.org/packages/86/59/3646a89537b4556274183519f6db9c354fb3d183f52ef4a2179af12dd386/amplifier_core-1.6.0-cp311-abi3-win_amd64.whl", hash = "sha256:5113aa2d88038776eb257af9e7d9de7af13b3cd9097d2ac67aef5730fa0678e3", size = 8910313, upload-time = "2026-05-18T16:13:55.249Z" }, + { url = "https://files.pythonhosted.org/packages/9f/9e/58b141115e5eea65703f0b01459eefed36b561e9642ba96d48542345cd8f/amplifier_core-1.6.0-cp311-abi3-win_arm64.whl", hash = "sha256:e1b2731dc09d1cbc668b411007e7f9a2c7edbd75b2525407cae1e6b4a4de0b83", size = 7661416, upload-time = "2026-05-18T16:13:57.513Z" }, +] + +[[package]] +name = "amplifier-module-tool-context-intelligence-query" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "amplifier-bundle-context-intelligence" }, + { name = "httpx" }, + { name = "idna" }, +] + +[package.dev-dependencies] +dev = [ + { name = "amplifier-core" }, + { name = "pyright" }, + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [ + { name = "amplifier-bundle-context-intelligence", git = "https://github.com/microsoft/amplifier-bundle-context-intelligence?rev=main" }, + { name = "httpx", specifier = ">=0.28.1" }, + { name = "idna", specifier = ">=3.15" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "amplifier-core", specifier = ">=1.6.0" }, + { name = "pyright", specifier = ">=1.1" }, + { name = "pytest", specifier = ">=9.0.3" }, + { name = "pytest-asyncio", specifier = ">=0.24" }, + { name = "ruff", specifier = ">=0.4" }, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, +] + +[[package]] +name = "anyio" +version = "4.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/b5/001890774a9552aff22502b8da382593109ce0c95314abaebbb116567545/anyio-4.14.0.tar.gz", hash = "sha256:b47c1f9ccf73e67021df785332508f99379c68fa7d0684e8e3492cb1d4b23f89", size = 253586, upload-time = "2026-06-15T22:00:49.021Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/16/9826f089383c593cdfc4a6e5aca94d9e91ae1692c57af82c3b2aa5e810f7/anyio-4.14.0-py3-none-any.whl", hash = "sha256:dd9b7a2a9799ed6552fde617b2c5df02b7fdd7d88392fc48101e51bae46164d9", size = 123506, upload-time = "2026-06-15T22:00:47.595Z" }, +] + +[[package]] +name = "certifi" +version = "2026.6.17" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/c7/424b75da314c1045981bd9777432fad05a9e0c69daa4ed7e308bbaffe405/certifi-2026.6.17.tar.gz", hash = "sha256:024c88eeec92ca068db80f02b8b07c9cef7b9fe261d1d535abfd5abd6f6af432", size = 134594, upload-time = "2026-06-17T10:31:07.894Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/2f/c5464532e965badff2f4c4c1a3a83f5697f0d7c407ed0cda44aaa99bb451/certifi-2026.6.17-py3-none-any.whl", hash = "sha256:2227dcbaafe0d2f59279d1762ddddc37783ed4354594f194ffc31d20f41fc3db", size = 133289, upload-time = "2026-06-17T10:31:06.348Z" }, +] + +[[package]] +name = "click" +version = "8.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9b/98/518d8e5081007684232226f475082b30087d0f585e8457db087298259f49/click-8.4.1.tar.gz", hash = "sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96", size = 353007, upload-time = "2026-05-22T04:08:37.769Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl", hash = "sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2", size = 116639, upload-time = "2026-05-22T04:08:35.26Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, +] + +[[package]] +name = "idna" +version = "3.18" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "nodeenv" +version = "1.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, +] + +[[package]] +name = "packaging" +version = "26.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "pydantic" +version = "2.13.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.46.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/fa/6d7708d2cfc1a832acb6aeb0cd16e801902df8a0f583bb3b4b527fde022e/pydantic_core-2.46.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:0e96592440881c74a213e5ad528e2b24d3d4f940de2766bed9010ab1d9e51594", size = 2111872, upload-time = "2026-05-06T13:40:27.596Z" }, + { url = "https://files.pythonhosted.org/packages/ae/6f/aa064a3e74b5745afbdf250594f38e7ead05e2d651bcb35994b9417a0d4d/pydantic_core-2.46.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e0d65b8c354be7fb5f720c3caa8bc940bc2d20ce749c8e06135f07f8ed95dd7c", size = 1948255, upload-time = "2026-05-06T13:39:12.574Z" }, + { url = "https://files.pythonhosted.org/packages/43/3a/41114a9f7569b84b4d84e7a018c57c56347dac30c0d4a872946ec4e36c46/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bfb192b3f4b9e8a89b6277b6ce787564f62cfd272055f6e685726b111dc7826", size = 1972827, upload-time = "2026-05-06T13:38:19.841Z" }, + { url = "https://files.pythonhosted.org/packages/ef/25/1ab42e8048fe551934d9884e8d64daa7e990ad386f310a15981aeb6a5b08/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9037063db01f09b09e237c282b6792bd4da634b5402c4e7f0c61effed7701a04", size = 2041051, upload-time = "2026-05-06T13:38:10.447Z" }, + { url = "https://files.pythonhosted.org/packages/94/c2/1a934597ddf08da410385b3b7aae91956a5a76c635effef456074fad7e88/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fc010ab034c8c7452522748bf937df58020d256ccae0874463d1f4d01758af8e", size = 2221314, upload-time = "2026-05-06T13:40:13.089Z" }, + { url = "https://files.pythonhosted.org/packages/02/6d/9e8ad178c9c4df27ad3c8f25d1fe2a7ab0d2ba0559fad4aee5d3d1f16771/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c5dac79fa1614d1e06ca695109c6105923bd9c7d1d6c918d4e637b7e6b32fd3", size = 2285146, upload-time = "2026-05-06T13:38:59.224Z" }, + { url = "https://files.pythonhosted.org/packages/80/50/540cd3aeefc041beb111125c4bff779831a2111fc6b15a9138cda277d32c/pydantic_core-2.46.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9fa868638bf362d3d138ea55829cefb3d5f4b0d7f142234382a15e2485dbec4", size = 2089685, upload-time = "2026-05-06T13:38:17.762Z" }, + { url = "https://files.pythonhosted.org/packages/6b/a4/b440ad35f05f6a38f89fa0f149accb3f0e02be94ca5e15f3c449a61b4bc9/pydantic_core-2.46.4-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:17299feefe090f2caa5b8e37222bb5f663e4935a8bfa6931d4102e5df1a9f398", size = 2115420, upload-time = "2026-05-06T13:37:58.195Z" }, + { url = "https://files.pythonhosted.org/packages/99/61/de4f55db8dfd57bfdfa9a12ec90fe1b57c4f41062f7ca86f08586b3e0ac0/pydantic_core-2.46.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4c63ebc82684aa89d9a3bcbd13d515b3be44250dc68dd3bd81526c1cb31286c3", size = 2165122, upload-time = "2026-05-06T13:37:01.167Z" }, + { url = "https://files.pythonhosted.org/packages/f7/52/7c529d7bdb2d1068bd52f51fe32572c8301f9a4febf1948f10639f1436f5/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:aaa2a54443eff1950ba5ddc6b6ccda0d9c84a364276a62f969bdf2a390650848", size = 2182573, upload-time = "2026-05-06T13:38:45.04Z" }, + { url = "https://files.pythonhosted.org/packages/37/b3/7c40325848ba78247f2812dcf9c7274e38cd801820ca6dd9fe63bcfb0eb4/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:18e5ceec2ab67e6d5f1a9085e5a24c9c4e2ac4545730bfe668680bca05e555f3", size = 2317139, upload-time = "2026-05-06T13:37:15.539Z" }, + { url = "https://files.pythonhosted.org/packages/d9/37/f913f81a657c865b75da6c0dbed79876073c2a43b5bd9edbe8da785e4d49/pydantic_core-2.46.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a0f62d0a58f4e7da165457e995725421e0064f2255d8eccebc49f41bbc23b109", size = 2360433, upload-time = "2026-05-06T13:37:30.099Z" }, + { url = "https://files.pythonhosted.org/packages/c4/67/6acaa1be2567f9256b056d8477158cac7240813956ce86e49deae8e173b4/pydantic_core-2.46.4-cp311-cp311-win32.whl", hash = "sha256:041bde0a48fd37cf71cab1c9d56d3e8625a3793fef1f7dd232b3ff37e978ecda", size = 1985513, upload-time = "2026-05-06T13:38:15.669Z" }, + { url = "https://files.pythonhosted.org/packages/aa/e6/c505f83dfeda9a2e5c995cfd872949e4d05e12f7feb3dca72f633daefa94/pydantic_core-2.46.4-cp311-cp311-win_amd64.whl", hash = "sha256:6f2eeda33a839975441c86a4119e1383c50b47faf0cbb5176985565c6bb02c33", size = 2071114, upload-time = "2026-05-06T13:40:35.416Z" }, + { url = "https://files.pythonhosted.org/packages/0f/da/7a263a96d965d9d0df5e8de8a475f33495451117035b09acb110288c381f/pydantic_core-2.46.4-cp311-cp311-win_arm64.whl", hash = "sha256:14f4c5d6db102bd796a627bbb3a17b4cf4574b9ae861d8b7c9a9661c6dd3362d", size = 2044298, upload-time = "2026-05-06T13:38:29.754Z" }, + { url = "https://files.pythonhosted.org/packages/ce/8c/af022f0af448d7747c5154288d46b5f2bc5f17366eaa0e23e9aa04d59f3b/pydantic_core-2.46.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3245406455a5d98187ec35530fd772b1d799b26667980872c8d4614991e2c4a2", size = 2106158, upload-time = "2026-05-06T13:38:57.215Z" }, + { url = "https://files.pythonhosted.org/packages/19/95/6195171e385007300f0f5574592e467c568becce2d937a0b6804f218bc49/pydantic_core-2.46.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:962ccbab7b642487b1d8b7df90ef677e03134cf1fd8880bf698649b22a69371f", size = 1951724, upload-time = "2026-05-06T13:37:02.697Z" }, + { url = "https://files.pythonhosted.org/packages/8e/bc/f47d1ff9cbb1620e1b5b697eef06010035735f07820180e74178226b27b3/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7", size = 1975742, upload-time = "2026-05-06T13:37:09.448Z" }, + { url = "https://files.pythonhosted.org/packages/5b/11/9b9a5b0306345664a2da6410877af6e8082481b5884b3ddd78d47c6013ce/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7", size = 2052418, upload-time = "2026-05-06T13:37:38.234Z" }, + { url = "https://files.pythonhosted.org/packages/f1/b7/a65fec226f5d78fc39f4a13c4cc0c768c22b113438f60c14adc9d2865038/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712", size = 2232274, upload-time = "2026-05-06T13:38:27.753Z" }, + { url = "https://files.pythonhosted.org/packages/68/f0/92039db98b907ef49269a8271f67db9cb78ae2fc68062ef7e4e77adb5f61/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4", size = 2309940, upload-time = "2026-05-06T13:38:05.353Z" }, + { url = "https://files.pythonhosted.org/packages/5f/97/2aab507d3d00ca626e8e57c1eac6a79e4e5fbcc63eb99733ff55d1717f65/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce", size = 2094516, upload-time = "2026-05-06T13:39:10.577Z" }, + { url = "https://files.pythonhosted.org/packages/22/37/a8aca44d40d737dde2bc05b3c6c07dff0de07ce6f82e9f3167aeaf4d5dea/pydantic_core-2.46.4-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987", size = 2136854, upload-time = "2026-05-06T13:40:22.59Z" }, + { url = "https://files.pythonhosted.org/packages/24/99/fcef1b79238c06a8cbec70819ac722ba76e02bc8ada9b0fd66eba40da01b/pydantic_core-2.46.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b", size = 2180306, upload-time = "2026-05-06T13:40:10.666Z" }, + { url = "https://files.pythonhosted.org/packages/ae/6c/fc44000918855b42779d007ae63b0532794739027b2f417321cddbc44f6a/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458", size = 2190044, upload-time = "2026-05-06T13:40:43.231Z" }, + { url = "https://files.pythonhosted.org/packages/6b/65/d9cadc9f1920d7a127ad2edba16c1db7916e59719285cd6c94600b0080ba/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b", size = 2329133, upload-time = "2026-05-06T13:39:57.365Z" }, + { url = "https://files.pythonhosted.org/packages/d0/cf/c873d91679f3a30bcf5e7ac280ce5573483e72295307685120d0d5ad3416/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c", size = 2374464, upload-time = "2026-05-06T13:38:06.976Z" }, + { url = "https://files.pythonhosted.org/packages/47/bd/6f2fc8188f31bf10590f1e98e7b306336161fac930a8c514cd7bd828c7dc/pydantic_core-2.46.4-cp312-cp312-win32.whl", hash = "sha256:9aa768456404a8bf48a4406685ac2bec8e72b62c69313734fa3b73cf33b3a894", size = 1974823, upload-time = "2026-05-06T13:40:47.985Z" }, + { url = "https://files.pythonhosted.org/packages/40/8c/985c1d41ea1107c2534abd9870e4ed5c8e7669b5c308297835c001e7a1c4/pydantic_core-2.46.4-cp312-cp312-win_amd64.whl", hash = "sha256:e9c26f834c65f5752f3f06cb08cb86a913ceb7274d0db6e267808a708b46bc89", size = 2072919, upload-time = "2026-05-06T13:39:21.153Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ba/f463d006e0c47373ca7ec5e1a261c59dc01ef4d62b2657af925fb0deee3a/pydantic_core-2.46.4-cp312-cp312-win_arm64.whl", hash = "sha256:4fc73cb559bdb54b1134a706a2802a4cddd27a0633f5abb7e53056268751ac6a", size = 2027604, upload-time = "2026-05-06T13:39:03.753Z" }, + { url = "https://files.pythonhosted.org/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306, upload-time = "2026-05-06T13:37:48.029Z" }, + { url = "https://files.pythonhosted.org/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906, upload-time = "2026-05-06T13:37:17.012Z" }, + { url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload-time = "2026-05-06T13:37:35.113Z" }, + { url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload-time = "2026-05-06T13:37:12.313Z" }, + { url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload-time = "2026-05-06T13:39:01.149Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload-time = "2026-05-06T13:37:41.406Z" }, + { url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload-time = "2026-05-06T13:39:18.847Z" }, + { url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload-time = "2026-05-06T13:40:17.944Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload-time = "2026-05-06T13:40:32.618Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload-time = "2026-05-06T13:36:51.018Z" }, + { url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload-time = "2026-05-06T13:40:37.764Z" }, + { url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload-time = "2026-05-06T13:39:34.152Z" }, + { url = "https://files.pythonhosted.org/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693, upload-time = "2026-05-06T13:37:55.072Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819, upload-time = "2026-05-06T13:38:49.139Z" }, + { url = "https://files.pythonhosted.org/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411, upload-time = "2026-05-06T13:40:45.796Z" }, + { url = "https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079, upload-time = "2026-05-06T13:38:41.019Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179, upload-time = "2026-05-06T13:36:59.812Z" }, + { url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload-time = "2026-05-06T13:37:39.933Z" }, + { url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload-time = "2026-05-06T13:38:01.995Z" }, + { url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload-time = "2026-05-06T13:40:50.371Z" }, + { url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload-time = "2026-05-06T13:37:21.531Z" }, + { url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload-time = "2026-05-06T13:39:31.942Z" }, + { url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload-time = "2026-05-06T13:37:25.033Z" }, + { url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload-time = "2026-05-06T13:37:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload-time = "2026-05-06T13:36:53.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload-time = "2026-05-06T13:40:29.971Z" }, + { url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload-time = "2026-05-06T13:37:23.027Z" }, + { url = "https://files.pythonhosted.org/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354, upload-time = "2026-05-06T13:38:03.499Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238, upload-time = "2026-05-06T13:39:40.807Z" }, + { url = "https://files.pythonhosted.org/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251, upload-time = "2026-05-06T13:37:26.72Z" }, + { url = "https://files.pythonhosted.org/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593, upload-time = "2026-05-06T13:39:47.682Z" }, + { url = "https://files.pythonhosted.org/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226, upload-time = "2026-05-06T13:40:40.428Z" }, + { url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload-time = "2026-05-06T13:37:32.029Z" }, + { url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload-time = "2026-05-06T13:38:55.239Z" }, + { url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload-time = "2026-05-06T13:37:08.096Z" }, + { url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload-time = "2026-05-06T13:40:20.221Z" }, + { url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload-time = "2026-05-06T13:38:12.153Z" }, + { url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload-time = "2026-05-06T13:40:02.971Z" }, + { url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload-time = "2026-05-06T13:39:27.506Z" }, + { url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload-time = "2026-05-06T13:38:31.93Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload-time = "2026-05-06T13:37:44.717Z" }, + { url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload-time = "2026-05-06T13:37:05.645Z" }, + { url = "https://files.pythonhosted.org/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575, upload-time = "2026-05-06T13:38:51.116Z" }, + { url = "https://files.pythonhosted.org/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624, upload-time = "2026-05-06T13:38:21.672Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload-time = "2026-05-06T13:40:52.723Z" }, + { url = "https://files.pythonhosted.org/packages/ee/a4/73995fd4ebbb46ba0ee51e6fa049b8f02c40daebb762208feda8a6b7894d/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:14d4edf427bdcf950a8a02d7cb44a08614388dd6e1bdcbf4f67504fa7887da9c", size = 2111589, upload-time = "2026-05-06T13:37:10.817Z" }, + { url = "https://files.pythonhosted.org/packages/fb/7f/f37d3a5e8bfcc2e403f5c57a730f2d815693fb42119e8ea48b3789335af1/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:0ce40cd7b21210e99342afafbd4d0f76d784eb5b1d60f3bdc566be4983c6c73b", size = 1944552, upload-time = "2026-05-06T13:36:56.717Z" }, + { url = "https://files.pythonhosted.org/packages/15/3c/d7eb777b3ff43e8433a4efb39a17aa8fd98a4ee8561a24a67ef5db07b2d6/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90884113d8b48f760e9587002789ddd741e76ab9f89518cd1e43b1f1a52ec44b", size = 1982984, upload-time = "2026-05-06T13:39:06.207Z" }, + { url = "https://files.pythonhosted.org/packages/63/87/70b9f40170a81afd55ca26c9b2acb25c20d64bcfbf888fafecb3ba077d4c/pydantic_core-2.46.4-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66ce7632c22d837c95301830e111ad0128a32b8207533b60896a96c4915192ea", size = 2138417, upload-time = "2026-05-06T13:39:45.476Z" }, + { url = "https://files.pythonhosted.org/packages/9d/1d/8987ad40f65ae1432753072f214fb5c74fe47ffbd0698bb9cbbb585664f8/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:1d8ba486450b14f3b1d63bc521d410ec7565e52f887b9fb671791886436a42f7", size = 2095527, upload-time = "2026-05-06T13:39:52.283Z" }, + { url = "https://files.pythonhosted.org/packages/64/d3/84c282a7eee1d3ac4c0377546ef5a1ea436ce26840d9ac3b7ed54a377507/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:3009f12e4e90b7f88b4f9adb1b0c4a3d58fe7820f3238c190047209d148026df", size = 1936024, upload-time = "2026-05-06T13:40:15.671Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ca/eac61596cdeb4d7e174d3dc0bd8a6238f14f75f97a24e7b7db4c7e7340a0/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526", size = 1990696, upload-time = "2026-05-06T13:38:34.717Z" }, + { url = "https://files.pythonhosted.org/packages/fa/c3/7c8b240552251faf6b3a957db200fcfbbcec36763c050428b601e0c9b83b/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0", size = 2147590, upload-time = "2026-05-06T13:39:29.883Z" }, + { url = "https://files.pythonhosted.org/packages/11/cb/428de0385b6c8d44b716feba566abfacfbd23ee3c4439faa789a1456242f/pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0c563b08bca408dc7f65f700633d8442fffb2421fc47b8101377e9fd65051ff0", size = 2112782, upload-time = "2026-05-06T13:37:04.016Z" }, + { url = "https://files.pythonhosted.org/packages/0b/b5/6a17bdadd0fc1f170adfd05a20d37c832f52b117b4d9131da1f41bb097ce/pydantic_core-2.46.4-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:db06ffe51636ffe9ca531fe9023dd64bdd794be8754cb5df57c5498ae5b518a7", size = 1952146, upload-time = "2026-05-06T13:39:43.092Z" }, + { url = "https://files.pythonhosted.org/packages/2a/dc/03734d80e362cd43ef65428e9de77c730ce7f2f11c60d2b1e1b39f0fbf99/pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:133878133d271ade3d41d1bfb2a45ec38dbdbda40bc065921c6b04e4630127e2", size = 2134492, upload-time = "2026-05-06T13:36:58.124Z" }, + { url = "https://files.pythonhosted.org/packages/de/df/5e5ffc085ed07cc22d298134d3d911c63e91f6a0eb91fe646750a3209910/pydantic_core-2.46.4-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9bc519fbf2b7578398853d815009ae5e4d4603d12f4e3f91da8c06852d3da3e9", size = 2156604, upload-time = "2026-05-06T13:37:49.88Z" }, + { url = "https://files.pythonhosted.org/packages/81/44/6e112a4253e56f5705467cbab7ab5e91ee7398ba3d56d358635958893d3e/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:c7a7bd4e39e8e4c12c39cd480356842b6a8a06e41b23a55a5e3e191718838ddf", size = 2183828, upload-time = "2026-05-06T13:37:43.053Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ad/5565071e937d8e752842ac241463944c9eb14c87e2d269f2658a5bd05e98/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:d396ec2b979760aaf3218e76c24e65bd0aca24983298653b3a9d7a45f9e47b30", size = 2310000, upload-time = "2026-05-06T13:37:56.694Z" }, + { url = "https://files.pythonhosted.org/packages/4f/c3/66883a5cec183e7fba4d024b4cbbe61851a63750ef606b0afecc46d1f2bf/pydantic_core-2.46.4-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:86e1a4418c6cd97d60c95c71164158eaf7324fae7b0923264016baa993eba6fc", size = 2361286, upload-time = "2026-05-06T13:40:05.667Z" }, + { url = "https://files.pythonhosted.org/packages/4b/2d/69abac8f838090bbecd5df894befb2c2619e7996a98ddb949db9f3b93225/pydantic_core-2.46.4-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:d51026d73fcfd93610abc7b27789c26b313920fcfb20e27462d74a7f8b06e983", size = 2193071, upload-time = "2026-05-06T13:38:08.682Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pyright" +version = "1.1.410" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nodeenv" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/10/53/e4d8ea1391bd4355231be6f91bf239479aa0014260ed3fb5526eeb12a1f2/pyright-1.1.410.tar.gz", hash = "sha256:07a073b8ba6749826773c1269773efa11b93440d9a6aa60419d9a3172d6dc488", size = 4062013, upload-time = "2026-06-01T17:35:48.894Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/33/288b5868fa00846dacf249633719d747893e54aebd196b9968ac1878a5d3/pyright-1.1.410-py3-none-any.whl", hash = "sha256:5e961bed37cacf96b3f7cd7b1da39b350a9239aa2e69138d0e88f728cfaf296c", size = 6082448, upload-time = "2026-06-01T17:35:46.387Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "pytest-asyncio" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/43/7c/d36d04db312ecf4298932ef77e6e4a9e8ad017906e24e34f0b0c361a2473/pytest_asyncio-1.4.0.tar.gz", hash = "sha256:c6c0d2259945122819f171a32ecea2c349ead889ee28176caaf492143424be42", size = 58514, upload-time = "2026-05-26T09:56:04.083Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/03/e2/08a497ef684b88559c9cc5f4ad53a37e7b99e727094a86d6ea32536d5d3c/pytest_asyncio-1.4.0-py3-none-any.whl", hash = "sha256:933ca923a23075a87fb7070c0ec272a6848489824d887c85c812670932835aa1", size = 16930, upload-time = "2026-05-26T09:56:02.576Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.18" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/74/98/1295ad5a5aa9bc85bdcdfa5d82fe7b49c61af5657df4f227637ff9de0da6/ruff-0.15.18.tar.gz", hash = "sha256:2698a964c70e8bf402dcb99c8810472d270d141e7aa8c4e13599fd52033a2f33", size = 4761437, upload-time = "2026-06-18T18:25:39.224Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/d0/686e984941269621e2be72612d5c1e461f8f7b38415a2a7d7a81c8ae6715/ruff-0.15.18-py3-none-linux_armv6l.whl", hash = "sha256:8b6850172348c8381b8b3084c5915a4393c2373b9b54cd5b5e1ea15812bc10df", size = 10887308, upload-time = "2026-06-18T18:25:03.062Z" }, + { url = "https://files.pythonhosted.org/packages/ed/21/bc4123e3f5515ee99f8ce1eb93a14a0628fe4d1678663cd08f933ac16931/ruff-0.15.18-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3fccc153a85417dcd976883160cacce486997b0a0058dd18f54b8aaaac7d1ce2", size = 11281305, upload-time = "2026-06-18T18:25:30.026Z" }, + { url = "https://files.pythonhosted.org/packages/51/93/4769464c25cf7ab2acb3c7dda9cad3d867eb41c59565b3e2a9d17249c90c/ruff-0.15.18-py3-none-macosx_11_0_arm64.whl", hash = "sha256:08d4c86a68f2c3ec2c9d56380a71fb4a4f65373055cbb8caabd645e9102f38d4", size = 10641215, upload-time = "2026-06-18T18:25:15.802Z" }, + { url = "https://files.pythonhosted.org/packages/6c/42/56926d17120db2c208d76bf60a1a019644dd9e91dc27f0f95c9caddb1366/ruff-0.15.18-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37e5108745c2c0705da916d7d4de533ddf547051ef45f62888c31bae73f66318", size = 10957224, upload-time = "2026-06-18T18:25:36.955Z" }, + { url = "https://files.pythonhosted.org/packages/22/4f/d43fab8d8189afde803103022d000a8ef9f230616d436d52a8b2b8d63b50/ruff-0.15.18-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:56949a6ce8b3abde54c0bcb22cebfe57e8771cadc84b407ae8b8eaf67ebdcd43", size = 10699024, upload-time = "2026-06-18T18:25:05.707Z" }, + { url = "https://files.pythonhosted.org/packages/63/42/1e3e4c68bd408b9768cf3e439acbe2c78245225faef253f7028a0cdb63e0/ruff-0.15.18-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01a754cd6a1b630d3f97e33eb452cf7a98040482318e870f8bc52a5a30e62657", size = 11491458, upload-time = "2026-06-18T18:25:20.275Z" }, + { url = "https://files.pythonhosted.org/packages/20/77/47a3484bea8521e14a203d98c389c5c97846675e4f02734672da4a69b52a/ruff-0.15.18-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ba7a07e03a44dbf10bb086ee06705b173625014ec99f73a7e6836a5e5590a0c", size = 12383752, upload-time = "2026-06-18T18:25:22.535Z" }, + { url = "https://files.pythonhosted.org/packages/0a/ca/054159590787023d83b658a1a1819c4c8910114e7015069340b71c0961cb/ruff-0.15.18-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a2c40a41a4cadbcf5897b548ab29dfe248b20c540961c0247d98a3973c70403", size = 11577923, upload-time = "2026-06-18T18:25:10.702Z" }, + { url = "https://files.pythonhosted.org/packages/6d/ff/d353d6b7bbd73cc0ec37f4463d7540e45e894338abdd9964eee0de332708/ruff-0.15.18-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f0480ce690cbb6c4db6e5d08f19fce98e10ba131a8b60c1bcdac42771e3ae2d", size = 11583925, upload-time = "2026-06-18T18:25:32.391Z" }, + { url = "https://files.pythonhosted.org/packages/c1/4a/891f89b9c296ed3e5f3ece1a5629badc989d9a8fdaa30431aaf4774bc1c2/ruff-0.15.18-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:2330215f1f393fa8733f55edce04fcf94c36a2c460fcde31f78cc84e4951e9b1", size = 11582834, upload-time = "2026-06-18T18:25:27.309Z" }, + { url = "https://files.pythonhosted.org/packages/32/a3/ed9e370154bf85de360b93c03026157f02d4943b2d01ff4945f4429f8e8a/ruff-0.15.18-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a6aa6a3d979e48ae617578183674bf264fbe7d0114a796a26bd678d67963c7ff", size = 10927328, upload-time = "2026-06-18T18:25:34.676Z" }, + { url = "https://files.pythonhosted.org/packages/f5/d1/5cf5909329fedb5d39d555ee818ba5cf4638e1a301b89785d34f2905bfcb/ruff-0.15.18-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a81beadbbff2c9c245561ae3f77b16709d87f35eec650d0501679239d3449b22", size = 10693187, upload-time = "2026-06-18T18:25:08.245Z" }, + { url = "https://files.pythonhosted.org/packages/fd/44/ff6c635cf2c4f4e7b618b6640da057376baa36014695487d88aed4794268/ruff-0.15.18-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2186d9e940ae332ab293623a75b5f4fe49565f449954d50a72a046683aa6b809", size = 11208721, upload-time = "2026-06-18T18:25:41.327Z" }, + { url = "https://files.pythonhosted.org/packages/88/d9/5baa2a30861adfb7022cf33c1e35b2fc18085b08c16f83eff4c7b99a5f48/ruff-0.15.18-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5c2abf140438032bc77b2284a6c9944ecd8a19e5f1c7b52b1b8e4a0a80d19a7a", size = 11678599, upload-time = "2026-06-18T18:25:13.607Z" }, + { url = "https://files.pythonhosted.org/packages/c3/1a/0725a7cfdc32ff769efb96ee782bec882e16448c5d9e3be947ec4c04ce27/ruff-0.15.18-py3-none-win32.whl", hash = "sha256:02299e6e9fa5b297a3f6d5d10d7bcd655c925b028bb8b9d4588214549c6b9ec4", size = 10901903, upload-time = "2026-06-18T18:25:24.755Z" }, + { url = "https://files.pythonhosted.org/packages/f3/51/805d9f6fb7970505c3504794a5ec350f605361b807fef4dcf214ebd35e72/ruff-0.15.18-py3-none-win_amd64.whl", hash = "sha256:dac80dc8d26b2257dbefabed62f5d255c3937b4ccb122da1fc634794fa3578b3", size = 12041189, upload-time = "2026-06-18T18:25:17.915Z" }, + { url = "https://files.pythonhosted.org/packages/29/4c/67bb45e41609eb4726f1bfeb59e083cf91d14c696d4bd14c234a980be93d/ruff-0.15.18-py3-none-win_arm64.whl", hash = "sha256:b2c9257fcbd4a3e5b977a1904e6facca016bafe2edc17df24db67cfaee03b4e4", size = 11329958, upload-time = "2026-06-18T18:25:43.686Z" }, +] + +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704, upload-time = "2026-03-25T20:21:10.473Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454, upload-time = "2026-03-25T20:21:12.036Z" }, + { url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561, upload-time = "2026-03-25T20:21:13.098Z" }, + { url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824, upload-time = "2026-03-25T20:21:14.569Z" }, + { url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227, upload-time = "2026-03-25T20:21:15.712Z" }, + { url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859, upload-time = "2026-03-25T20:21:17.001Z" }, + { url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204, upload-time = "2026-03-25T20:21:18.079Z" }, + { url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084, upload-time = "2026-03-25T20:21:18.978Z" }, + { url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285, upload-time = "2026-03-25T20:21:20.309Z" }, + { url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924, upload-time = "2026-03-25T20:21:21.626Z" }, + { url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018, upload-time = "2026-03-25T20:21:23.002Z" }, + { url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948, upload-time = "2026-03-25T20:21:24.04Z" }, + { url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341, upload-time = "2026-03-25T20:21:25.177Z" }, + { url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159, upload-time = "2026-03-25T20:21:26.364Z" }, + { url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290, upload-time = "2026-03-25T20:21:27.46Z" }, + { url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141, upload-time = "2026-03-25T20:21:28.492Z" }, + { url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847, upload-time = "2026-03-25T20:21:29.386Z" }, + { url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088, upload-time = "2026-03-25T20:21:30.677Z" }, + { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866, upload-time = "2026-03-25T20:21:31.65Z" }, + { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887, upload-time = "2026-03-25T20:21:33.028Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704, upload-time = "2026-03-25T20:21:34.51Z" }, + { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628, upload-time = "2026-03-25T20:21:36.012Z" }, + { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180, upload-time = "2026-03-25T20:21:37.136Z" }, + { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674, upload-time = "2026-03-25T20:21:38.298Z" }, + { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976, upload-time = "2026-03-25T20:21:39.316Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755, upload-time = "2026-03-25T20:21:40.248Z" }, + { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265, upload-time = "2026-03-25T20:21:41.219Z" }, + { url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726, upload-time = "2026-03-25T20:21:42.23Z" }, + { url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859, upload-time = "2026-03-25T20:21:43.386Z" }, + { url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713, upload-time = "2026-03-25T20:21:44.474Z" }, + { url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084, upload-time = "2026-03-25T20:21:45.62Z" }, + { url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973, upload-time = "2026-03-25T20:21:46.937Z" }, + { url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223, upload-time = "2026-03-25T20:21:48.467Z" }, + { url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973, upload-time = "2026-03-25T20:21:49.526Z" }, + { url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082, upload-time = "2026-03-25T20:21:50.506Z" }, + { url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490, upload-time = "2026-03-25T20:21:51.474Z" }, + { url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263, upload-time = "2026-03-25T20:21:52.543Z" }, + { url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736, upload-time = "2026-03-25T20:21:53.674Z" }, + { url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717, upload-time = "2026-03-25T20:21:55.129Z" }, + { url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461, upload-time = "2026-03-25T20:21:56.228Z" }, + { url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855, upload-time = "2026-03-25T20:21:57.653Z" }, + { url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144, upload-time = "2026-03-25T20:21:59.089Z" }, + { url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683, upload-time = "2026-03-25T20:22:00.214Z" }, + { url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196, upload-time = "2026-03-25T20:22:01.169Z" }, + { url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393, upload-time = "2026-03-25T20:22:02.137Z" }, + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, +] diff --git a/modules/tool-graph-query/amplifier_module_tool_graph_query/__init__.py b/modules/tool-graph-query/amplifier_module_tool_graph_query/__init__.py deleted file mode 100644 index 1cca2c5..0000000 --- a/modules/tool-graph-query/amplifier_module_tool_graph_query/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -"""Graph query tool module โ€” Cypher queries against the context-intelligence server. - -Implements the Amplifier Tool protocol. Configuration is resolved lazily -via the ``context_intelligence.config_resolver`` coordinator capability -registered by the hook-context-intelligence module. -""" - -from __future__ import annotations - -from typing import Any - -__amplifier_module_type__ = "tool" - - -async def mount(coordinator: Any, config: dict[str, Any]) -> dict[str, Any]: # noqa: ARG001 - """Mount the graph_query tool. - - Captures a coordinator reference for lazy capability resolution. - The tool reads the config resolver at execute() time, not mount() time, - because hooks mount after tools. - """ - from .graph_query_tool import GraphQueryTool - - tool = GraphQueryTool(coordinator=coordinator, config=config) - await coordinator.mount("tools", tool, name=tool.name) - return {"tool": tool.name, "status": "mounted"} diff --git a/modules/tool-graph-query/pyproject.toml b/modules/tool-graph-query/pyproject.toml deleted file mode 100644 index 389f9b4..0000000 --- a/modules/tool-graph-query/pyproject.toml +++ /dev/null @@ -1,52 +0,0 @@ -[project] -name = "amplifier-module-tool-graph-query" -version = "0.1.0" -description = "Graph query tool โ€” executes Cypher queries against the context-intelligence server" -requires-python = ">=3.11" -license = "MIT" - -dependencies = [ - "amplifier-bundle-context-intelligence @ git+https://github.com/microsoft/amplifier-bundle-context-intelligence@main", - "httpx>=0.28.1", - "idna>=3.15", -] - -[project.entry-points."amplifier.modules"] -tool-graph-query = "amplifier_module_tool_graph_query:mount" - -[build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" - -[tool.uv] -package = true - -[tool.hatch.build.targets.wheel] -packages = ["amplifier_module_tool_graph_query"] - -[tool.hatch.metadata] -# Required to build a wheel that carries a PEP 508 direct-reference (git+https) dependency. -allow-direct-references = true - -[dependency-groups] -dev = [ - "amplifier-core>=1.6.0", - "pytest>=9.0.3", - "pytest-asyncio>=0.24", - "pyright>=1.1", - "ruff>=0.4", -] - -[tool.pytest.ini_options] -asyncio_mode = "auto" -asyncio_default_fixture_loop_scope = "function" - -[tool.pyright] -pythonVersion = "3.11" -typeCheckingMode = "basic" -venvPath = "." -venv = ".venv" - -[tool.ruff] -target-version = "py311" -line-length = 100 diff --git a/modules/tool-graph-query/tests/__init__.py b/modules/tool-graph-query/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/modules/tool-graph-query/tests/test_mount.py b/modules/tool-graph-query/tests/test_mount.py deleted file mode 100644 index d97b843..0000000 --- a/modules/tool-graph-query/tests/test_mount.py +++ /dev/null @@ -1,73 +0,0 @@ -"""Tests for tool-graph-query module mount contract.""" - -from __future__ import annotations - -import inspect -from unittest.mock import AsyncMock, MagicMock - - -class TestModuleContract: - """Module-level contract for a tool module.""" - - def test_module_type_is_tool(self) -> None: - from amplifier_module_tool_graph_query import __amplifier_module_type__ - - assert __amplifier_module_type__ == "tool" - - def test_mount_is_coroutine(self) -> None: - from amplifier_module_tool_graph_query import mount - - assert inspect.iscoroutinefunction(mount) - - def test_mount_signature_has_coordinator_and_config(self) -> None: - from amplifier_module_tool_graph_query import mount - - sig = inspect.signature(mount) - params = list(sig.parameters.keys()) - assert params[0] == "coordinator" - assert params[1] == "config" - - -class TestMountBehavior: - """mount() registers a Tool-protocol-compliant object via coordinator.mount().""" - - async def test_mount_calls_coordinator_mount_with_tools_category(self) -> None: - from amplifier_module_tool_graph_query import mount - - coordinator = MagicMock() - coordinator.mount = AsyncMock() - await mount(coordinator, config={}) - coordinator.mount.assert_called_once() - assert coordinator.mount.call_args.args[0] == "tools" - - async def test_mounted_tool_has_name_graph_query(self) -> None: - from amplifier_module_tool_graph_query import mount - - coordinator = MagicMock() - coordinator.mount = AsyncMock() - await mount(coordinator, config={}) - assert coordinator.mount.call_args.kwargs["name"] == "graph_query" - - async def test_mounted_tool_is_protocol_compliant(self) -> None: - from amplifier_module_tool_graph_query import mount - - coordinator = MagicMock() - coordinator.mount = AsyncMock() - await mount(coordinator, config={}) - tool = coordinator.mount.call_args.args[1] - assert hasattr(tool, "name") - assert hasattr(tool, "description") - assert hasattr(tool, "input_schema") - assert hasattr(tool, "execute") - assert isinstance(tool.input_schema, dict) - assert inspect.iscoroutinefunction(tool.execute) - - async def test_mount_returns_metadata_dict(self) -> None: - from amplifier_module_tool_graph_query import mount - - coordinator = MagicMock() - coordinator.mount = AsyncMock() - result = await mount(coordinator, config={}) - assert isinstance(result, dict) - assert result["tool"] == "graph_query" - assert result["status"] == "mounted" diff --git a/modules/tool-graph-query/tests/test_tool_dependencies.py b/modules/tool-graph-query/tests/test_tool_dependencies.py deleted file mode 100644 index f8952e6..0000000 --- a/modules/tool-graph-query/tests/test_tool_dependencies.py +++ /dev/null @@ -1,96 +0,0 @@ -"""Test that the graph-query tool pyproject.toml declares the bundle dependency in a -form that installs standalone (outside the monorepo). - -The tool imports from the `context_intelligence` package shipped by the parent -bundle. For the tool to install standalone under the Amplifier agent's -`uv pip install --no-sources` policy, the bundle MUST be referenced as a PEP 508 -direct git reference inside [project.dependencies] (which survives --no-sources), -NOT via a [tool.uv.sources] `path = "../.."` entry (which --no-sources strips). - -This guard mirrors hook-context-intelligence/tests/test_hook_dependencies.py so -that every module references the parent bundle uniformly and cannot regress to a -uv path source (the original cause of the uv conflicting-URLs co-install failure). -""" - -from __future__ import annotations - -import tomllib -from pathlib import Path - -MODULE_ROOT = Path(__file__).parent.parent -PYPROJECT = MODULE_ROOT / "pyproject.toml" - -BUNDLE = "amplifier-bundle-context-intelligence" - - -def _load_pyproject() -> dict: - return tomllib.loads(PYPROJECT.read_text()) - - -def _dep_name(dep: str) -> str: - """Extract the bare package name from a requirement string. - - Handles version specifiers (>=, ==) and PEP 508 direct references - (`name @ git+https://...`). - """ - return dep.split("@")[0].split(">=")[0].split("==")[0].strip() - - -class TestToolDependencies: - """Verify the tool declares the bundle as a standalone-installable dependency.""" - - def test_bundle_declared_as_direct_git_reference(self) -> None: - """The bundle must be a PEP 508 direct git reference in [project.dependencies]. - - A direct `name @ git+https://...` reference survives `--no-sources`, - unlike a bare name (only resolvable from PyPI) or a [tool.uv.sources] entry. - """ - data = _load_pyproject() - deps: list[str] = data["project"]["dependencies"] - bundle_deps = [d for d in deps if _dep_name(d) == BUNDLE] - assert bundle_deps, f"Expected '{BUNDLE}' in dependencies, got: {deps}" - assert "git+https://" in bundle_deps[0], ( - f"Bundle dependency must be a direct git+https reference so it survives " - f"`uv pip install --no-sources`, got: {bundle_deps[0]!r}" - ) - - def test_bundle_is_not_a_uv_path_source(self) -> None: - """The bundle must NOT be a [tool.uv.sources] path entry. - - The `path = '../..'` assumption is exactly what breaks standalone install: - --no-sources strips [tool.uv.sources], leaving an unresolvable reference. - Two modules referencing the bundle via path while others use a git URL is - what produced uv's "conflicting URLs" abort on a single co-install command. - """ - data = _load_pyproject() - sources: dict = data.get("tool", {}).get("uv", {}).get("sources", {}) - assert BUNDLE not in sources, ( - f"'{BUNDLE}' must not be a [tool.uv.sources] entry (breaks standalone " - f"install under --no-sources); declare it as a direct git reference in " - f"[project.dependencies] instead. Got sources: {sources}" - ) - - def test_dependencies_list_has_httpx_and_bundle(self) -> None: - """Production deps must include httpx and the bundle. - - amplifier-core is NOT a production dep โ€” it is runtime-provided by the - Amplifier CLI. - """ - data = _load_pyproject() - deps: list[str] = data["project"]["dependencies"] - assert any("httpx" in d for d in deps), f"httpx not found in {deps}" - assert any(_dep_name(d) == BUNDLE for d in deps), f"{BUNDLE} not found in {deps}" - assert not any(_dep_name(d) == "amplifier-core" for d in deps), ( - f"amplifier-core must not be a production dep (runtime-provided): {deps}" - ) - - def test_allow_direct_references_enabled(self) -> None: - """Building a wheel that carries a direct reference requires this hatch flag.""" - data = _load_pyproject() - allow = ( - data.get("tool", {}).get("hatch", {}).get("metadata", {}).get("allow-direct-references") - ) - assert allow is True, ( - "tool.hatch.metadata.allow-direct-references must be true to build a wheel " - f"carrying the direct git reference, got: {allow!r}" - ) diff --git a/modules/tool-graph-query/uv.lock b/modules/tool-graph-query/uv.lock deleted file mode 100644 index f459672..0000000 --- a/modules/tool-graph-query/uv.lock +++ /dev/null @@ -1,515 +0,0 @@ -version = 1 -revision = 3 -requires-python = ">=3.11" - -[[package]] -name = "amplifier-bundle-context-intelligence" -version = "0.1.1" -source = { git = "https://github.com/microsoft/amplifier-bundle-context-intelligence?rev=main#2e47dc7c331b60210814f711129a10fdffd76ee4" } - -[[package]] -name = "amplifier-core" -version = "1.6.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "pydantic" }, - { name = "pyyaml" }, - { name = "tomli" }, - { name = "typing-extensions" }, -] -wheels = [ - { url = "https://files.pythonhosted.org/packages/32/90/d520390cd91aae3d02db53653f828046089c79203dbb142e9bda346fa1d6/amplifier_core-1.6.0-cp311-abi3-macosx_10_12_x86_64.whl", hash = "sha256:d35130e4262cf0db2d6c5f7e65e244a9ef2c7397bfe2a9853bc9b0d9fd05be64", size = 8113151, upload-time = "2026-05-18T16:13:46.825Z" }, - { url = "https://files.pythonhosted.org/packages/94/75/3ab3126ba5a6f2fc6051a4d08e42364899e4c9ac4daa9d0a60947bf8acd1/amplifier_core-1.6.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:387a2c58fcf4caefdb45c52ec228307bc225e73606897f242154782bc3e123da", size = 7268223, upload-time = "2026-05-18T16:13:48.749Z" }, - { url = "https://files.pythonhosted.org/packages/21/22/5a36160b3487170bcba0cbc61535101ff624e8314ed38fd35e561cb711a1/amplifier_core-1.6.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8344fccdedd725a51c018de17867cdf1c35abb571dabc0bbccdb5c1242324a47", size = 7532259, upload-time = "2026-05-18T16:13:50.614Z" }, - { url = "https://files.pythonhosted.org/packages/bd/d7/3874c2308523209411367cf3b8b690e14e869f5f6bfb64cb1b1971e06a96/amplifier_core-1.6.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a8e0103242a2e2a975c880b1de0e5a02501e0421c1e5386dadae3f111e1d2b5", size = 8507642, upload-time = "2026-05-18T16:13:52.977Z" }, - { url = "https://files.pythonhosted.org/packages/86/59/3646a89537b4556274183519f6db9c354fb3d183f52ef4a2179af12dd386/amplifier_core-1.6.0-cp311-abi3-win_amd64.whl", hash = "sha256:5113aa2d88038776eb257af9e7d9de7af13b3cd9097d2ac67aef5730fa0678e3", size = 8910313, upload-time = "2026-05-18T16:13:55.249Z" }, - { url = "https://files.pythonhosted.org/packages/9f/9e/58b141115e5eea65703f0b01459eefed36b561e9642ba96d48542345cd8f/amplifier_core-1.6.0-cp311-abi3-win_arm64.whl", hash = "sha256:e1b2731dc09d1cbc668b411007e7f9a2c7edbd75b2525407cae1e6b4a4de0b83", size = 7661416, upload-time = "2026-05-18T16:13:57.513Z" }, -] - -[[package]] -name = "amplifier-module-tool-graph-query" -version = "0.1.0" -source = { editable = "." } -dependencies = [ - { name = "amplifier-bundle-context-intelligence" }, - { name = "httpx" }, - { name = "idna" }, -] - -[package.dev-dependencies] -dev = [ - { name = "amplifier-core" }, - { name = "pyright" }, - { name = "pytest" }, - { name = "pytest-asyncio" }, - { name = "ruff" }, -] - -[package.metadata] -requires-dist = [ - { name = "amplifier-bundle-context-intelligence", git = "https://github.com/microsoft/amplifier-bundle-context-intelligence?rev=main" }, - { name = "httpx", specifier = ">=0.28.1" }, - { name = "idna", specifier = ">=3.15" }, -] - -[package.metadata.requires-dev] -dev = [ - { name = "amplifier-core", specifier = ">=1.6.0" }, - { name = "pyright", specifier = ">=1.1" }, - { name = "pytest", specifier = ">=9.0.3" }, - { name = "pytest-asyncio", specifier = ">=0.24" }, - { name = "ruff", specifier = ">=0.4" }, -] - -[[package]] -name = "annotated-types" -version = "0.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, -] - -[[package]] -name = "anyio" -version = "4.12.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "idna" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/96/f0/5eb65b2bb0d09ac6776f2eb54adee6abe8228ea05b20a5ad0e4945de8aac/anyio-4.12.1.tar.gz", hash = "sha256:41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703", size = 228685, upload-time = "2026-01-06T11:45:21.246Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl", hash = "sha256:d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c", size = 113592, upload-time = "2026-01-06T11:45:19.497Z" }, -] - -[[package]] -name = "certifi" -version = "2026.2.25" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7", size = 155029, upload-time = "2026-02-25T02:54:17.342Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa", size = 153684, upload-time = "2026-02-25T02:54:15.766Z" }, -] - -[[package]] -name = "click" -version = "8.3.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, -] - -[[package]] -name = "colorama" -version = "0.4.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, -] - -[[package]] -name = "h11" -version = "0.16.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, -] - -[[package]] -name = "httpcore" -version = "1.0.9" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "h11" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, -] - -[[package]] -name = "httpx" -version = "0.28.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "certifi" }, - { name = "httpcore" }, - { name = "idna" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, -] - -[[package]] -name = "idna" -version = "3.15" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/77/7b3966d0b9d1d31a36ddf1746926a11dface89a83409bf1483f0237aa758/idna-3.15.tar.gz", hash = "sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc", size = 199245, upload-time = "2026-05-12T22:45:57.011Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/23/408243171aa9aaba178d3e2559159c24c1171a641aa83b67bdd3394ead8e/idna-3.15-py3-none-any.whl", hash = "sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8", size = 72340, upload-time = "2026-05-12T22:45:55.733Z" }, -] - -[[package]] -name = "iniconfig" -version = "2.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, -] - -[[package]] -name = "nodeenv" -version = "1.10.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, -] - -[[package]] -name = "packaging" -version = "26.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, -] - -[[package]] -name = "pluggy" -version = "1.6.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, -] - -[[package]] -name = "pydantic" -version = "2.12.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "annotated-types" }, - { name = "pydantic-core" }, - { name = "typing-extensions" }, - { name = "typing-inspection" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, -] - -[[package]] -name = "pydantic-core" -version = "2.41.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e8/72/74a989dd9f2084b3d9530b0915fdda64ac48831c30dbf7c72a41a5232db8/pydantic_core-2.41.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6", size = 2105873, upload-time = "2025-11-04T13:39:31.373Z" }, - { url = "https://files.pythonhosted.org/packages/12/44/37e403fd9455708b3b942949e1d7febc02167662bf1a7da5b78ee1ea2842/pydantic_core-2.41.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b", size = 1899826, upload-time = "2025-11-04T13:39:32.897Z" }, - { url = "https://files.pythonhosted.org/packages/33/7f/1d5cab3ccf44c1935a359d51a8a2a9e1a654b744b5e7f80d41b88d501eec/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a", size = 1917869, upload-time = "2025-11-04T13:39:34.469Z" }, - { url = "https://files.pythonhosted.org/packages/6e/6a/30d94a9674a7fe4f4744052ed6c5e083424510be1e93da5bc47569d11810/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8", size = 2063890, upload-time = "2025-11-04T13:39:36.053Z" }, - { url = "https://files.pythonhosted.org/packages/50/be/76e5d46203fcb2750e542f32e6c371ffa9b8ad17364cf94bb0818dbfb50c/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e", size = 2229740, upload-time = "2025-11-04T13:39:37.753Z" }, - { url = "https://files.pythonhosted.org/packages/d3/ee/fed784df0144793489f87db310a6bbf8118d7b630ed07aa180d6067e653a/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1", size = 2350021, upload-time = "2025-11-04T13:39:40.94Z" }, - { url = "https://files.pythonhosted.org/packages/c8/be/8fed28dd0a180dca19e72c233cbf58efa36df055e5b9d90d64fd1740b828/pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b", size = 2066378, upload-time = "2025-11-04T13:39:42.523Z" }, - { url = "https://files.pythonhosted.org/packages/b0/3b/698cf8ae1d536a010e05121b4958b1257f0b5522085e335360e53a6b1c8b/pydantic_core-2.41.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b", size = 2175761, upload-time = "2025-11-04T13:39:44.553Z" }, - { url = "https://files.pythonhosted.org/packages/b8/ba/15d537423939553116dea94ce02f9c31be0fa9d0b806d427e0308ec17145/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284", size = 2146303, upload-time = "2025-11-04T13:39:46.238Z" }, - { url = "https://files.pythonhosted.org/packages/58/7f/0de669bf37d206723795f9c90c82966726a2ab06c336deba4735b55af431/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594", size = 2340355, upload-time = "2025-11-04T13:39:48.002Z" }, - { url = "https://files.pythonhosted.org/packages/e5/de/e7482c435b83d7e3c3ee5ee4451f6e8973cff0eb6007d2872ce6383f6398/pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e", size = 2319875, upload-time = "2025-11-04T13:39:49.705Z" }, - { url = "https://files.pythonhosted.org/packages/fe/e6/8c9e81bb6dd7560e33b9053351c29f30c8194b72f2d6932888581f503482/pydantic_core-2.41.5-cp311-cp311-win32.whl", hash = "sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b", size = 1987549, upload-time = "2025-11-04T13:39:51.842Z" }, - { url = "https://files.pythonhosted.org/packages/11/66/f14d1d978ea94d1bc21fc98fcf570f9542fe55bfcc40269d4e1a21c19bf7/pydantic_core-2.41.5-cp311-cp311-win_amd64.whl", hash = "sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe", size = 2011305, upload-time = "2025-11-04T13:39:53.485Z" }, - { url = "https://files.pythonhosted.org/packages/56/d8/0e271434e8efd03186c5386671328154ee349ff0354d83c74f5caaf096ed/pydantic_core-2.41.5-cp311-cp311-win_arm64.whl", hash = "sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f", size = 1972902, upload-time = "2025-11-04T13:39:56.488Z" }, - { url = "https://files.pythonhosted.org/packages/5f/5d/5f6c63eebb5afee93bcaae4ce9a898f3373ca23df3ccaef086d0233a35a7/pydantic_core-2.41.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7", size = 2110990, upload-time = "2025-11-04T13:39:58.079Z" }, - { url = "https://files.pythonhosted.org/packages/aa/32/9c2e8ccb57c01111e0fd091f236c7b371c1bccea0fa85247ac55b1e2b6b6/pydantic_core-2.41.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0", size = 1896003, upload-time = "2025-11-04T13:39:59.956Z" }, - { url = "https://files.pythonhosted.org/packages/68/b8/a01b53cb0e59139fbc9e4fda3e9724ede8de279097179be4ff31f1abb65a/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69", size = 1919200, upload-time = "2025-11-04T13:40:02.241Z" }, - { url = "https://files.pythonhosted.org/packages/38/de/8c36b5198a29bdaade07b5985e80a233a5ac27137846f3bc2d3b40a47360/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75", size = 2052578, upload-time = "2025-11-04T13:40:04.401Z" }, - { url = "https://files.pythonhosted.org/packages/00/b5/0e8e4b5b081eac6cb3dbb7e60a65907549a1ce035a724368c330112adfdd/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05", size = 2208504, upload-time = "2025-11-04T13:40:06.072Z" }, - { url = "https://files.pythonhosted.org/packages/77/56/87a61aad59c7c5b9dc8caad5a41a5545cba3810c3e828708b3d7404f6cef/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc", size = 2335816, upload-time = "2025-11-04T13:40:07.835Z" }, - { url = "https://files.pythonhosted.org/packages/0d/76/941cc9f73529988688a665a5c0ecff1112b3d95ab48f81db5f7606f522d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c", size = 2075366, upload-time = "2025-11-04T13:40:09.804Z" }, - { url = "https://files.pythonhosted.org/packages/d3/43/ebef01f69baa07a482844faaa0a591bad1ef129253ffd0cdaa9d8a7f72d3/pydantic_core-2.41.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5", size = 2171698, upload-time = "2025-11-04T13:40:12.004Z" }, - { url = "https://files.pythonhosted.org/packages/b1/87/41f3202e4193e3bacfc2c065fab7706ebe81af46a83d3e27605029c1f5a6/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c", size = 2132603, upload-time = "2025-11-04T13:40:13.868Z" }, - { url = "https://files.pythonhosted.org/packages/49/7d/4c00df99cb12070b6bccdef4a195255e6020a550d572768d92cc54dba91a/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294", size = 2329591, upload-time = "2025-11-04T13:40:15.672Z" }, - { url = "https://files.pythonhosted.org/packages/cc/6a/ebf4b1d65d458f3cda6a7335d141305dfa19bdc61140a884d165a8a1bbc7/pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1", size = 2319068, upload-time = "2025-11-04T13:40:17.532Z" }, - { url = "https://files.pythonhosted.org/packages/49/3b/774f2b5cd4192d5ab75870ce4381fd89cf218af999515baf07e7206753f0/pydantic_core-2.41.5-cp312-cp312-win32.whl", hash = "sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d", size = 1985908, upload-time = "2025-11-04T13:40:19.309Z" }, - { url = "https://files.pythonhosted.org/packages/86/45/00173a033c801cacf67c190fef088789394feaf88a98a7035b0e40d53dc9/pydantic_core-2.41.5-cp312-cp312-win_amd64.whl", hash = "sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815", size = 2020145, upload-time = "2025-11-04T13:40:21.548Z" }, - { url = "https://files.pythonhosted.org/packages/f9/22/91fbc821fa6d261b376a3f73809f907cec5ca6025642c463d3488aad22fb/pydantic_core-2.41.5-cp312-cp312-win_arm64.whl", hash = "sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3", size = 1976179, upload-time = "2025-11-04T13:40:23.393Z" }, - { url = "https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", size = 2120403, upload-time = "2025-11-04T13:40:25.248Z" }, - { url = "https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", size = 1896206, upload-time = "2025-11-04T13:40:27.099Z" }, - { url = "https://files.pythonhosted.org/packages/15/df/a4c740c0943e93e6500f9eb23f4ca7ec9bf71b19e608ae5b579678c8d02f/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", size = 1919307, upload-time = "2025-11-04T13:40:29.806Z" }, - { url = "https://files.pythonhosted.org/packages/9a/e3/6324802931ae1d123528988e0e86587c2072ac2e5394b4bc2bc34b61ff6e/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", size = 2063258, upload-time = "2025-11-04T13:40:33.544Z" }, - { url = "https://files.pythonhosted.org/packages/c9/d4/2230d7151d4957dd79c3044ea26346c148c98fbf0ee6ebd41056f2d62ab5/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", size = 2214917, upload-time = "2025-11-04T13:40:35.479Z" }, - { url = "https://files.pythonhosted.org/packages/e6/9f/eaac5df17a3672fef0081b6c1bb0b82b33ee89aa5cec0d7b05f52fd4a1fa/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", size = 2332186, upload-time = "2025-11-04T13:40:37.436Z" }, - { url = "https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", size = 2073164, upload-time = "2025-11-04T13:40:40.289Z" }, - { url = "https://files.pythonhosted.org/packages/bf/e3/f6e262673c6140dd3305d144d032f7bd5f7497d3871c1428521f19f9efa2/pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", size = 2179146, upload-time = "2025-11-04T13:40:42.809Z" }, - { url = "https://files.pythonhosted.org/packages/75/c7/20bd7fc05f0c6ea2056a4565c6f36f8968c0924f19b7d97bbfea55780e73/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", size = 2137788, upload-time = "2025-11-04T13:40:44.752Z" }, - { url = "https://files.pythonhosted.org/packages/3a/8d/34318ef985c45196e004bc46c6eab2eda437e744c124ef0dbe1ff2c9d06b/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", size = 2340133, upload-time = "2025-11-04T13:40:46.66Z" }, - { url = "https://files.pythonhosted.org/packages/9c/59/013626bf8c78a5a5d9350d12e7697d3d4de951a75565496abd40ccd46bee/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", size = 2324852, upload-time = "2025-11-04T13:40:48.575Z" }, - { url = "https://files.pythonhosted.org/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679, upload-time = "2025-11-04T13:40:50.619Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766, upload-time = "2025-11-04T13:40:52.631Z" }, - { url = "https://files.pythonhosted.org/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005, upload-time = "2025-11-04T13:40:54.734Z" }, - { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" }, - { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" }, - { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" }, - { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" }, - { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" }, - { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" }, - { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" }, - { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" }, - { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" }, - { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" }, - { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" }, - { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" }, - { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" }, - { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" }, - { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" }, - { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" }, - { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" }, - { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" }, - { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" }, - { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" }, - { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" }, - { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" }, - { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" }, - { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" }, - { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" }, - { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, - { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, - { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, - { url = "https://files.pythonhosted.org/packages/11/72/90fda5ee3b97e51c494938a4a44c3a35a9c96c19bba12372fb9c634d6f57/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034", size = 2115441, upload-time = "2025-11-04T13:42:39.557Z" }, - { url = "https://files.pythonhosted.org/packages/1f/53/8942f884fa33f50794f119012dc6a1a02ac43a56407adaac20463df8e98f/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c", size = 1930291, upload-time = "2025-11-04T13:42:42.169Z" }, - { url = "https://files.pythonhosted.org/packages/79/c8/ecb9ed9cd942bce09fc888ee960b52654fbdbede4ba6c2d6e0d3b1d8b49c/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2", size = 1948632, upload-time = "2025-11-04T13:42:44.564Z" }, - { url = "https://files.pythonhosted.org/packages/2e/1b/687711069de7efa6af934e74f601e2a4307365e8fdc404703afc453eab26/pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad", size = 2138905, upload-time = "2025-11-04T13:42:47.156Z" }, - { url = "https://files.pythonhosted.org/packages/09/32/59b0c7e63e277fa7911c2fc70ccfb45ce4b98991e7ef37110663437005af/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd", size = 2110495, upload-time = "2025-11-04T13:42:49.689Z" }, - { url = "https://files.pythonhosted.org/packages/aa/81/05e400037eaf55ad400bcd318c05bb345b57e708887f07ddb2d20e3f0e98/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc", size = 1915388, upload-time = "2025-11-04T13:42:52.215Z" }, - { url = "https://files.pythonhosted.org/packages/6e/0d/e3549b2399f71d56476b77dbf3cf8937cec5cd70536bdc0e374a421d0599/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56", size = 1942879, upload-time = "2025-11-04T13:42:56.483Z" }, - { url = "https://files.pythonhosted.org/packages/f7/07/34573da085946b6a313d7c42f82f16e8920bfd730665de2d11c0c37a74b5/pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b", size = 2139017, upload-time = "2025-11-04T13:42:59.471Z" }, - { url = "https://files.pythonhosted.org/packages/5f/9b/1b3f0e9f9305839d7e84912f9e8bfbd191ed1b1ef48083609f0dabde978c/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26", size = 2101980, upload-time = "2025-11-04T13:43:25.97Z" }, - { url = "https://files.pythonhosted.org/packages/a4/ed/d71fefcb4263df0da6a85b5d8a7508360f2f2e9b3bf5814be9c8bccdccc1/pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808", size = 1923865, upload-time = "2025-11-04T13:43:28.763Z" }, - { url = "https://files.pythonhosted.org/packages/ce/3a/626b38db460d675f873e4444b4bb030453bbe7b4ba55df821d026a0493c4/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc", size = 2134256, upload-time = "2025-11-04T13:43:31.71Z" }, - { url = "https://files.pythonhosted.org/packages/83/d9/8412d7f06f616bbc053d30cb4e5f76786af3221462ad5eee1f202021eb4e/pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1", size = 2174762, upload-time = "2025-11-04T13:43:34.744Z" }, - { url = "https://files.pythonhosted.org/packages/55/4c/162d906b8e3ba3a99354e20faa1b49a85206c47de97a639510a0e673f5da/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84", size = 2143141, upload-time = "2025-11-04T13:43:37.701Z" }, - { url = "https://files.pythonhosted.org/packages/1f/f2/f11dd73284122713f5f89fc940f370d035fa8e1e078d446b3313955157fe/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770", size = 2330317, upload-time = "2025-11-04T13:43:40.406Z" }, - { url = "https://files.pythonhosted.org/packages/88/9d/b06ca6acfe4abb296110fb1273a4d848a0bfb2ff65f3ee92127b3244e16b/pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f", size = 2316992, upload-time = "2025-11-04T13:43:43.602Z" }, - { url = "https://files.pythonhosted.org/packages/36/c7/cfc8e811f061c841d7990b0201912c3556bfeb99cdcb7ed24adc8d6f8704/pydantic_core-2.41.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51", size = 2145302, upload-time = "2025-11-04T13:43:46.64Z" }, -] - -[[package]] -name = "pygments" -version = "2.20.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, -] - -[[package]] -name = "pyright" -version = "1.1.408" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "nodeenv" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/74/b2/5db700e52554b8f025faa9c3c624c59f1f6c8841ba81ab97641b54322f16/pyright-1.1.408.tar.gz", hash = "sha256:f28f2321f96852fa50b5829ea492f6adb0e6954568d1caa3f3af3a5f555eb684", size = 4400578, upload-time = "2026-01-08T08:07:38.795Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/82/a2c93e32800940d9573fb28c346772a14778b84ba7524e691b324620ab89/pyright-1.1.408-py3-none-any.whl", hash = "sha256:090b32865f4fdb1e0e6cd82bf5618480d48eecd2eb2e70f960982a3d9a4c17c1", size = 6399144, upload-time = "2026-01-08T08:07:37.082Z" }, -] - -[[package]] -name = "pytest" -version = "9.0.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "iniconfig" }, - { name = "packaging" }, - { name = "pluggy" }, - { name = "pygments" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, -] - -[[package]] -name = "pytest-asyncio" -version = "1.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pytest" }, - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5", size = 50087, upload-time = "2025-11-10T16:07:47.256Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075, upload-time = "2025-11-10T16:07:45.537Z" }, -] - -[[package]] -name = "pyyaml" -version = "6.0.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, - { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, - { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, - { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, - { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, - { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, - { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, - { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, - { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, - { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, - { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, - { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, - { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, - { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, - { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, - { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, - { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, - { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, - { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, - { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, - { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, - { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, - { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, - { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, - { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, - { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, - { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, - { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, - { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, - { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, - { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, - { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, - { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, - { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, - { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, - { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, - { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, - { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, - { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, - { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, - { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, - { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, - { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, - { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, - { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, - { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, - { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, -] - -[[package]] -name = "ruff" -version = "0.15.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/51/df/f8629c19c5318601d3121e230f74cbee7a3732339c52b21daa2b82ef9c7d/ruff-0.15.6.tar.gz", hash = "sha256:8394c7bb153a4e3811a4ecdacd4a8e6a4fa8097028119160dffecdcdf9b56ae4", size = 4597916, upload-time = "2026-03-12T23:05:47.51Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/2f/4e03a7e5ce99b517e98d3b4951f411de2b0fa8348d39cf446671adcce9a2/ruff-0.15.6-py3-none-linux_armv6l.whl", hash = "sha256:7c98c3b16407b2cf3d0f2b80c80187384bc92c6774d85fefa913ecd941256fff", size = 10508953, upload-time = "2026-03-12T23:05:17.246Z" }, - { url = "https://files.pythonhosted.org/packages/70/60/55bcdc3e9f80bcf39edf0cd272da6fa511a3d94d5a0dd9e0adf76ceebdb4/ruff-0.15.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ee7dcfaad8b282a284df4aa6ddc2741b3f4a18b0555d626805555a820ea181c3", size = 10942257, upload-time = "2026-03-12T23:05:23.076Z" }, - { url = "https://files.pythonhosted.org/packages/e7/f9/005c29bd1726c0f492bfa215e95154cf480574140cb5f867c797c18c790b/ruff-0.15.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3bd9967851a25f038fc8b9ae88a7fbd1b609f30349231dffaa37b6804923c4bb", size = 10322683, upload-time = "2026-03-12T23:05:33.738Z" }, - { url = "https://files.pythonhosted.org/packages/5f/74/2f861f5fd7cbb2146bddb5501450300ce41562da36d21868c69b7a828169/ruff-0.15.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13f4594b04e42cd24a41da653886b04d2ff87adbf57497ed4f728b0e8a4866f8", size = 10660986, upload-time = "2026-03-12T23:05:53.245Z" }, - { url = "https://files.pythonhosted.org/packages/c1/a1/309f2364a424eccb763cdafc49df843c282609f47fe53aa83f38272389e0/ruff-0.15.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e2ed8aea2f3fe57886d3f00ea5b8aae5bf68d5e195f487f037a955ff9fbaac9e", size = 10332177, upload-time = "2026-03-12T23:05:56.145Z" }, - { url = "https://files.pythonhosted.org/packages/30/41/7ebf1d32658b4bab20f8ac80972fb19cd4e2c6b78552be263a680edc55ac/ruff-0.15.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70789d3e7830b848b548aae96766431c0dc01a6c78c13381f423bf7076c66d15", size = 11170783, upload-time = "2026-03-12T23:06:01.742Z" }, - { url = "https://files.pythonhosted.org/packages/76/be/6d488f6adca047df82cd62c304638bcb00821c36bd4881cfca221561fdfc/ruff-0.15.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:542aaf1de3154cea088ced5a819ce872611256ffe2498e750bbae5247a8114e9", size = 12044201, upload-time = "2026-03-12T23:05:28.697Z" }, - { url = "https://files.pythonhosted.org/packages/71/68/e6f125df4af7e6d0b498f8d373274794bc5156b324e8ab4bf5c1b4fc0ec7/ruff-0.15.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c22e6f02c16cfac3888aa636e9eba857254d15bbacc9906c9689fdecb1953ab", size = 11421561, upload-time = "2026-03-12T23:05:31.236Z" }, - { url = "https://files.pythonhosted.org/packages/f1/9f/f85ef5fd01a52e0b472b26dc1b4bd228b8f6f0435975442ffa4741278703/ruff-0.15.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98893c4c0aadc8e448cfa315bd0cc343a5323d740fe5f28ef8a3f9e21b381f7e", size = 11310928, upload-time = "2026-03-12T23:05:45.288Z" }, - { url = "https://files.pythonhosted.org/packages/8c/26/b75f8c421f5654304b89471ed384ae8c7f42b4dff58fa6ce1626d7f2b59a/ruff-0.15.6-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:70d263770d234912374493e8cc1e7385c5d49376e41dfa51c5c3453169dc581c", size = 11235186, upload-time = "2026-03-12T23:05:50.677Z" }, - { url = "https://files.pythonhosted.org/packages/fc/d4/d5a6d065962ff7a68a86c9b4f5500f7d101a0792078de636526c0edd40da/ruff-0.15.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:55a1ad63c5a6e54b1f21b7514dfadc0c7fb40093fa22e95143cf3f64ebdcd512", size = 10635231, upload-time = "2026-03-12T23:05:37.044Z" }, - { url = "https://files.pythonhosted.org/packages/d6/56/7c3acf3d50910375349016cf33de24be021532042afbed87942858992491/ruff-0.15.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:8dc473ba093c5ec238bb1e7429ee676dca24643c471e11fbaa8a857925b061c0", size = 10340357, upload-time = "2026-03-12T23:06:04.748Z" }, - { url = "https://files.pythonhosted.org/packages/06/54/6faa39e9c1033ff6a3b6e76b5df536931cd30caf64988e112bbf91ef5ce5/ruff-0.15.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:85b042377c2a5561131767974617006f99f7e13c63c111b998f29fc1e58a4cfb", size = 10860583, upload-time = "2026-03-12T23:05:58.978Z" }, - { url = "https://files.pythonhosted.org/packages/cb/1e/509a201b843b4dfb0b32acdedf68d951d3377988cae43949ba4c4133a96a/ruff-0.15.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cef49e30bc5a86a6a92098a7fbf6e467a234d90b63305d6f3ec01225a9d092e0", size = 11410976, upload-time = "2026-03-12T23:05:39.955Z" }, - { url = "https://files.pythonhosted.org/packages/6c/25/3fc9114abf979a41673ce877c08016f8e660ad6cf508c3957f537d2e9fa9/ruff-0.15.6-py3-none-win32.whl", hash = "sha256:bbf67d39832404812a2d23020dda68fee7f18ce15654e96fb1d3ad21a5fe436c", size = 10616872, upload-time = "2026-03-12T23:05:42.451Z" }, - { url = "https://files.pythonhosted.org/packages/89/7a/09ece68445ceac348df06e08bf75db72d0e8427765b96c9c0ffabc1be1d9/ruff-0.15.6-py3-none-win_amd64.whl", hash = "sha256:aee25bc84c2f1007ecb5037dff75cef00414fdf17c23f07dc13e577883dca406", size = 11787271, upload-time = "2026-03-12T23:05:20.168Z" }, - { url = "https://files.pythonhosted.org/packages/7f/d0/578c47dd68152ddddddf31cd7fc67dc30b7cdf639a86275fda821b0d9d98/ruff-0.15.6-py3-none-win_arm64.whl", hash = "sha256:c34de3dd0b0ba203be50ae70f5910b17188556630e2178fd7d79fc030eb0d837", size = 11060497, upload-time = "2026-03-12T23:05:25.968Z" }, -] - -[[package]] -name = "tomli" -version = "2.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/30/31573e9457673ab10aa432461bee537ce6cef177667deca369efb79df071/tomli-2.4.0.tar.gz", hash = "sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c", size = 17477, upload-time = "2026-01-11T11:22:38.165Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3c/d9/3dc2289e1f3b32eb19b9785b6a006b28ee99acb37d1d47f78d4c10e28bf8/tomli-2.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867", size = 153663, upload-time = "2026-01-11T11:21:45.27Z" }, - { url = "https://files.pythonhosted.org/packages/51/32/ef9f6845e6b9ca392cd3f64f9ec185cc6f09f0a2df3db08cbe8809d1d435/tomli-2.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9", size = 148469, upload-time = "2026-01-11T11:21:46.873Z" }, - { url = "https://files.pythonhosted.org/packages/d6/c2/506e44cce89a8b1b1e047d64bd495c22c9f71f21e05f380f1a950dd9c217/tomli-2.4.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95", size = 236039, upload-time = "2026-01-11T11:21:48.503Z" }, - { url = "https://files.pythonhosted.org/packages/b3/40/e1b65986dbc861b7e986e8ec394598187fa8aee85b1650b01dd925ca0be8/tomli-2.4.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76", size = 243007, upload-time = "2026-01-11T11:21:49.456Z" }, - { url = "https://files.pythonhosted.org/packages/9c/6f/6e39ce66b58a5b7ae572a0f4352ff40c71e8573633deda43f6a379d56b3e/tomli-2.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d", size = 240875, upload-time = "2026-01-11T11:21:50.755Z" }, - { url = "https://files.pythonhosted.org/packages/aa/ad/cb089cb190487caa80204d503c7fd0f4d443f90b95cf4ef5cf5aa0f439b0/tomli-2.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576", size = 246271, upload-time = "2026-01-11T11:21:51.81Z" }, - { url = "https://files.pythonhosted.org/packages/0b/63/69125220e47fd7a3a27fd0de0c6398c89432fec41bc739823bcc66506af6/tomli-2.4.0-cp311-cp311-win32.whl", hash = "sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a", size = 96770, upload-time = "2026-01-11T11:21:52.647Z" }, - { url = "https://files.pythonhosted.org/packages/1e/0d/a22bb6c83f83386b0008425a6cd1fa1c14b5f3dd4bad05e98cf3dbbf4a64/tomli-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa", size = 107626, upload-time = "2026-01-11T11:21:53.459Z" }, - { url = "https://files.pythonhosted.org/packages/2f/6d/77be674a3485e75cacbf2ddba2b146911477bd887dda9d8c9dfb2f15e871/tomli-2.4.0-cp311-cp311-win_arm64.whl", hash = "sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614", size = 94842, upload-time = "2026-01-11T11:21:54.831Z" }, - { url = "https://files.pythonhosted.org/packages/3c/43/7389a1869f2f26dba52404e1ef13b4784b6b37dac93bac53457e3ff24ca3/tomli-2.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1", size = 154894, upload-time = "2026-01-11T11:21:56.07Z" }, - { url = "https://files.pythonhosted.org/packages/e9/05/2f9bf110b5294132b2edf13fe6ca6ae456204f3d749f623307cbb7a946f2/tomli-2.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8", size = 149053, upload-time = "2026-01-11T11:21:57.467Z" }, - { url = "https://files.pythonhosted.org/packages/e8/41/1eda3ca1abc6f6154a8db4d714a4d35c4ad90adc0bcf700657291593fbf3/tomli-2.4.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a", size = 243481, upload-time = "2026-01-11T11:21:58.661Z" }, - { url = "https://files.pythonhosted.org/packages/d2/6d/02ff5ab6c8868b41e7d4b987ce2b5f6a51d3335a70aa144edd999e055a01/tomli-2.4.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1", size = 251720, upload-time = "2026-01-11T11:22:00.178Z" }, - { url = "https://files.pythonhosted.org/packages/7b/57/0405c59a909c45d5b6f146107c6d997825aa87568b042042f7a9c0afed34/tomli-2.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b", size = 247014, upload-time = "2026-01-11T11:22:01.238Z" }, - { url = "https://files.pythonhosted.org/packages/2c/0e/2e37568edd944b4165735687cbaf2fe3648129e440c26d02223672ee0630/tomli-2.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51", size = 251820, upload-time = "2026-01-11T11:22:02.727Z" }, - { url = "https://files.pythonhosted.org/packages/5a/1c/ee3b707fdac82aeeb92d1a113f803cf6d0f37bdca0849cb489553e1f417a/tomli-2.4.0-cp312-cp312-win32.whl", hash = "sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729", size = 97712, upload-time = "2026-01-11T11:22:03.777Z" }, - { url = "https://files.pythonhosted.org/packages/69/13/c07a9177d0b3bab7913299b9278845fc6eaaca14a02667c6be0b0a2270c8/tomli-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da", size = 108296, upload-time = "2026-01-11T11:22:04.86Z" }, - { url = "https://files.pythonhosted.org/packages/18/27/e267a60bbeeee343bcc279bb9e8fbed0cbe224bc7b2a3dc2975f22809a09/tomli-2.4.0-cp312-cp312-win_arm64.whl", hash = "sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3", size = 94553, upload-time = "2026-01-11T11:22:05.854Z" }, - { url = "https://files.pythonhosted.org/packages/34/91/7f65f9809f2936e1f4ce6268ae1903074563603b2a2bd969ebbda802744f/tomli-2.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0", size = 154915, upload-time = "2026-01-11T11:22:06.703Z" }, - { url = "https://files.pythonhosted.org/packages/20/aa/64dd73a5a849c2e8f216b755599c511badde80e91e9bc2271baa7b2cdbb1/tomli-2.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e", size = 149038, upload-time = "2026-01-11T11:22:07.56Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8a/6d38870bd3d52c8d1505ce054469a73f73a0fe62c0eaf5dddf61447e32fa/tomli-2.4.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4", size = 242245, upload-time = "2026-01-11T11:22:08.344Z" }, - { url = "https://files.pythonhosted.org/packages/59/bb/8002fadefb64ab2669e5b977df3f5e444febea60e717e755b38bb7c41029/tomli-2.4.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e", size = 250335, upload-time = "2026-01-11T11:22:09.951Z" }, - { url = "https://files.pythonhosted.org/packages/a5/3d/4cdb6f791682b2ea916af2de96121b3cb1284d7c203d97d92d6003e91c8d/tomli-2.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c", size = 245962, upload-time = "2026-01-11T11:22:11.27Z" }, - { url = "https://files.pythonhosted.org/packages/f2/4a/5f25789f9a460bd858ba9756ff52d0830d825b458e13f754952dd15fb7bb/tomli-2.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f", size = 250396, upload-time = "2026-01-11T11:22:12.325Z" }, - { url = "https://files.pythonhosted.org/packages/aa/2f/b73a36fea58dfa08e8b3a268750e6853a6aac2a349241a905ebd86f3047a/tomli-2.4.0-cp313-cp313-win32.whl", hash = "sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86", size = 97530, upload-time = "2026-01-11T11:22:13.865Z" }, - { url = "https://files.pythonhosted.org/packages/3b/af/ca18c134b5d75de7e8dc551c5234eaba2e8e951f6b30139599b53de9c187/tomli-2.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87", size = 108227, upload-time = "2026-01-11T11:22:15.224Z" }, - { url = "https://files.pythonhosted.org/packages/22/c3/b386b832f209fee8073c8138ec50f27b4460db2fdae9ffe022df89a57f9b/tomli-2.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132", size = 94748, upload-time = "2026-01-11T11:22:16.009Z" }, - { url = "https://files.pythonhosted.org/packages/f3/c4/84047a97eb1004418bc10bdbcfebda209fca6338002eba2dc27cc6d13563/tomli-2.4.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6", size = 154725, upload-time = "2026-01-11T11:22:17.269Z" }, - { url = "https://files.pythonhosted.org/packages/a8/5d/d39038e646060b9d76274078cddf146ced86dc2b9e8bbf737ad5983609a0/tomli-2.4.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc", size = 148901, upload-time = "2026-01-11T11:22:18.287Z" }, - { url = "https://files.pythonhosted.org/packages/73/e5/383be1724cb30f4ce44983d249645684a48c435e1cd4f8b5cded8a816d3c/tomli-2.4.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66", size = 243375, upload-time = "2026-01-11T11:22:19.154Z" }, - { url = "https://files.pythonhosted.org/packages/31/f0/bea80c17971c8d16d3cc109dc3585b0f2ce1036b5f4a8a183789023574f2/tomli-2.4.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d", size = 250639, upload-time = "2026-01-11T11:22:20.168Z" }, - { url = "https://files.pythonhosted.org/packages/2c/8f/2853c36abbb7608e3f945d8a74e32ed3a74ee3a1f468f1ffc7d1cb3abba6/tomli-2.4.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702", size = 246897, upload-time = "2026-01-11T11:22:21.544Z" }, - { url = "https://files.pythonhosted.org/packages/49/f0/6c05e3196ed5337b9fe7ea003e95fd3819a840b7a0f2bf5a408ef1dad8ed/tomli-2.4.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8", size = 254697, upload-time = "2026-01-11T11:22:23.058Z" }, - { url = "https://files.pythonhosted.org/packages/f3/f5/2922ef29c9f2951883525def7429967fc4d8208494e5ab524234f06b688b/tomli-2.4.0-cp314-cp314-win32.whl", hash = "sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776", size = 98567, upload-time = "2026-01-11T11:22:24.033Z" }, - { url = "https://files.pythonhosted.org/packages/7b/31/22b52e2e06dd2a5fdbc3ee73226d763b184ff21fc24e20316a44ccc4d96b/tomli-2.4.0-cp314-cp314-win_amd64.whl", hash = "sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475", size = 108556, upload-time = "2026-01-11T11:22:25.378Z" }, - { url = "https://files.pythonhosted.org/packages/48/3d/5058dff3255a3d01b705413f64f4306a141a8fd7a251e5a495e3f192a998/tomli-2.4.0-cp314-cp314-win_arm64.whl", hash = "sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2", size = 96014, upload-time = "2026-01-11T11:22:26.138Z" }, - { url = "https://files.pythonhosted.org/packages/b8/4e/75dab8586e268424202d3a1997ef6014919c941b50642a1682df43204c22/tomli-2.4.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9", size = 163339, upload-time = "2026-01-11T11:22:27.143Z" }, - { url = "https://files.pythonhosted.org/packages/06/e3/b904d9ab1016829a776d97f163f183a48be6a4deb87304d1e0116a349519/tomli-2.4.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0", size = 159490, upload-time = "2026-01-11T11:22:28.399Z" }, - { url = "https://files.pythonhosted.org/packages/e3/5a/fc3622c8b1ad823e8ea98a35e3c632ee316d48f66f80f9708ceb4f2a0322/tomli-2.4.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df", size = 269398, upload-time = "2026-01-11T11:22:29.345Z" }, - { url = "https://files.pythonhosted.org/packages/fd/33/62bd6152c8bdd4c305ad9faca48f51d3acb2df1f8791b1477d46ff86e7f8/tomli-2.4.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d", size = 276515, upload-time = "2026-01-11T11:22:30.327Z" }, - { url = "https://files.pythonhosted.org/packages/4b/ff/ae53619499f5235ee4211e62a8d7982ba9e439a0fb4f2f351a93d67c1dd2/tomli-2.4.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f", size = 273806, upload-time = "2026-01-11T11:22:32.56Z" }, - { url = "https://files.pythonhosted.org/packages/47/71/cbca7787fa68d4d0a9f7072821980b39fbb1b6faeb5f5cf02f4a5559fa28/tomli-2.4.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b", size = 281340, upload-time = "2026-01-11T11:22:33.505Z" }, - { url = "https://files.pythonhosted.org/packages/f5/00/d595c120963ad42474cf6ee7771ad0d0e8a49d0f01e29576ee9195d9ecdf/tomli-2.4.0-cp314-cp314t-win32.whl", hash = "sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087", size = 108106, upload-time = "2026-01-11T11:22:34.451Z" }, - { url = "https://files.pythonhosted.org/packages/de/69/9aa0c6a505c2f80e519b43764f8b4ba93b5a0bbd2d9a9de6e2b24271b9a5/tomli-2.4.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd", size = 120504, upload-time = "2026-01-11T11:22:35.764Z" }, - { url = "https://files.pythonhosted.org/packages/b3/9f/f1668c281c58cfae01482f7114a4b88d345e4c140386241a1a24dcc9e7bc/tomli-2.4.0-cp314-cp314t-win_arm64.whl", hash = "sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4", size = 99561, upload-time = "2026-01-11T11:22:36.624Z" }, - { url = "https://files.pythonhosted.org/packages/23/d1/136eb2cb77520a31e1f64cbae9d33ec6df0d78bdf4160398e86eec8a8754/tomli-2.4.0-py3-none-any.whl", hash = "sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a", size = 14477, upload-time = "2026-01-11T11:22:37.446Z" }, -] - -[[package]] -name = "typing-extensions" -version = "4.15.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, -] - -[[package]] -name = "typing-inspection" -version = "0.4.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, -] diff --git a/tests/test_tool_resolver.py b/tests/test_tool_resolver.py index c8e7bce..ca8e4fb 100644 --- a/tests/test_tool_resolver.py +++ b/tests/test_tool_resolver.py @@ -1,7 +1,7 @@ """Unit tests for context_intelligence.tool_resolver. Tests the shared helpers (_first_entry, _first_destination, resolve_query_endpoint) -and ToolConfigResolver.read_destinations (including legacy synthesis โ€” spec ยง7 cases +and ToolConfigResolver.sources (including legacy synthesis โ€” spec ยง7 cases #9 and #10 at the unit level). """ @@ -134,51 +134,51 @@ async def test_debug_log_emitted(self, caplog: Any) -> None: # --------------------------------------------------------------------------- -# TestToolConfigResolverReadDestinations +# TestToolConfigResolverSources # --------------------------------------------------------------------------- -class TestToolConfigResolverReadDestinations: - """ToolConfigResolver.read_destinations โ€” parsing and legacy synthesis.""" +class TestToolConfigResolverSources: + """ToolConfigResolver.sources โ€” parsing and legacy synthesis.""" def test_explicit_mapping_parsed(self) -> None: - """Explicit read_destinations key โ†’ parsed into ReadEndpoint dict.""" - from context_intelligence.tool_resolver import ReadEndpoint, ToolConfigResolver + """Explicit sources key โ†’ parsed into Source dict.""" + from context_intelligence.tool_resolver import Source, ToolConfigResolver config = { - "read_destinations": { + "sources": { "default": {"url": "http://read.example.com", "api_key": "read-key"}, } } resolver = ToolConfigResolver(config, _make_coordinator()) - rd = resolver.read_destinations + rd = resolver.sources assert "default" in rd - assert isinstance(rd["default"], ReadEndpoint) + assert isinstance(rd["default"], Source) assert rd["default"].url == "http://read.example.com" assert rd["default"].api_key == "read-key" assert rd["default"].name == "default" def test_explicit_empty_dict_returns_empty(self) -> None: - """Explicit read_destinations={} โ†’ {} (no legacy synthesis).""" + """Explicit sources={} โ†’ {} (no legacy synthesis).""" from context_intelligence.tool_resolver import ToolConfigResolver - config = {"read_destinations": {}} + config = {"sources": {}} resolver = ToolConfigResolver(config, _make_coordinator()) - assert resolver.read_destinations == {} + assert resolver.sources == {} def test_non_dict_entry_skipped(self) -> None: - """Non-dict entries under read_destinations are silently skipped.""" + """Non-dict entries under sources are silently skipped.""" from context_intelligence.tool_resolver import ToolConfigResolver config = { - "read_destinations": { + "sources": { "bad": "not-a-dict", "good": {"url": "http://read.example.com", "api_key": "k"}, } } resolver = ToolConfigResolver(config, _make_coordinator()) - rd = resolver.read_destinations + rd = resolver.sources assert "bad" not in rd assert "good" in rd @@ -187,37 +187,37 @@ def test_url_api_key_stripped(self) -> None: from context_intelligence.tool_resolver import ToolConfigResolver config = { - "read_destinations": { + "sources": { "default": {"url": " http://read.example.com ", "api_key": " key "}, } } resolver = ToolConfigResolver(config, _make_coordinator()) - rd = resolver.read_destinations + rd = resolver.sources assert rd["default"].url == "http://read.example.com" assert rd["default"].api_key == "key" # --- Case #9: legacy synthesis when BOTH scalars present --- def test_absent_key_both_scalars_synthesizes_default(self) -> None: - """Case #9 unit: absent read_destinations + both scalars โ†’ synthesized default.""" - from context_intelligence.tool_resolver import ReadEndpoint, ToolConfigResolver + """Case #9 unit: absent sources key + both scalars โ†’ synthesized default.""" + from context_intelligence.tool_resolver import Source, ToolConfigResolver config = { "context_intelligence_server_url": "http://legacy.example.com", "context_intelligence_api_key": "legacy-key", } resolver = ToolConfigResolver(config, _make_coordinator()) - rd = resolver.read_destinations + rd = resolver.sources assert "default" in rd - assert isinstance(rd["default"], ReadEndpoint) + assert isinstance(rd["default"], Source) assert rd["default"].url == "http://legacy.example.com" assert rd["default"].api_key == "legacy-key" # --- Case #10: url-only โ†’ no synthesis --- def test_absent_key_url_only_no_synthesis(self) -> None: - """Case #10 unit: absent read_destinations + url only โ†’ {} (no synthesis).""" + """Case #10 unit: absent sources key + url only โ†’ {} (no synthesis).""" from context_intelligence.tool_resolver import ToolConfigResolver config = { @@ -225,27 +225,27 @@ def test_absent_key_url_only_no_synthesis(self) -> None: # no context_intelligence_api_key } resolver = ToolConfigResolver(config, _make_coordinator()) - assert resolver.read_destinations == {} + assert resolver.sources == {} def test_absent_key_no_scalars_returns_empty(self) -> None: """Absent key + no scalars โ†’ {} (neither synthesis nor parse).""" from context_intelligence.tool_resolver import ToolConfigResolver resolver = ToolConfigResolver({}, _make_coordinator()) - assert resolver.read_destinations == {} + assert resolver.sources == {} - def test_read_destinations_cached_after_first_access(self) -> None: - """read_destinations is cached โ€” same object returned on second access.""" + def test_sources_cached_after_first_access(self) -> None: + """sources is cached โ€” same object returned on second access.""" from context_intelligence.tool_resolver import ToolConfigResolver config = { - "read_destinations": { + "sources": { "default": {"url": "http://read.example.com", "api_key": "k"}, } } resolver = ToolConfigResolver(config, _make_coordinator()) - rd1 = resolver.read_destinations - rd2 = resolver.read_destinations + rd1 = resolver.sources + rd2 = resolver.sources assert rd1 is rd2 # --- env is excluded from legacy synthesis (tier 3 only) --- @@ -266,7 +266,7 @@ def test_absent_key_env_does_not_synthesize_into_tier1(self) -> None: } with patch.dict(os.environ, env_patch): resolver = ToolConfigResolver({}, _make_coordinator()) - rd = resolver.read_destinations + rd = resolver.sources - # Env must NOT synthesize into read_destinations โ€” result is empty dict. + # Env must NOT synthesize into sources โ€” result is empty dict. assert rd == {} From 6cd4f0250bf5632e214d3d92fffaee0c5930f377 Mon Sep 17 00:00:00 2001 From: colombod Date: Tue, 23 Jun 2026 12:09:22 +0000 Subject: [PATCH 3/5] fix(hook): source metadata working_dir from session.working_dir capability, not events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit metadata.json recorded `working_dir` by scraping it from event payloads (`data.get("working_dir", "")`), which was wrong on three counts: - working_dir is a SESSION attribute, not an event attribute; - only session:start/fork events carry it, so if the first event seen for a session was any other type, metadata was written with working_dir="" and only corrected if/when session:start later reached this handler (and never, for forwarded/partial sessions); - a present-but-empty "" in the event payload was stored as-is (the default in .get(key, "") only applies when the key is absent, not when it is empty). Source it from the session instead. Add HookConfigResolver.working_dir -- a live (uncached) read of the session.working_dir capability (returns "" when unavailable), mirroring the access the resolver already uses for project_slug. The LoggingHandler already holds the resolver, so both metadata sites now use self._resolver.working_dir: - _ensure_metadata: working_dir = self._resolver.working_dir - _enrich_metadata_from_session_init: self._resolver.working_dir or meta.get(...) (the `or meta.get` keeps a prior non-empty value if the capability read is transiently empty). Reading live (not cached) also tracks mid-session working-directory changes. Tests: HookConfigResolver.working_dir (capability present / absent / empty / non-str / no get_capability / not cached); and metadata sourcing -- working_dir filled from the resolver when the first event is not session:start, a present-but-empty event working_dir no longer wins, and an empty resolver value does not clobber a previously-stored non-empty value. Full hook module suite: 380 passing. ๐Ÿค– Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> --- .../config_resolver.py | 15 ++ .../handlers/logging_handler.py | 4 +- .../tests/test_config_resolver.py | 83 ++++++++ .../tests/test_logging_handler.py | 195 +++++++++++++++++- .../tests/test_logging_handler_fanout.py | 1 + .../test_logging_handler_last_event_at.py | 1 + .../test_logging_handler_server_dispatch.py | 1 + .../tests/test_silent_by_default.py | 1 + 8 files changed, 296 insertions(+), 5 deletions(-) diff --git a/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/config_resolver.py b/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/config_resolver.py index 18cd124..1524fff 100644 --- a/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/config_resolver.py +++ b/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/config_resolver.py @@ -155,6 +155,21 @@ def project_slug(self) -> str: self._project_slug = str(raw) return self._project_slug + @property + def working_dir(self) -> str: + """Absolute session working directory from the ``session.working_dir`` capability. + + Read live (not cached) so it reflects mid-session working-directory changes. + Returns "" when the capability is unavailable. + """ + get_cap = getattr(self._coordinator, "get_capability", None) + if get_cap is None: + return "" + wd = get_cap("session.working_dir") + if not isinstance(wd, str) or not wd: + return "" + return wd + @property def base_path(self) -> Path: """Resolved base path for project storage. diff --git a/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/handlers/logging_handler.py b/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/handlers/logging_handler.py index bada232..166b5e5 100644 --- a/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/handlers/logging_handler.py +++ b/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/handlers/logging_handler.py @@ -299,7 +299,7 @@ def _ensure_metadata( "started_at": data.get("timestamp", ""), "last_event_at": data.get("timestamp", ""), "status": "running", - "working_dir": data.get("working_dir", ""), + "working_dir": self._resolver.working_dir, } meta_path.write_text(json.dumps(metadata, separators=(",", ":"))) @@ -334,7 +334,7 @@ def _enrich_metadata_from_session_init( or meta.get("parent_id", "") ) meta["started_at"] = data.get("timestamp", "") or meta.get("started_at", "") - meta["working_dir"] = data.get("working_dir", "") or meta.get("working_dir", "") + meta["working_dir"] = self._resolver.working_dir or meta.get("working_dir", "") for field in _OPTIONAL_METADATA_FIELDS: value = data.get(field) diff --git a/modules/hook-context-intelligence/tests/test_config_resolver.py b/modules/hook-context-intelligence/tests/test_config_resolver.py index 4b2194e..ff20b10 100644 --- a/modules/hook-context-intelligence/tests/test_config_resolver.py +++ b/modules/hook-context-intelligence/tests/test_config_resolver.py @@ -702,3 +702,86 @@ def test_handles_windows_path(self) -> None: def test_empty_string_returns_default(self) -> None: """Empty path string returns the default project slug.""" assert _slugify_path("") == "default" + + +class TestWorkingDir: + """working_dir property โ€” live read of the session.working_dir capability. + + Unlike project_slug (cached), working_dir is read live on every access so it + reflects mid-session working-directory changes. It returns "" when the + capability is unavailable. + """ + + def test_returns_capability_value_when_present(self) -> None: + """working_dir returns the path string from the session.working_dir capability.""" + coordinator = MagicMock() + coordinator.get_capability = MagicMock(return_value="/home/user/project") + resolver = ConfigResolver(config={}, coordinator=coordinator) + + assert resolver.working_dir == "/home/user/project" + + def test_returns_empty_string_when_capability_returns_none(self) -> None: + """working_dir returns '' when get_capability('session.working_dir') is None.""" + coordinator = MagicMock() + coordinator.get_capability = MagicMock(return_value=None) + resolver = ConfigResolver(config={}, coordinator=coordinator) + + assert resolver.working_dir == "" + + def test_returns_empty_string_when_capability_returns_empty_string(self) -> None: + """working_dir returns '' when the capability returns '' (present-but-empty).""" + coordinator = MagicMock() + coordinator.get_capability = MagicMock(return_value="") + resolver = ConfigResolver(config={}, coordinator=coordinator) + + assert resolver.working_dir == "" + + def test_returns_empty_string_when_capability_returns_non_str(self) -> None: + """working_dir returns '' when the capability returns a non-string type.""" + coordinator = MagicMock() + coordinator.get_capability = MagicMock(return_value=42) + resolver = ConfigResolver(config={}, coordinator=coordinator) + + assert resolver.working_dir == "" + + def test_returns_empty_string_when_coordinator_lacks_get_capability(self) -> None: + """working_dir returns '' when the coordinator has no get_capability method.""" + bare = _make_bare_coordinator() # plain object(), no get_capability + resolver = ConfigResolver(config={}, coordinator=bare) + + assert resolver.working_dir == "" + + def test_returns_empty_string_when_coordinator_is_none(self) -> None: + """working_dir returns '' when coordinator is None.""" + resolver = ConfigResolver(config={}, coordinator=None) + + assert resolver.working_dir == "" + + def test_not_cached_reads_live(self) -> None: + """working_dir is NOT cached โ€” each access re-reads the capability. + + This is intentional: working_dir must reflect mid-session cwd changes, + unlike project_slug which is cached after first access. + """ + coordinator = MagicMock() + coordinator.get_capability = MagicMock(return_value="/first/path") + resolver = ConfigResolver(config={}, coordinator=coordinator) + + first = resolver.working_dir + assert first == "/first/path" + + # Simulate capability value changing mid-session. + coordinator.get_capability = MagicMock(return_value="/second/path") + second = resolver.working_dir + assert second == "/second/path" + + # Contrast with project_slug which IS cached. + assert first != second + + def test_returns_str_type(self) -> None: + """working_dir always returns a str.""" + coordinator = MagicMock() + coordinator.get_capability = MagicMock(return_value="/some/path") + resolver = ConfigResolver(config={}, coordinator=coordinator) + + assert isinstance(resolver.working_dir, str) diff --git a/modules/hook-context-intelligence/tests/test_logging_handler.py b/modules/hook-context-intelligence/tests/test_logging_handler.py index 904897e..f1113cc 100644 --- a/modules/hook-context-intelligence/tests/test_logging_handler.py +++ b/modules/hook-context-intelligence/tests/test_logging_handler.py @@ -20,11 +20,16 @@ class _FakeResolver: """Minimal resolver adapter for testing LoggingHandler in isolation.""" def __init__( - self, base_path: Path, project_slug: str, workspace: str = "test-workspace" + self, + base_path: Path, + project_slug: str, + workspace: str = "test-workspace", + working_dir: str = "", ) -> None: self.base_path = base_path self.project_slug = project_slug self.workspace = workspace + self.working_dir = working_dir def session_dir(self, session_id: str) -> Path: return self.base_path / self.project_slug / "sessions" / session_id / "context-intelligence" @@ -91,14 +96,19 @@ async def test_writes_metadata_json_with_correct_fields(self, tmp_path: Path) -> LoggingHandler, ) - handler = LoggingHandler(_FakeResolver(tmp_path, "proj", workspace="my-project")) + # working_dir comes from the resolver (session capability), not the event payload. + handler = LoggingHandler( + _FakeResolver( + tmp_path, "proj", workspace="my-project", working_dir="/home/user/project" + ) + ) await handler( "session:start", { "session_id": "s1", "parent_id": "p1", "timestamp": "2026-01-15T10:00:00Z", - "working_dir": "/home/user/project", + # working_dir in event data is NOT used for metadata; resolver value is. }, ) meta_path = tmp_path / "proj" / "sessions" / "s1" / "context-intelligence" / "metadata.json" @@ -646,3 +656,182 @@ async def test_event_data_parent_id_wins_over_config(self, tmp_path: Path) -> No ).read_text() ) assert meta["parent_id"] == "from-event" + + +# --------------------------------------------------------------------------- +# TestWorkingDirFromResolver โ€” working_dir is a session attribute, not event data +# --------------------------------------------------------------------------- +class TestWorkingDirFromResolver: + """working_dir in metadata.json comes from the resolver (session capability), not the event. + + This class covers three key guarantees: + (a) working_dir is populated from the resolver even when the first event is NOT + session:start and carries no working_dir in its payload. + (b) A present-but-empty working_dir in the event payload does NOT win โ€” the resolver + value is used (event-payload empty string was the old bug). + (c) When the resolver's working_dir is "" (capability unavailable), metadata gracefully + stores "", and _enrich does not clobber a previously-set non-empty value. + """ + + async def test_working_dir_from_resolver_on_non_session_start_first_event( + self, tmp_path: Path + ) -> None: + """(a) working_dir comes from resolver when first event is tool:call (no session:start).""" + from amplifier_module_hook_context_intelligence.handlers.logging_handler import ( + LoggingHandler, + ) + + resolver = _FakeResolver(tmp_path, "proj", working_dir="/resolver/working/dir") + handler = LoggingHandler(resolver) + + # First event is NOT session:start โ€” old code would have stored "" here. + await handler( + "tool:call", + { + "session_id": "s1", + "timestamp": "2026-01-15T10:00:01Z", + "tool_name": "read_file", + # No working_dir in payload at all. + }, + ) + + meta = json.loads( + ( + tmp_path / "proj" / "sessions" / "s1" / "context-intelligence" / "metadata.json" + ).read_text() + ) + assert meta["working_dir"] == "/resolver/working/dir" + + async def test_present_but_empty_event_working_dir_does_not_win( + self, tmp_path: Path + ) -> None: + """(b) An empty working_dir in the event payload does not clobber the resolver value. + + The old code used data.get("working_dir", ""), so a payload that carries + {"working_dir": ""} (present-but-empty) would return "" and store it. + New code ignores event working_dir entirely; the resolver always wins. + """ + from amplifier_module_hook_context_intelligence.handlers.logging_handler import ( + LoggingHandler, + ) + + resolver = _FakeResolver(tmp_path, "proj", working_dir="/real/path") + handler = LoggingHandler(resolver) + + # Event deliberately carries working_dir="" (present-but-empty). + await handler( + "session:start", + { + "session_id": "s1", + "timestamp": "2026-01-15T10:00:00Z", + "working_dir": "", # Present but empty โ€” old code would have stored "". + }, + ) + + meta = json.loads( + ( + tmp_path / "proj" / "sessions" / "s1" / "context-intelligence" / "metadata.json" + ).read_text() + ) + # Resolver's value wins over the event's empty string. + assert meta["working_dir"] == "/real/path" + + async def test_resolver_working_dir_empty_stores_empty_gracefully( + self, tmp_path: Path + ) -> None: + """(c-i) When resolver.working_dir is '', metadata working_dir is '' (graceful).""" + from amplifier_module_hook_context_intelligence.handlers.logging_handler import ( + LoggingHandler, + ) + + resolver = _FakeResolver(tmp_path, "proj", working_dir="") + handler = LoggingHandler(resolver) + + await handler( + "session:start", + { + "session_id": "s1", + "timestamp": "2026-01-15T10:00:00Z", + }, + ) + + meta = json.loads( + ( + tmp_path / "proj" / "sessions" / "s1" / "context-intelligence" / "metadata.json" + ).read_text() + ) + assert meta["working_dir"] == "" + + async def test_enrich_does_not_clobber_prior_value_with_empty_resolver( + self, tmp_path: Path + ) -> None: + """(c-ii) _enrich does not overwrite a good working_dir with '' from an empty resolver. + + Scenario: first event stores a non-empty working_dir via the resolver, then + _enrich_metadata_from_session_init is called (session:start arrives late) while + the resolver's working_dir returns "". The prior value must be preserved. + """ + from amplifier_module_hook_context_intelligence.handlers.logging_handler import ( + LoggingHandler, + ) + + # Phase 1: resolver has a working_dir โ€” first event stores it. + resolver = _FakeResolver(tmp_path, "proj", working_dir="/first/event/dir") + handler = LoggingHandler(resolver) + + await handler( + "tool:call", + { + "session_id": "s1", + "timestamp": "2026-01-15T10:00:01Z", + }, + ) + + # Verify initial state. + meta_path = tmp_path / "proj" / "sessions" / "s1" / "context-intelligence" / "metadata.json" + meta = json.loads(meta_path.read_text()) + assert meta["working_dir"] == "/first/event/dir" + + # Phase 2: resolver now returns "" (e.g. capability went away). + resolver.working_dir = "" + + # session:start arrives (triggers _enrich). + await handler( + "session:start", + { + "session_id": "s1", + "timestamp": "2026-01-15T10:00:02Z", + # No working_dir in event payload either. + }, + ) + + meta = json.loads(meta_path.read_text()) + # Prior non-empty value must be preserved; "" from resolver must not clobber. + assert meta["working_dir"] == "/first/event/dir" + + async def test_working_dir_from_resolver_overrides_event_on_session_start( + self, tmp_path: Path + ) -> None: + """Resolver value wins even when event carries a different non-empty working_dir.""" + from amplifier_module_hook_context_intelligence.handlers.logging_handler import ( + LoggingHandler, + ) + + resolver = _FakeResolver(tmp_path, "proj", working_dir="/resolver/path") + handler = LoggingHandler(resolver) + + await handler( + "session:start", + { + "session_id": "s1", + "timestamp": "2026-01-15T10:00:00Z", + "working_dir": "/event/path", # Different value in event โ€” resolver wins. + }, + ) + + meta = json.loads( + ( + tmp_path / "proj" / "sessions" / "s1" / "context-intelligence" / "metadata.json" + ).read_text() + ) + assert meta["working_dir"] == "/resolver/path" diff --git a/modules/hook-context-intelligence/tests/test_logging_handler_fanout.py b/modules/hook-context-intelligence/tests/test_logging_handler_fanout.py index 46e996b..6378968 100644 --- a/modules/hook-context-intelligence/tests/test_logging_handler_fanout.py +++ b/modules/hook-context-intelligence/tests/test_logging_handler_fanout.py @@ -21,6 +21,7 @@ def __init__(self, base_path: Path, project_slug: str = "proj") -> None: self.workspace: str | None = "ws" self.parent_id: str = "" self.resolve_instance_id: str = "" + self.working_dir: str = "" def session_dir(self, session_id: str) -> Path: return self.base_path / self.project_slug / "sessions" / session_id / "context-intelligence" diff --git a/modules/hook-context-intelligence/tests/test_logging_handler_last_event_at.py b/modules/hook-context-intelligence/tests/test_logging_handler_last_event_at.py index 2f9b65e..febda7f 100644 --- a/modules/hook-context-intelligence/tests/test_logging_handler_last_event_at.py +++ b/modules/hook-context-intelligence/tests/test_logging_handler_last_event_at.py @@ -22,6 +22,7 @@ def __init__( self.base_path = base_path self.project_slug = project_slug self.workspace = workspace + self.working_dir: str = "" def session_dir(self, session_id: str) -> Path: return self.base_path / self.project_slug / "sessions" / session_id / "context-intelligence" diff --git a/modules/hook-context-intelligence/tests/test_logging_handler_server_dispatch.py b/modules/hook-context-intelligence/tests/test_logging_handler_server_dispatch.py index efead83..1aa5922 100644 --- a/modules/hook-context-intelligence/tests/test_logging_handler_server_dispatch.py +++ b/modules/hook-context-intelligence/tests/test_logging_handler_server_dispatch.py @@ -42,6 +42,7 @@ def __init__( self.workspace = workspace self.parent_id = parent_id self.resolve_instance_id = resolve_instance_id + self.working_dir: str = "" def session_dir(self, session_id: str) -> Path: return self.base_path / self.project_slug / "sessions" / session_id / "context-intelligence" diff --git a/modules/hook-context-intelligence/tests/test_silent_by_default.py b/modules/hook-context-intelligence/tests/test_silent_by_default.py index 13b4c60..20d1059 100644 --- a/modules/hook-context-intelligence/tests/test_silent_by_default.py +++ b/modules/hook-context-intelligence/tests/test_silent_by_default.py @@ -30,6 +30,7 @@ def _make_resolver(tmp_path, *, server_url=None, api_key=None): context_intelligence_server_url=server_url, context_intelligence_api_key=api_key, workspace="test-workspace", + working_dir="", dispatch_timeout=10.0, dispatch_failure_threshold=3, dispatch_queue_capacity=256, From 0c20c12e92b56b7bec355b9145ce896577c17e28 Mon Sep 17 00:00:00 2001 From: colombod Date: Tue, 23 Jun 2026 12:19:27 +0000 Subject: [PATCH 4/5] docs(readme): clarify the read path supports a single source only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make the read-side config constraints explicit in the "Query tools" section: - Only ONE read source is supported in this version; the read path does not fan out to multiple sources. If more than one `sources` entry is present, only the first (insertion order) is used and the rest are ignored. - State plainly that with nothing configured, the read tools use the FIRST configured `destination` in the hook config as their read source (tier 2). - Reinforce the single-source rule in the YAML example comments (name it `default`). ๐Ÿค– Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7d35c8d..b0926fb 100644 --- a/README.md +++ b/README.md @@ -310,16 +310,19 @@ The hook config above governs **where events are written** (the upload / fan-out Each field walks the chain independently (a tier that supplies a `url` but no `api_key` lets `api_key` fall through). **Env is a true fallback โ€” it never outranks the hook destination** (tier 2). There are **no** `*_PRIVATE_*` environment variables; the only env names consulted are the canonical `AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL` / `_API_KEY`. -**`sources`** is a dict keyed by name, mirroring the hook's `destinations` shape. The **first** entry (declaration / insertion order) is used. Reach for it only when the read endpoint must differ from the upload destination (e.g. a read replica or a debugging override) โ€” it overrides the **read path only** and does not change where the hook uploads: +**`sources`** is a mapping keyed by name, mirroring the hook's `destinations` shape. **Only a single read source is supported in this version** โ€” the read path does **not** fan out to multiple sources. Configure exactly one entry (conventionally named `default`); if more than one is present, only the **first** (declaration / insertion order) is used and the rest are ignored. + +In most setups you configure nothing here: **with no `sources` set, the read tools use the first configured `destination` in the hook config as their read source** (tier 2 below). Reach for `sources` only when the read endpoint must differ from the upload destination (e.g. a read replica or a debugging override) โ€” it overrides the **read path only** and does not change where the hook uploads: ```yaml -# ~/.amplifier/settings.yaml โ€” only needed when queries must hit a DIFFERENT server than uploads +# ~/.amplifier/settings.yaml โ€” only needed when queries must hit a DIFFERENT server than uploads. # One config namespace covers both graph_query and blob_read tools โ€” configure once. +# Only ONE read source is supported; name it `default`. overrides: tool-context-intelligence-query: config: sources: - default: + default: # the single read source (only the first entry is honored) url: "http://read-replica.example.com" api_key: "${CI_READ_KEY}" # secret lives in keys.env, referenced here ``` From f049931181540734356396c4902387db4523974b Mon Sep 17 00:00:00 2001 From: colombod Date: Tue, 23 Jun 2026 12:22:28 +0000 Subject: [PATCH 5/5] style(hook): apply root ruff formatting to test_logging_handler.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The CI Lint job runs `ruff format --check .` from the repo root, whose ruff config differs slightly from the per-module venv config used during development. Reformat the new working_dir tests with the root config so the Lint job passes. No behavior change. ๐Ÿค– Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> --- .../tests/test_logging_handler.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/modules/hook-context-intelligence/tests/test_logging_handler.py b/modules/hook-context-intelligence/tests/test_logging_handler.py index f1113cc..0847ce8 100644 --- a/modules/hook-context-intelligence/tests/test_logging_handler.py +++ b/modules/hook-context-intelligence/tests/test_logging_handler.py @@ -702,9 +702,7 @@ async def test_working_dir_from_resolver_on_non_session_start_first_event( ) assert meta["working_dir"] == "/resolver/working/dir" - async def test_present_but_empty_event_working_dir_does_not_win( - self, tmp_path: Path - ) -> None: + async def test_present_but_empty_event_working_dir_does_not_win(self, tmp_path: Path) -> None: """(b) An empty working_dir in the event payload does not clobber the resolver value. The old code used data.get("working_dir", ""), so a payload that carries @@ -736,9 +734,7 @@ async def test_present_but_empty_event_working_dir_does_not_win( # Resolver's value wins over the event's empty string. assert meta["working_dir"] == "/real/path" - async def test_resolver_working_dir_empty_stores_empty_gracefully( - self, tmp_path: Path - ) -> None: + async def test_resolver_working_dir_empty_stores_empty_gracefully(self, tmp_path: Path) -> None: """(c-i) When resolver.working_dir is '', metadata working_dir is '' (graceful).""" from amplifier_module_hook_context_intelligence.handlers.logging_handler import ( LoggingHandler,

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 literal 113846 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 B=PMxnk5SEU?zk>gilf$4d1 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�% zzJO9i^^zu(OD#GVNL;@pzqm~cB*<|R1|i&NG-Aady{CINc>Lyv|- zl6e;6{aA;Qb<;crx`XWKoVD0B6#g+>h4hB7qP-T-2C1@s)OB{Q`W7ilPcsURzF|Mr zQ&E8qx%v9x%V(tjX#sZMzx;3}(yfMMzdz=9(+DGUi(j{~`IxdL4K{J{iOmwfAr@4} zG@b1`7EG}*e~gHUOG(ZzHtjQYzvVvArtm8fgVa?2K^Vh!!jp){W&5QS#M7OYDQkBp z0UO85&OY+{x6sxS$L)UuejZG<`~LUYG=j5%_O;g9mNG3(C_zVgNRixIlh3v+H&+ry zb*ZQMR&KPFm%?1k4B#pEZ%+3%?=PK?QF=Gm268#=%XTT#jYq5<<1MdimmvjB{s0~T zJQhr1re6S|bY#NxVe$A~JD>dHfgAywJ*#c8YQ3;~$Ob>6re8%w%UWWMXf#G|evM z2ILTOy}?T*+2PDUNCeAA=(}kAQx3R zI@;3K3}{~~B5JwT%lk%xSjkj*qk>hzY)+1<*<|x4B*$6VDc!lcRj}MT`6b&NKDUHW4dq!KURT{lT zbv&TGxdHda{OSoNT*V0Y1XF=teY3~52Ja=sjXl^~4XDg}Ng7&e9aP?r@gLhnu@?;h+vC>bnaEoDQ8Z18Vz^lF7TAG5Da=&Et4LAiAJob8dn={C$%WJY1jWFso1 zjZil!AT95Cq_LF_ru-J~PSwi@vnyg*5s&-v&4al9=}sl{CoNw^?6~75e_0WhGC6I_ zwktcXP8+U_>4x2Pepb%*X*TW4^z+H!>AbgOGWqKFq*i1DpjZ-5>?79JKH(7L>s+f! znnl#qqEo|D{}>u98e%}e^}u2HcMShYEn0EE-ue1a;+yA8y7E+r4>6ZaHt`W+Y&yHN z()*PA4576|o&K%7HTp}&=$-s!mA01YmX_(oC}ph*Uat;4H!!&MIpjl`KZyl1w5&Ns%%E33DDU<6bO@OR^X z=*szNig9BPsIkB}5BngFPX7|rDgeN_;e?L|)MmT%9Tp+B8&V$CE)dQBoE_=Y*<_i` zsBy<)FfIrsU)G`y$}W?RL&=jSNzzJDJjIneOaYoPTp>ESx+1_dCWxR5V1oqYLW z7H(bvzQa(Q8Q}SxADRV)&|`X_xaX=X%Ah$54K)xGzBi7ccjh_DDEn=gO7*S&Q|hvc83s#P|WaKdv*(C-F2Is5frR>RDgfBKN< zBmOb4wLVw)DM{ti!~_ZudbkM~v}vPZkkxY>lR{`Jp^30SozqR#(p~;WOD(14UjcuWEka6mH4~H|NQ7W zbXI%TkWg1-U79rTkqxOBfI8oFG@mSED`(6v;Dwt4fpD55fe7VSKwm%ugDMcZ)2+2V zqYSg6GNe-III?PjmjOLdosF$R?pHk?V-CVdc_>T8_z7D?#$gJ7D|Br*XV()41!4!u zH_rR*Z@v8ukJ^xetk#_~b38F*(V}1@ekia*UDuY(+*H>ZLdmvL*B73>U zGb|>oaqEkw@o@06{4C{b`PUgT3FkfBI5;?V+|!MXZ}vj|Tx0Y{Vbd6oTuqK0aBe;mzI#Wz|60GoI&FPv%^c09LsR;-#9d0W00R$nPMg=F4v$U9w4?Tp|XDDH`(&o4NuZc(l%IaEO?$Jxwr7HIyXWShhfxn~#rJySKU2IAypO)Xg~`o@nKvRP!R8PG>P5 zox-ImuTt6o=)S^ps(*48ykBR{c2?F8-L0b`uhi^a3`NpF1}yO^i>4r-^Z^fa?_i*d zT9|>fu05`%#lzM`U36u)OU&Y~jth=@XjFs6Otm_aA)&rjUEr?llj~iA$xY2Et+lu{ z%8O|>93fmhTmg@xwYlZSIx&Z?k-P43C-D!syW)s;nbSc=aVc!W7NHaYg6N-7mS*@K z7fV_nttCut5MUuKNYP$iUfMNs|1T$gFIe6z<7XLPpP!qV%av1{%*;>4&relfo143& zxzXXuhUHbnthPBj47Jc*>g%ptsf?wK^yKZw1~C2QlQ8+Mss?!N;%rGzGSS9yk>S*-uJG~MZU^N>>tN0wu^yJiVE}|O+2NbrgAJ= zEjHaW1z9h9Or7reNsY?Jv*^;!o?eh?sFfL))qm!PQ1G$2_vFGsa-d$$-hLK6P-5A4 zp}*O?kTr3B@wq@>IbHmPLFPk|Z{g8zqd{MYLEmZ-SiVrolAn=Q1QjJm$1p|GfkDEBs~PrUp(!ywX))sa7ku=8)xe5a6t&6VBjeb>m#)wnm&&| zteC|V*oT-hkYzOM1RU}Ywky}!pNQL$W z(pc884o!YrLJo$$v{YF+YdInDv8qA@!W2q>KBDvKh*12>r^M3;V*sOu&(WS>MO#HB zDkj2=w^P-_`-TTcy@p)TVw$1G#rR0`SUfJ@dfZybI+y6vhsWnT6)*JpJoCjM`o@cHghXf@;yI#=@W{p zZMk4c2q77`!AXN5wQIFRNgVk))vaA^8Cf|@)pu4KaTy5UjoFULz_7?UGe2dcc*GF( zW1r8(e`I8s9#$wT`iAOE?lu;KjFf#@MoC6V+|Y4l;z@vdP^a6WANC6Y!T9MH1*x(} zd4;8wih|;vKm^|(JuxxyOJn(24-6fWFl%gMWi>4DdQ>O)T`YgCvkbZ}vl`fNBx5S6 zC`UwuyZ4-O4?C??5<1xCEw^KZlJP3)SC(a^$Kyl(f?cq8C^Q=tQ}^t@!D{!|&CQK1 zjm=K%%`I0k*8`;XkGgb*Sbq1pJ>?!oy})B%rln!C*+=z!lrHZ&#nUrVJ)BN;i$-x@ zOU*CM5pFUz!e9Uc)bMFfU0A zhJgziCHvjhSAiVfu=mKbC$9P6(f|3bqs;z~H8%Uk;W#q~{3nkOBR5E_`FT$j*vqVj z6_PW$Tt?ZX&C=4j@I?a?+H;YemJuBlL16RxZvvx->2HDC0WB`T;cJMPTD`aTgMc#OgtDmUUC7%v zZ$57bR;L54LSW!SP!Lyr3jnsyy+c=4Oh7%Fsp(0;F0bo>q?p*U(=dk8BY3%Q&U*=8 zX-?ZCNff>=PLg?BIiAo@`|kG{!npc)&Q8vIJ$rdn>b6$r6$Sns2BJP9)Gbudp3~Q_ z=`ZI`yLHN#7?S2p-Rh)&)v;h!DO^Q8bnkdj%lIa|uWK{M*!W{UVM_eqk9g_bc;-ENTS*@S`+?THQR6BY=?;&zwsgYRG_ z`}^+8k|ncGKp&Q+ZGqsN15sg~_1J(=>9G!ub&mw{&85@;FB0;GztHdBqoR2|`~zzx zCpD*}Uo1*=Y9hI?$oLf%6i!>R0CdE~$=Ti0qrrdMPr>!g{BZu|S|sQ*sO*Oq(1I9k znB8JB@^C(b<6Gabdv&i4t68+UUczG+sepPr@9p|;?A`ssG^y)gAp6!(gmStF&5jl* zym8*(l#mz=Jwe00lHg%BkB?WCS04<2R03>WjzUwi*e4!?&;6tnct+HHe}1J$S@He!=@W>0XO5?q8dXnR z5B^{&YADp0FDhS5pY!wcv$M0?`3P68fUO94JzM_!mx7Lt4_Fle{G(ue9rB7?!tpIy zgTz6`8eJDh2Cp;*CgujZ8eXISRlT2>k-k125s^l?j)5if{z`9(Q$3!YGq{stj-+KA z(dywkkBNvT-xO1MJ-NQ4(pp+5xt$c?)Zy&vs>A(6kEg|6aBx)QTvXh-?H1jv!~C0Tcdvgj%ghQCJvWP@mZe&h=s9ZtZ{4l#%HJ5*c7g zodz130QU)Hy7Nyoj>dof;;@!f%sZ+>aS?^J{2C zU|OWcwV3kCtuaw4Z|MyW7cIbVwN00Lc}LD98dPv(&*Fq_NQ(JG}Ao!=Axd z8vEzyz~=_2v)12Tt6PrZLOD@5|B}$N`=8**P<6Kp83%_0V3-g5Qb3E7(|x3hmR23` z2my8jT^$`bLO^T+e63Cn)=$^QOKNLt2M6Vql;FTNzr@Gb$Vj^Z>b@~mH7nx^(0gER z4g4Pt5byv~Nf{Z?gNK`ep#YFCfLXwR0GmUwSMToZ92~uTH2^{@MEc59pg&8uB};gs z#78n-684@K7<~ZKyZQNf?K+pVf&wx!vc9G!1r-$z+a(}YjE;@6y2#LF8uVuLz9fV?kRL(ECB1DK4J$K5*&> zM>GE1oK-TvurM?{3>KakU;_o;0d^Nc;uaS9VPOg;CM$sB15`9H1;K!TPy`0WT2brO z%R98Wxw*8I^}rtw;vEq1UO|C{lk;btk_>RU5fl^@5utqX!fPTM*eB$tr70;Z9~|!* zgJmAPz*7cBak=Vc*^Pd%`6W?k;qxnpj{X5~bDJ?qc}ZQJV5^l%s2u90%n1E(8O>B zsGh&Hy`-ilARw5nv?d2UcZ;4>G_wdOu921oHPL|+?W6zLVmo~CSneWVdIG$*XkWiZ zfF}lIWg~DnYHu|xKYs)CgTR2`;^Hl=LeGRX=yABl;;cuZJBBW6Poyc-=t!OacpFo3~e zgCyu^rQ)AH(cZh~Q&r{MdRp1i3!5e)lvTMLf~5&EFzrC116RT&fjLWwk5Z) zu)8*7?SC=$&s5}poL(I!#^J@)H``Hwhe9!RaW(V%|E>9GC!moB9k}s@g@xJK{u`>? ztlHYz0MP;?6cFvz`o|?;Fg?V@>xkzIDn+ic)ic7!Pr)I6kpVvzN?_r}{CY>~gs577 z)!<}*)7VTO`R7k!cJ@0*T94aciZy1)P;gd$cfiltZcZuLyV&y+e;+0h_KfQ?0%}c9 zR#>X!sXxKNfsixkn;KR-q4Y!|pf8etPx12F`HUpN6;;4q#U9{RI1 zhqFmXKck`PSUK||qyg7*n&*$Ztgu28yahfq6c!Q^vVm4ZdwI&K5_w(p+^(0a(MmOl znbeX$Lw`gT8{~BzMK5qwajphu;^{L!bul^-4)XaLi^)~IAP%x7&TU6fL$+6zcxdo zqdyuNQch?L3(Tv|LT&7PhTwba)XQYnlBE@yz$wVch-!My?#*?sm^d8~6(tkT9IX@T zvD~5co6ma{Gs6sb15&%Zr~R4qCa?xeOG~>v#&zc5>9G8FZEpir!)JVO|31bb$$OO% zsl>@%PpxRR=m!LJsXUSScdr-q(gHB09=svoJ#>-i6bJ7drG7=eS~ZFk>i>Fl}yVegFRbckkcZsx7~Bd>%Im4^Xj7`&L%l05*gmG!W2hnlyx-v;MnWl4BA+ zQ@xKb$QgtkpL^gFIuin7*W>)y2kd|_ujgdHwvDarCN-s+RH>=%1yPixB=b*`vC$8; z`C6)f3~d*2AQ?jK7v*DG$A_I1U;OSCpEOc?fqJr38a7E4)1UQ$Gq>xuPuVweUKS)$ zC2@;s`^NI?!Th|o!J7wkIS>hpE-U+L_$)q$EOD6vkR2g|l<%xO9w}k0O#XBN)U$%h z7s`L>9NtUW?`M7{zjbg2Td4jobldKrRK9|hh|z7%X}QfWB&(|!+TkLE&Q`Uc+7_uP z*@dADtWBMro#|E|_RJ@PPBxc=uNWi)oSa<5fS z;9uxSt-}zA0P2frsGEd!g;B&X-6x2OhG zPfYB;A5jRa2o3&@d5>BQY<@sn9CiNt(AzXuh*7^bu+*f_c-hw0H~OR37&C5!y+6L* zsyeYSF}XPTG#LJfJ9nl?^o_*lPS_Yg7!>d3blb-`q6W)O)@dqo*9s9gL8|s1L+|Ep?JXdQvEWatR6#QXC{vg=hq~#@JONEN8)vlxSR)u zO)E1iUqb!@BZDvY!<2>;$4AG*-!d&Z3zPiDV6AO^)EO@i=UW02;%^|DuC_2}rBNVR z(3Y=LA3HXmn4DubTB`uy2WJ)MxFr`S*WZZ0A_EmpVUv(0lyk0{k1Y*2NwV1ocH)RnJpkwSYb(Oyvk@aX1D@if)jTq zP>LsITL`vyn#C%h?^i)L+9%bkEs5uWyta1lXr4%y)Z@Dg7p`5P?Oy>GR~4dwjby^* z2+@+0Tsjs8~(Q}8HKp@*hpy|b&$iI`JCK1-*5wQsORttK3KIb zhxYo{7Ck0tsJ@#Fs0ClNzJF?t7*aGM*%gaRpx`I9FiTG>pnOj8>jPsvpVQ2rS_U%I zEPh#32gBp=C+bg}hjuScUgr3XNK)(?eY7o!(TSHS)0Fg1TE^d!&w9 zLIxe8Ii=|xN<}Z8^7Nr7>MtJj&h?gJ1v{Mqw#_&<$JOxb$NY~#6~f8s3XTD_HxhFe zcE15f+WEe#;LLULOknw$-B^{8vCBIb32TWz-%G#{>Q!Is&;9_5yC4wTc3iHAHz@H~ zfZ~T4vJJqdH`trjdxIvw&fcf#d<_nA@RQ^eFYJjnVGp172# z6tEtgUA3NH0GPUrHcwh=`ml7ymX$jBZ*ttHPsgNp9koFwM@&o%$~EZ7u6O%rD=*m@ zcA=;pdl0U2mJ8Uc%oP=t6-VVVcrqR2l;s`ld}bNLbl0QU-b@N{fqq#aJidHL`>-N! z3by@P_^qUYZ)2#4*}3V~aC*M(<^&&z>JfKeT1w{ab9rbWIISO$|>1!UCh& z9lA@4%yFb$ttTtH%@>%fQ#?mjy$E?P4~-@`DRezh<9?;55!t7GgJ0~jubY42w^msI z>r>E3v0+7bN!)vT(wRQH$d+y}8Q3w5N+Z{^Zc%ISAi$`}yQfhmfwpz3n{x@lqS;|q zr&sfTt{31|KPvk$nVknBY|Gb{wN`zcwk(3Qmb6jf0!!_sp4=QWJM!7vC=6vh+GPfv z{v}=EQO_$p1a0MhdH$5CiA82s#`ucd4an#1l2$V!6P+rjeU5u~wQl_z*n2M+-qyRF z4I0*&4NU{1SR(TTJ=WvhQ%L~g4A-Hn*2}aYFN<%^*6l~*TXHUPU=5&hUN<7}xX?8Zif&_Vsj5*EobMYcsroG?Miw$SLFC5$>+c zESR59)(bqdJN#V0T3w76jVPWAo+uPM<#7#cnrnAeh`UjBW<}UJR$tmF`Dw4$?17UOcts2(fl49=NfVq8*Q_*Rv&Ib-im4) zp*}yFIGF$rEX%?1wq=gvRv(%&w8wiJR$sQq;BP=!HTZKE#MUu{&;u~ml!<#?gbGERkTG6qs+VOwEs zer=3b7_J!~*T$2ZEIx5n!%b3gAaAv0p?vW-_Fb>hE;Lvimz$`9ivID^B3Qj7iu}NM zKFyu%>T1i$%IVO)30vp(ae=&~U8(M6LoFil>Zt+#A6SbWea?(>)9eqSB1`3a$wZS? zTY9GZyGiOj2lRBuyk#k(=iA$eH3hQlUJF8AJ1a#iMS#GP36Mc3{u+owEzXlXu&_wE zE4K-?>kO~gSB+u&;jHG>#S{W>>|3@?Ct+kWE}5yB2ASK8Zxw@9o&1ofb=J)d+rOIldNp<4btF zfSWXWhg*W0qO3vM`NgAwh-c-^U4|eJS&Ou|IUOiQ*r&=mWZ8xjRhG|N%bRyf;a#Xo zD}?@~F>xjvnJG}Y`~0tB`}4dvYkwLxXJ1kUh@cY|n2jd#G0@1!iEIy-4TWq_QqQ{E znO;a(R!AWaEg4H0Kk1cIfoW;I!vWPGD8=^|zKT+=IQaPVG_TCcHB$Vb zu;ZC~s8wX^|?eskPtES|bbME8>HaPP&6X%`Xoxz>jHD17^VQuo-sSb+seLLB)-QkPl)8ThflT(&cl(pmAb4i?4 zi;-XtqUYFOrHMFUjnMiHY-9$8JMBV7H^SQ(y54oZ@OqK|O*5|H6BGq0zF!QD3W2(v z4w!$_5K$BPg7HM@@uTiX4*BEJ@jpPqitF@u4Rv(7CLD>ETZ`|^=W&#qTsv4clvw8qTw?5`DkLo>K>8!^{GIG z7A`E}`}a5KaPCgiRZ98pMPq#K3d+ym5+XCy~ z)!?)yzo4MSKYtiGEK`Z+LjVkXIq*vf`1$Jr+W+;=w*iv&gqO68-Mzh-Y6==}{-u{I z1tK1GF59mU-qB8fK2y^xXs(AIyA1pmvAZ{D|KDDi)u25z>p%hP)0B=DTzr+w1d9z0 z_hBb1t*9VlzTM|;%JMH!b2pzZF8lMo5n~q5?%qxY=Z5XP*~TdF@a-oNkMhdCUeLHx zM1ufe3{Wiufawzx6FoiA_8S0-44AoLvl}-)lk&O9`cP0(f}ZC~2m~Mm8=~_Fr{^54 znQ)k>5APhEoB){~*l0(2UHen0i>a$~1C;G`Z#TddfV_xLsT|nFgV&n@BOILXz&#jX zoayQ57IxG98r2oq-(K@sU)+$7PyJ*!4ba@Rl@)PETCGRdaJ?W>RSh+}5NK*<20-B) zP%N9B4gO7JAO(7@x&p_4PyvYn0aXUfOib3%#ecQCr)NpF6XvwLwW40Vmz0zQU5iA( z;jsV3NRkH+9{ex1{yQG)HvS*R&z7i+QYvLtR+3N@$w){>l98F25t5ayBq1xwj_eg7 zJ5+|{D-}`=i&&T!0HM-7mypQ8`yvB2o`NS8C;Y4Hb4pHD9XyuEE zz35&sn<+u#f$gNC+GVQe2_88NR9;s7%Juu)kKkW#5rJA&i9wM%#s7XW;{E$ml9INE zQ4NFcVPS>fls@YZ~^E zUCx=<325Xu(#Qn4{g)~k_ygn}9DIzN+!s`3LEE`O@oH)`jxbSPy=JTpJ8C@pw9u5p0OV zM~^~M5%Qyj1qJ8T@;*B8qLhPoF9ucZot?b=32)yjK72Ropd2VFf*fhTLzthGytJyjf(uWfhfNQc_Y>B%lzvtAqT17C8~UQp_VD zJd9o(97%?Thg(}()L|C@vF-Ndb0E}m^7Dt;)mBy}fd;=caSv<~s&~)6-j@o4BkU(b zu(V&kdL<<($wz0Cw%y{(Ojf^kN9k*IIoqjIT(_;FN)PNkapDA&?+Z?^%Ky*7*xF`w z^YFZ_3PL3S*-!CT$NEP{4NXmdR#$gM&BImPhfeUPE*FHFA=-*gxKkR_Qy(9);*IO& z?*H~~pKK7Ii${)FL7X4WB9RJ6Ju9UuYw7F9$HldLXMsF6tZa`T2dB3VeuWb@d-e;F z|JT29j)o0aTU#5J8n4vUb6{#iZu=ddRTY}n%F20++`*xtKjB6Mx-X8_Bn>-Z^1t+c zUAU*n-Uc68QBg56GSbnZLQ3k5p7lLdRWO5ca|(p8aL~AKmNDOH`9CeCf;{XL^rqo- z%6;|fI{M9!qQ%MT#lIVAh+%{bf)81g#eZdM{iTfRmoRlNij94K_Vm>6-#WUw-)n27 zZ7c~92mU=Wm$aA$t^u^W>3B`U(bUI$(Ng=rD8g67p;`R>$B*ofuPzhT(Hq?kWD!Rc z#IB;);^g#qb#*;^+Ehm;1|&HQH`PfGF?V3{^Z+F5-dtuTCWvRQtzr0AB$zD7uuZ*& z9E10^N%@M-B^5CTINe|>DIy|bDZaN}kHI{;78W=tx*1>3s(UM@m|{wx;H`*vY=5Kg!Aw8-l~a zavg}baU30T_*_fNi`{aB`kJn;&mO&JzAayKSa}2j5RPl|t2|H7DlEI4*hv?S?Pcpw z58FCK9Yu*tAddg}&mDT-cko@_Ub;ze!hEJE2vM%uK?i+by@DjG=y7uwvi<+MmtUrr z9FNZ;CPcrwEF}KozddOqgg+od`tJ`2@r&Re(w@3b5jNG%QSHyJ2t%_0hgrzxFrmH- zTX0|t`lb93YW{#h-rpJEM=?Xmw!KRy==9lQSSCz%ze!4LtS3f31@b{OFJyjZ?|<^dWZ3#L9VCa z(v`seMofpHNoi^6@87?e~5Nsfbf}vH8i;IwvQL?9}BwF0~q$D}?Wb+*UVu?Trn1`eV z1paHaGhpmVdHArdw)SIC5b<@`)eAm-c%~b4umr?4L&GFISOgA?nzSB1toh-_p-zZ6 zu_=gITuCRaouGVA%m9Pyc^JpwPhnOFF)j7kimEE=W5?>PtPS3O`SPW$ZQIEXFNAeW zE%FNrLW6^Gq83M++$p%s2fpX!T}EDj-+-Vm9|P~<3%V5)A}?KCOA(|JVXtnA!3KtU z2e(IFoC8O9;UcuhbP!fchbSqVnwko&#^X~`3bjg!`1$$IULcH6|BEapdHMMdYD29s zkQyA+Mc}u#$M_AmwVqxaW|}d)wNTP7cKCZoR8&+>&c8c2AYguV(O85SVt#z<(r9@y1N)xd0;KapNds&v1 zy>Q=t9i^hekHz#5W?M8kf(2*0w%Ng!(Z!pd9v&I0J9qBH7`WV*t^__m*fSW6XMOc^ zC#M@58G(P_?d#Wdu*x_dch@k!<=wuRnwU5^I3Rw2kvi=03u4|-$YAU93@}u_HgoQ8;Y%^%pSw zJ%9e^_wTWz?I3M}J_)UK7^kROm2d`BO3BFd6gw8af3Jn-hm8;z5ivP6_3riS$8Zi* zQc}VVsw+)UKe8R-`fTiH`h>C7)YZFFl+y9lF+Pe)ND!wffF}*c-RbG+aKmFbgO9_o z3brQjLB8vb(K;r}U4=HXLPC8AJlLU#4Ivi|4>5eluc@l?98*+M8Xg_pmM6!M8Q=H% z^-`=g#3D17^?*sahAam*6r|eoc!Aq%GX+0F8iwzsr8+qDI4>|=(%bt84&E5+;u453 z3gNd&Lv%||=U{kVsSB4B;GJK&yC-y~_0k!^cxh^C3UhdL0k&Iir=e|Z4?MW{ea4I92{m#&9Ef{jTfg5FZh-qImWL9 zHp0$On(Ct-YP* z@*|h-_a8sjx3nk-3As>c8yF=8;u$*SJTGfoTWtm_{O|q}CBBzyst*5a48WBHT^Mh@{g@SxS#V8_6u$i! zI{=sPSg~IinN4XWE=Iyai(`pU#m${XLdkSa<8!bPFMc8=Wk6tHoJN-NIb45CL;ik# z7dSbOV@-pDl`;OuXF4@=pFUj*2ngtSu&(?0^Zb=7wqKv^!Sou{%QhDqKD^T=5x@b3I7c zp>;+t#yRgcI&hlU*}d&1|LN-2kKFsOD8i9K{<98u7;Ffv9j0~4547xiJi;E*v`m?lW%d=66$S+sP!>2$>|CQrerhZ&5J8UakeukmlyY z&VdA>uO;B83ULFrf*mg+f#RaTW*V+ABPN|W+15~YwOU&;Atxta$|NXgr57UvV+F3l zALPP?+me!1&CQ>L_ad*yl|>{gx-rx5iiB}(a+#d{&+p&xX~2t(ot>1JSh?6CAO33C zg{o@@`*?9_Avx8+T?3Cc6koXXp{NC03EWBQTV^K-F3;@43tr-hH}{6ub6R=Q@95)2 z&GmO>_Oz8R#nGd!DD}Xs*92gqMAkLeTl>N>oE*(!2d&(dwKd)mZeRt;$b68MKtapi zevN3q_+0|3+kIqY@nedVBETo%zP?*>*KXG~j^!u9Kb+JC{`{$}t~TbmA9V``H}ITG zy_aRTG-0T#d-&u@;E!misBpq^XJ#G&BZP2S&yorx=9g(Pg%+I*<;ZJ}bBl{d4jr1C znTaAZfsz3ZCt@3-4}Riy(uFhve<(53N;(V|SbwQIu7v9?6m*v#_5G<18n>aKq=f5B zGrU}Y11jlF5O0S%6E45FxIY-;RaaFZw#1^I8XH@U2|%h$ef&78HDd#VnVFg0d-j0l znPE&2*$ZD8eA-D=M6|R{(>(&Tw6u_^fbAP2WqMwQ*VSjb~d)otOv5< z;^hE=0bzrRW1F2W0%r$*|Ay`Td-C!l#9!p1@C_o`%9fFm!j1p%!sP!a9c=Uc!NSTK z0+UsE4d4_eBrvZvuq!c>4p2}~9K#RB&JQI%MA$qD zEjIv)kneYWG7QMgT}Ca#EEB#m_veIKcnyWkS%RrU!G2gA)fEr zwQGqLMuP@O`*3045FvcxLbV+KH7ULW0H&@YdnF+udKQ)u>^WqNs7H@oxGxl@&b6`! z(FA-eYnff{bv|vp)8(yBAJw|`>;LH}t;o5*J?#F- z#-;=rG2*-1^XEf#k-h1fB}i+FpUi$k=?4i6=x+saXv#=P^bHOIuJr=P$MXmqb&X$e zaGv%LPb@{VSva577&au%WGdq7#00$HWFoIg6PsIFI-s^hMD+CZEc2l$G-!yPcCIWy zu8b@#@~Z6}OtNu%^nY{1lJ}BZnw#TxBf-#&lQSRR3L!b@y!vVky|ak0urN9zIXO$| zvU}>&Q0HNihP-CGcKQUzzze**W&?sRO^|V&zIyd4dPQjWRO-T734#kgv;r!(ZjG<0 zHg`y(WD2NU-z>XA7zzGAAqo6pVg^7Le`se+ z>sTWq%*+H|&=NrzbAo1ka&q#|pC3-un|oAm+}MMV%Mgo|xw{{I0V`DtgvERJjt9mb z6oEZoqI+a4ZXO#h2!kCtdX)FFVa%@M|JSs2ycKC_RPl86%g)Zue_v;B*Kg4i(AZwM zCV*3eP>pSY!sd<#V?)QK`x4tbQ?DBLA%b;8NC+~NYFrf{AZ_n+9{2A_*O7$x$xr?-7U1#f zczOwtrs^sxc2L;BlMt!EErKKx21j^W!+m|XRa7L2M{(4VpqrRXriYvUm$sdfbYC1dR$Hp8ktw7!JVnZeARv9~7TRy9S(~#?cb<_zLxCH~eeA`yEbHuw>`a`t}?dq;u~Bv~3W*5SJk_ zIXFBV^ybY&%P3sc9v+o=SF{yiapz0J|4UJLC*ez^Yo#v4=un+^*Vo?`5&4Gx7iuBI z$fTqs{M*IF#Y?=r!~Om5`K2HO7nQ7GZ{MG6}EktxxC%a<>aR}2mg zVyhv;K{#nGDtOC(7jK1{+13s#_V z6yyZH{~+r1Wx-NI(3ZsGI(7Q=ba!Dnu3`g&JQ#taIf~k`0r%FIy8qf(CchEKkTsxo z!+55mvU0RDH{H$c2Qa==92%*x2tz}QP_p}9r)2&0|I;ukb_}c31+H`(nF%rglH>zK zr|IdV5cDj|i3u|)|JFe$1)wzfKw7wJhKGdUqLD>zjI^ZLI&J^Lbl zK00~Z&8W||SwIcmxS@yrivx;t#R9;&`iXySH3RHz69ik_QSgXE#6zNGs;!-gWE`~@ zIsyeTy9g`N|9$*vK=#tr3#kw+XlS6Xc?Ok;iAfP+BLdc&gL_>B(ZlZOyK+Oi)FO>Q zy#g~gtgn`qmV&~O?hGL%ML9W?6R;6(f(sXJvfAcmOMo5}6%}!TS-KMugqXKGP&6v| zzW~t1ce1nN>(2N>Cyp8!H79;eMJR!={bej~V~43{8!3p2J`aEP>`yS~yD~A!$pOcw0g zO^DjD{XRa7f`ZO4z)CVSH0H6FjpPsV+P`&sSH!UcFOuBc`e*td_|o+jRq|iEwuz(( zrGaJn9>PpvzdwMlG!iHQ;4N$Fv>6xHK<4995gO&%H!$${k>zJgZa!YY-Y;M185!NC zKmu^$U1vT{h>8JH9rj|c{euMU&VO`IWa;iFT#UVZ|4UqOn9ouZ?p;)bi0z|3#C%Ut zmWl)I%)}HQ8^3MusStgBWcthhcB=bun;?sHC!>+X>;ONev^zCaFd#r|D;J`O>)#-GZ;0NzLatF;F13RAJ@M) zxo^`(%-oI}n#o28WLu3Z9s%Q$O$j;WZ=ZI}r{6tzy!8)$L8KSBI<{|<1@7E**Bpq8 zj?ACPjHeX$Njz{e)>yZ#XFhy^-$=mpVU}i->JizEE6xiAyXFKR)qicsSoCPBdu1dN zrWQA~bLXb;a5*Wj>L-H+bgMef@{CAgo&=Y*rM|DbQalu$r_GfVmE!rM1ywq-J~_+o zMuOjq4hb3-aMQFDZ@!0?u=Jxxk5X0vo6j+lI6Bfh_mdEz4ro36ls%kXPM4Se9UVi$U{_X#Q6TwL zw}qwod$J9KA-WrF3yWq7;f5TV*CY!xRaCT%v^a%sxOMj|oH5fZ*}N9(T=%YaeZ`;R z)R|M!vC&5NjYP6F$;kA%LagQEKf0Gl-pqe|rKX`J4&5%&0mD^y@!Jw3rfNXpdk3V9 zFGuRFRQR7h$F8oXPIv8z%ULENw5>E2TBE;YJ-x+yF5;pMm$jP}%Pu0a%TPC&ncWXn zIQzxbmiMmiPo8`<$+X(Oqg?cnZ^DIwR+WdhVOV3`K?`ONki+>y1`b#XGu$= zhK7|lmp?3!o+l#887zIFkypQPV{L{5(A*uvV>dZFM?|Apz zli&OO{spGGu*~tnG<2$^!!Kr}rTI*~oVKwkQ_T&OHt z{YwE^d+x`ZuEBZiRpaZ|EorwB>O!(i%dKI8kgdVk5=*(0YZzXMMWq$4;D4PY`&D-#}*t{nJYh#QlitOr>GQ{TU zlcwCu+RKR$|6`J1);#Sm?Z_^IV#^Nj%$LU{cyUbviZm$=?;HQ)ggUJKEIF zU6^Lgdpy;g{pz>JH6!NoOlC_9ukxOlSEb&2?uQ@97Q~T0yJSisl_hxfkDgxZG_zxg zghJ%!=m81Uu!nIp6LvIae!d`oXQ2O&BdnTHlj(C<##5sm z&tqHmDi~39mv~3VZOuFqhOy94y515qht0ga^uK?dKPdmiG?}=+uP>O>Sz|En);}r_ z$<4}*a^J|M5$jxUSe4KPKNWa?yN$5xsvj|VaLvMg^5xsQ>viwu?%AS9yrc30&4>_sZ z-Ar(NwwTC+$zH|sxK00pVRb`H2}euY1i5e9*5l9d$I0mMu#TgGGrUvUbzt)(iWKyi z$5t&!9wauiD&Jen4+(-?S8LH2X2)0LiqHQzFupFdeW zjOUO31M-&EE&IyX^sMWNEK`rafpr-@og}j;+9RIvkt_MGi4vQGldV@SmQgsIQZ6o8 zrzmB(SXTdu>{x$SoQ3I&8>rv-;9dku&fe{O)3U0v(*Mm=lO>&_ygV+!>-I}iS1tXj zID0-;ma=_J?pj`|AYzn&59WITLzvc?KmYa6Ng?#7DyTI^s} z-_*E4%zFOpK5~-3fg#S88>;-OcSqoGtI=#))U;W?+wHmK!a|EVt*vFeeq2K66&_BS{rMi*Zu%_GT z?7Npd_tN-n!<)NGX#0U=1fJb^G`C$o81GJHyPj=VyoTh|{lI8mP}=YRHVCS3{pmBK zXo!CeV2*fDbIdrDtN9B(^Z0yWuGw|dE((gnU1Q@}x>KK#Y_pLaqp<%iW+LtFZX@6F zmxYOH=)t-#Sd7-=J>F-xCT*5#qVJI@m43V1+ze_8ZFfm}{QE0+HMiyyWUEg`oK#m6 zQ&u@7vJ`pQ)J%uJMkq2_YG&iApv^%QTG?Crl!p(^b>vvJM3>xoCm8Vhtw+9HwtJ$1 zoEC!>qqFw*hWhoB={y6cbzX>D_Tq3&%}8RR$=b49HNW7&#@mhp3Rc;MIWgkiv=IS; zM~>2{I~$*3&~1Emd@X1C^5}4`ZcDP5SJ=h^dEIh>)wG6+$|~iq_r{l>j6^lkGs?5c z+m!}iwt4N~Y-^`u(2*{F%yQyc%kF9(sc>S3c*S^0*EeJ|*DTlDW_iMMQbY!teE{*m zRBF^`CxP!G`XsNTi|oq8aw7!`4;~2&iii<-7@Qx-xOnotT#R_RfRmJfXSvCuk%cka z(%J9pKb%Q_{nD?C;(Fv)-Rmr$9%TE(U~D8dAr9G@JUgGAow;n}ceSFW*=~Nf&5fbU z{L4y;OwVJl+7ErQ9DT;<)!t3Ed-vzMC#p(H<>*guTqSLG?lM9mcK;_`(YyO*SoVYV zzlj(Izf`(Z`1yq?rC;K=pgg!avdYV;x~qBc*)x&Kn>P^)+2@sGVv|>!7-nbYUZ9j@ zJa=xsR2-lA%e0f)Vp3(}##zIA?cRmfjvKE9TeN=pZi=aFmNs1^a%~W;d_2;DjxlP( zqxR=b3sgbei8w(LLdW&v`;QkP2PnrG%dXwMqxSmIZ<(LNYO_59r61gFC`W!R_%X#N zL(+hkfvS*A(S4Bxy*Kfd*ETB{8g(vk~0jSaF6rH|JOl|B`m za5{RGR+gS(gyzTY@-+htztskr4xSuu?K!8BL)3;V*H9Ep&g8 z)K$O?tSl{G)%s8#IzpXBM(eIQ^!bg4hhg%c=A5@VU8$dI*LY<^`1TO|0z$IP4L<_( zo93b6WbLG5QaTz;e9+v#|NQ%g=BpOu#t*_ucsBPCByLKOsM97tNM??qkC;8@Dskpr z@lghrQ^bTv4OT+~{ipmT#1zHYz1czhc<+8aNuFjO^(EGPY5QCDk|Lhb1p{B%+;6ko zUHCCVS?D9^5c#EQlTmu#{w^Q(G7TpOJ)!47gdWf=Z0h={CMt44dfr63&BP+VM$|5Wj9WdG6g&8@APMRwT<2>=wp z2t>x(I_Jd;FLSoZLQB;Xp;e&? zjCFor{nCD>4VCE=gk){%1UJK4ESt&IuRJe{x_PE??5}Wwb>sp544u4NFZg9ieM`4a ztWQte$ZDNZ+fN{FTM1fT_#vK4M=H3X$IE@l!}3q%5#9RW0QdPh=OA~faD!&c&|#^h ztcMZPYLvOn&kwVS8{6})>G1n7l`$3A<)89DgDrogz(^=7f+j*dheo5oE@YZdli)JV zCrEB#Q`PL+Pi><)Kx@S#Str_R6VXd--_hMd6XKvVbH9}!5-svg`x}f=0@%%0NgmNL z6F;Ljh|YL-Z9{v(#EPAr^?1lksr$ekdGWlDyBC;I(5a(JK-&;ZcdP}FGw0dZs(<_l zM4OiIWOiT=(km@320|Z38xV=EP(YT#_oz?E#N@;0&+EWC>>%iJ*;c-0gh03P!-ogR z$ck;IX=(T`^*FAtz~%C_H4TFt!zuqKf^*k0i4L6Dd*bm;MHNM3`4rhG^33Ej)ZXuY zPrf}I)GRvzU)}zn^3~2^y}!En%tH3g`3HKpv^QN5VD-N9wejnrN;d)_Sta=row48j zpEOs!)+_6NCdg6x2SwNn-&y#3eK>}rM_*5eot0$|;n8Dr6+Y!M@gJwHUTah0u`OI# z+I70-=eWUmaFGGeoPR)Alj)G<*uLvL*V=6Cjs6&Hbf=OqFfuD#sVTFgxCG%)VT#?- zLa%|1>gieV*-0%893xth0NCNBn)C3A^@K9uWN~reGsG}viiX7*rs{pULM5%$1{1nV9?=QWrm z8``pBPYgyxmKBH*gj5E+Qa^EoiSqusv`D!&ZZ!6yP&aSBIoCMR1nloSq|Zn^_F36j z*?h8kH2Y`=fhApT2jRkjW7Pb{oRM4MrK$=XdxnX~85{_JQ74e+uM$|AM$Hn*xDeOlYM#Oy$!Fy0)Loc2(7N+-j{v z_lI@OfV$QCQ+a?%hGMsHePr5)?8U}WVlo-B-oRely&Ff>uUUx6-TO0a9rMg7WogO! zDy^^7r(Fc}XSyNH**VL3L zfw0fb)61(f+Ze(Y5%1sk$4iHuVJzX+-$|NKQbJei^4Ii|suI7dQen@#o{5DC$FSvJ zt<5G^4nNZ+Gg!#2h8mhf>)*_enFnl0yyp*BeEy2X)ScWt7#!$*q>}MPj9I+kH@9#5 zAJ56t#q~Hi$*TwxU7>X5es{;{zA61FhC?=|f7-s2M*#j(Rzj3Zf990LDSs7eRTehY zi!Hpqv9mkIi8s__-JffHSy*1)8c_(K2v6RNEweEy@+(cC*m*1eH}i{>N3#o~HAf9g z1AV&wyyWJHOxU#JuTT6vG^GFFL3(1M&^7H0W!*QGjg51dBVc#ogki2QIy#Dt^v2e% zl#_?Y$IGj_rshpx;Nr~8%4CDADQ-b=)x89l5Vv;SP>**W8diFj2w&>E{M;jzL`A;a zM9}^5Ee_dHLb3HI=zz_;&=+Y$GOTLVWFM2eDd*V4@S2lUK>9pw+FGlQpKl(S+MS035>U<=`u=;S zx8rZEfEy81&A0af9sB0b?ui>$ZqW#n zW`Hf;a%hqfz<~$sstCYrJX%bRpS!uiNIXmX$3E&wgmR30pnar_0i@_DE7GjsP2IQe z-Z`zW%-YTm;XizI*f_M+6nY}`mwmc?i{g=>w}~HC!&g}@tuLG>5ZL&~d*3t@E?XmLU5721>{F*zxwj-ICcOG5>%b}hV|nZ|N9~0< z^~Me}TE&$JZ03Y&wJUc9`-ck)jFJ)huGane*1tdZe3wdrU3-0DqPcl0nJQ(m^@E$j zNiXvrsc2L4a`2|nEO(cAr+QCo6uXv1-D_9&S6Fm1mVN*A{=bm2kxxA~w!K9hmZata zm`hvo9fqV-jg8B^E)tdq1QylVUy7~tVTW&4S9M&u!X@vx6(c7qJTmFHIx<_nFE#4p zM>lU$HH~LefC6K>7@L$-SyMAHIaxF}{u#3{Y!xZ&qrtqyLSA(xYeOq2XmUqob zr=r;8a=z1fn}79BM9|IA7CPhDKXC$YYXcNs$C;CO$0z0nWru1V+2EpX@2)T_O8;xQ zU;ix!|KVEl;Pm(y84qb;Y4djKUWQWIG^W#(O@H?eM+!)!eMk;`8>B&#!?a<@SJIa| z87sC;;YmcQPOEkOPjk5cPgK}-9czOlEKf)LvpYAsrB#86YG~OFP)V< zYgbU{{3)S6(Pi!O_SqAAM3!B%8F_Vn%?*TNQ^dFj@Pmg``I#^<2yl|04SXAl&K`5p|Ot#njSIy%4_Ys%7&V?CD z)ksnCG^vD!WoZ_5SWG0o_ozH(NKhNF|8Xt8la~$n=5XN&~ z@P&l9o3%e)AGkq%quE6Ns`F+>^r@19eaByYv$5uBZryq-BT^qpdQUP9wrFE5DQHO? zJ$TUE!U8S%gOgeUFLTa5Y$1wVw2NP5IV@rSx~#G`-*WMe-QGQpbZRGeKBFgIrF2YA z?aJ1>)wa3u*}k7T?Wtu87psuteXderKVq_{ml z!6m}=x}wHr(CRMX-zT365eN`zi4d^=RZ$@!Eo}mrGF}Tl#%f$4`j1D(wDd?B%~@wj z?VoW76iD6EB3})FODJ-f5!u6z8+?@97Wd2>`~~a@gz2nIa~c})r3ud5jD|42z@_Z$ zOP2_QgK~0J#}AsLCz_V?OOg5p`j~G5LgnMvfp~~}`BGg~Wbp8jlWJ-kt~=Y?+6Wil z0Qkwx&E3Sm&)^mP@w*T)c=F^j!NuJ-fhAYs#x1uVb8l|#JKAaU51dM97nq-VP$Dr{ zVCLdl%Q;eKL#kXLc~|Wu;kKrdd+MPbgv2$qY7Bx)t8c{^2!;JLwFvJXTClWv@cGHX zO#R8>u`x$xpDhPxrcbQ$@%73T=NTDq05kg}Iz7!lC`kO2e{&1-w{d{x{ubIa*_n{o z&fb)kCUyP#h{VGC-mk+aZ0Xt;0|ULK@5nTMFMIxUcB{DRmqM%FnFkA&%OhcTJ9|dTc69d{tl684E-G%cOuK$Y#pzHPXpoGtare-8? zkT??%mBRJ^>Kqy8(m|eIm%7lrGiYmQvXR~INqmagEIi*_-}$*)QQXJinUb&e57i$Q z?HqE>ecAD0p7+SzBUaLu;)ky5ipH+pS*DW-?-|k*bR=bx`F&U_96vA0ysq)*Qb+zg z=7Qc4r1uoe>Kaa`ygkpx!TSDOL@uMlQG$zWfJNRZBT}oy>Z?PBqhk`4Rf^853uiXJ z&UzgkY2YS~7Gz>#+WGWLUEMTp^egGMRJ6=Ck!{uw`3dywoRd#h zoD-(s{c1)P>sL9L`Hd@<$vb)nEL1O*)@nWXpu9-(^*afcoqBI-f^33R+KGpgZ`t{X zh~jSC=+@-r&bBeXSz9U0W2};8oAu%M0V>5`(^R&5SJ=*`5C}D?A87UTW0{y7Qxh-b zz9sK2Qk4)LTwbDhws`?wFB=;hfc~HhiSRu%BzVEz`oPD`tYo7U#W#29={QbaGy7xU z9V-UwsC_p=e8pp4c1(KZ@~d=aX%_G4J4Yb2Yf%wyZ{^drv)mLB>-yI7+9SkpCR>;5 zFKTOnZh@&=UH&)9k{r*aNXbg>C5(iOk+XcW>T9HI8Z#P0hV_BwL;L08&l2t8^s$Wb zO3tZ6M+YN~t_0eRzWnL)b0J}L@sia*;~^?CDqu8EI~&w{6&-AXR&+x1H=avZm366;9Hm7p1IuRNRs2_-*pFe-bj|~ofA#r5H zr~VcTD+^~14-uh{?~&W|e)ZwHn(8XYY&DRfFDgm_ANnl5#I|F&vUI2m3O?tRM@Ld;gu z3ylGdbyI>Cd`u#uYP)?)IV?1)zJI^i@^~yE(>G|V@U!jK5UV`=pE8@Wc-Kr01srPP zY-Ih(R_rj*n7=ZAeduxhG=XwEkZs4Z6M$D^#F>?q9+0%5CuG{J2 zy5;3R$xFYM`WR2F5<4EHRU4!{nP;<;)?F~~&zFI~o*iFz5M1Jn-_~+33+dDoT#!9F zuk)siCejr=CiWH%kce%Wca@pEcHCN9{Qs$)UnQnwrQ~NEC)9gSZC|^;L zKg7Hn@@n^WQ_p=!{Hq+3ngmeR4nj*{3vXnv_OR|=!bwv8f~`nLyun4!yeD}E?r*ku zNC37o@P6dl9e$3<8&`ib=o&Yb_8I$dwf8RGK6C>bC#tu?!j^;La7WcbeS#BB<(Xiq6fcLmtbgr}^`)puEg9|HvS} z(i2-`XlAlZq9PK)%^JfpUrJ8By66A@3!RAexruNEXeLC(Q!K7C{qc_YwhXDpA{~9L z9(%3G@VQ*Z<8GpEET=`ri(1X*x}Qud93ZD7Cwyt^ICj&UK(J2B;XQTAYu-!mh@Lwe z*9Gnk|_EWy}#4F%z{ptXP=a&^X?J;eGtI(;kR`$ zjc@z|4=#!;m?+?{jv%S*i&D278rmCJ>Ce&ApSzH^liDp_?&8XzOS7=VU1CDLa_h^~ zLr+g;WoF!Yk$iRIvr3qXqHP-AqrXu;{y+POu$U5O?pR#sW_(drz%)n*X>}KKwr7^S zE&9bKg5$ModqD^OT3lMtPk1oh`8l^Z-n9BX#hD!`DM`B!yfsniT;KfAzdc(&ZNEulnxIbnED_qkv=Bl_D14BYZxn;);hx@J`J9tciQ-OVbF9G zr-34mqVAPB=`|j=^W-1St+B+=Z_M2z@|QT!MRmFFY_C;ucvtv|AR@Chv#<{-G*$=s znb$fZj7y(=`*`EesY9nY-hJ+)95gmI+(p0zJS9-FOt)3bN*-{eOb|^Mj$1280noX+EmTX}@>@@q; z+Qv%htr8%$>)QMQJO0aV1j+cJ@0Y#kcOy{w9CEZ|hB>+NF9g@Gci#q)rx`xf$2h*) z(<@F-4>|6SGiO+C@GLDU)x9fy`_@P%M8xsttUI}{_HP2AA}S#G`SbGV8wA23kA?No zrf;7e^cAV(Z{5?#XHng>%3glcBP%; z>gV8q5czPWS6`#NO{5O6A2@!j#34{mPe;IU*>bgM!Shh+vt*H(k`t_6FPd1Wzc{;= zyhszfar1_(4e#SJqZbMb)dsqB%q5G(Lrv_#_k#VS|L&MayVd`ShDwY&*&vWvH~ z(d@RLUAZCe7y~|YyJePUZ#lH#y_#h+KYd#NVa>EFc)N%c{_T;IcAn5TnbKPEQXW)Y z+)5pGcCN<7jvJx=9yg`0Qxb$CF6|)fo1fc3c-?r~PS&Nqvk+5d&$-9tA>68}D%NHs z_vY&aozpdWqdHPPeRA2ef0$k4D*bWSC=w}Ud`P)p#PIHc(=EY9|-9TOcSH$n%FPl7c z5A?PQO_}VwrQCkcB;4f1LvQr(W>m&X2IMTCpY z<@1!c_Dj0i^O`BX2~>Ei)BE7TmQDXNByBEK$=95&TCIF^P1#S*G3|0n@6x5cN&nQ}(f)huw84avP-U-YHo&TF8&gHXcxjeJ) z!0epB#hc)9to>b6P`G=uO0tokYQ!CX8+T1cz<%gl(XQikeFGE}yS*cxKi>`DH4v*1 zA*`wdouQzx5V#o-mkwUZg5D>WrQRs3Vcm3M;C~rb3ohbE0L(i|A8XZ~=I^bQz#g081D0Od& zh+riNE{}G@1cX&{YkVi+Bw(rI1&ayknqklHQ4*rE^FwTI@7pI$3mCFI)UpdUSc-N% zbt>~W5eMiT*!U5eij{xaXITaMKaLI#@iGx({rwrBKD~HBMEC;6DJF=+H6c3s`a}Kw zvornI312|X_?3FE6cy0;xIHlSj*c6ER32edeDmf_s_L?y(>8en>=|G~0K)@z7b3bI z;dGf_!QCMyCSKoI?p0S;2ib>+pjKqp0{lY6_yGpE<#Y)u9i~g4ZO27K$RY(S{!T??ZEe_a zob|l(y!^Lg*O2w6TuooEKPP7CZ%z(VALNv)5(h4r<(!(T`g|O}=m7e*@rsH=JlE?| zLfY`$4CVYY=P35S5f0c*M*Tu5eeLQ!|_xZHeWW z^*XICjN*~)BETKhEp{KEq9vHD0NPF@XTA0L7XI>71ovWN(`)znTxd|;xD zlK|Ak7O0D?qbA{2offWFevz*Ig|t%93S5*fK3%FK+m{?8V1G*jshUj5JDhx zuSPwp(H(MNx0~CZq+dmU28OJGB^?YJE^+2aPn0lxs(JhNO@&Jw!`*$MXsyi5%ux*v z<=3Jo-SduCP_{1Fm(EO3GHTYksgD7O$Jx~mzN&H@uCi6TD#GCxPy6-1mEOqGPgltt ztZ2`AB_(xwx_Y-?Sb%G3KfYtJ=8@36bLY-o9kP9%-fp}3b&uT5hG|X0#tx$tqte!i zh2UXK0cSTlCE)P;v6`YP-rdp-01C$;Zm<<|q1rg`58W4nV$Ur9pRTwG&ugZUeYOp-f4p6hP zj!qWT7&0?6zqUBVm0)u=2W&{3IrK*d#3G=;VaYx|Jp2INR1=e0aEMlC`Ze>rW1)g~ zS3{*^#cCogKO-ad<88ScnDH)8(fE&LlvGw27@H_GVJt%7@%@Nbk=NY*Q@^#7Y<|$Z zLO+I3?@=oEv+WAsH6O2(wROFqx{>i#dwcs26UFR&sj)n^_zFOH% zK+w6lEsTxX77GOM?ePFWZUIoA-~!|obV2-c+Z!65o?KX5w6d`QtB<_3uh)5thJs=S z&12WS)2`Oi*oJU#bK?%Ta{hqu@+0!XvK3=Ys;9hsWa zM`AL{FLQO+hi>|Ne~+%NOS+fq>1qcK%`B$Bm6XgD`*DlPu{4*iExU<|`dylud))J3 zk-Yv_6Tm6!%5t+4vjO@0scM!Mb`vJZJ7*UfPTL<1a_8hE*U|PT8j`aqh$8A5Z1SezIH$DBu6!Ck#rL z+&XhF=jVMnQxCc8wT|o~)j>`C6fZa1+S*LJKV#Ha@YQ~!Xa8EBt#h9{&`%wzoxJBs zryfo^gl`7B>b%@Yjq3lOg{AfeYp4x0OlN070zG7`^YanuK{+|qH1kq)0Q4^t6L;l6 ztIMDZRS=pnlg2y*ld%^MKW1kyLSz~Zp4HV=FjF8T@a_Hu1PPpU@L4|sP2bY;Au;io z+NAgzSj8crN@Ki;D0=ebtFQN8q^r~Lf&PAPSC>n4e7U*(to{yh%;q1Yd!TRf<3}lf?bm*D{j#U> z%>E_BCIUq*VZ2F3iO$PD=mE=W6lGdiipG?zlX7u#iwih>oc?ZpkdxCypnI<&2aB=4 zu~bN=Q7O@&GJ00OVs=}c2&*~DAvR00UMT||lh)Rw6cj?!LQ#Ux;GPan?k#n%^!ZF* zy}$*sz0@7$nUb2rdhAy0;K(1^Dv{l_pq_YhQH*Q1u;pC^1u%Odv0hqU&V2qnEhS~? zw{M_V433R?ip9)6fyBfDc#LSHLT4T4*l&>*+_(tj2{f=uW;uJ7i<=u#lRF8}{js*R zgh&kdla2_|2#J`2NJQ))1#OdP_wK893s8P9h>aaYkVZZMzB#lnKn_Rq9Fe#kWJ7S2 zh?HU)A^`9JyKDP(y41zD2vdYTD z;0r;1gKph**U-68SFK}9N)q+Q#+jFT(M1I;+g$@`*CnujpmEdi(d*^%nzfnQ|po;Bl4dSBbId6F$%Gp}mSyz?5Nv=AJYbmcV!*%P(3o)|oUXHW| zE`NNNHz!HFen7kQ)Cnoff7n=9Fq#Ku`(am}9MT5`g+Om_lR@v(`^Vwbh&E%%=BhE$ z%AFT^$?nL@7dnhKA_ZoQi&NTTw$f58TyHktTfD)0Uc=MJ=T~E6w9UEt$Xgm3o1j&I zFao8O$Lp>uDa`4O{Lwchh2^xSCh~!YK*q7)qu1rSy(xb;0z~3$Kyr;BgiDC)ndouJ zv#hKPhdlbmZ@&hL7;+Pj>Dk!$p9n_MJ$pzpHZY)l|GrRrZV(S13W!-CY7bdhwfuD5 z+aE44B71#ee7}0`)UOs}ai5bwMMm3PuD=|GoC!oQ3_No_eF8ft2LX0rp`JhS=F<>N z&fLX8WPm6^PlnXV?PAG5?atcPkEp%$hdi*usr{H*e*M}>K%R?%D|V~8nwsCy08Hea z%k5I}Q^4DQprdn3Qj+?w!j2s~kau}eacnBfdmyb!`nCN<(8~5I7t8dm`V*#X%&*5d_K^ z^}@8slD^_c{jctEXIol2nJ>}r-k{(L2@eYhps?6l$~MNX!jM@pRe6V!s|&qB@_ckT{LPzY&p*|mk@lr= zU}rzxerO}I4ILel8x*PNZ5@i$Pm_-gDWD}mew#Rgs=kOHOr zEM4(>i2_?O+w{g7A|ozi9P7IJ+c^1Pq1l!1!MIP{WqYSu3ei&lQOoM(a`f=w&(2%L zSy_}0G?D&V3=^==Q5T|n8&c<)txWdQBcjXFc&jnKKuFQW! z#FFm5_p#7`IOOsDAM*^}6o9VfKAF`%BMy0oIGfKD7n7g`gKz;;lt8>Q=FDKAKf;9t zS&Qs!;0ZrvW$9=?I}t1b2;IMj+;H*!t#C>2)7!WVp&gl!BKhSe02OthWa~!(wC}O;U^yyR18#nrw=Pw+4g}d_q z$KH4UWBtExUoBKbDMFHwl0>#-B$VvzQOe%3lHJfyMv?5DnNcB<5oPa{k(G#S%3k+z zz2D!@{rKLG`}+snKit=&M~~j#xL()m^?W|h^E}SuJPxq#!2G~{iGf58?u+xpH++qm zdc|olC=dgxz>Jao6enT{NzdL{4?I)+j3v0Hlp{jof}!CMQcXO^6Ssxp-?6c>=2&*5 zLy|!0L(QoN`7axqnzD(piieL6!ggvTXrgu?*+gFSn{l3L+p`MxG!#psiP5zeCHj$m#ci_p8UR4ISab+L3r?$AE{>Z4`sXYS)tlj?_cs;)PH!%7zjFu;vHa1I6b_vP!K1dJ$;Hx!jXs9$r;W7 z+aV{o;owlFpr9Z~s;aisg>oY)*h3ft-2<=$n)r&4HdIh}UW?NMX%fB_LT$nfm2*|@gb5bV$pdY!je)J(fitr!VpW|a?SYD+6*)z{{qQralNzesXH@E8r zw{C7PO5(dCuQR-q{F2Lr!=iP$@9L}T#A`hj5)y*Df)z-#7&l=VKp8tVIVsC&k1Peb z01nih1Plj5G2$46KM0th=4W|fZfp$6qIWmS?n96RiW88%IwvfA%ibQ7%Y5g~^?>|! zD^JyT&;7WX8wtffrP+g#%Hj1qFyYh{zHiwtS|7QqNS5yLmzB4$x?*9ayEPK&us9T{ z=K`D`=Loi|zJ3&-pyC}z(#rH|5u9&3JKvLgn{;~Th0;i5UQjH8Mi8zSpaUciK{om| zG9mz3Gl+x?*biVUAW1s14{}i?#ME#*VJ8X6qlXVS7CH?G1V_g|5DLPib6E!(Ry(F@Aptv`4=fp7(3>6*N4p{t4fIy1#@Zm$WoUsS-WRXd3eI$9zU>_mj?FAYS zW^W)m1OXwA4vetBR~T|CBCE!uijrKrY;J_NvDroNk~MN+akJ? zEP(+8Taa~;qaq`QIujJ1Y@sIu&AxRnQOotBA{J1@4bOl7*hw$gDe4>H#f&a z1hE)!x%9Y`Oiapb2T=7Qu*(X+u!E`*N-5OzBm_vSn3$QRKN=m$L+!(|#$BVrPoIu4$wAKL89y4c&IOa=D^9*?)$OC0OJg0?kOEyYw<@aYT zyXv}Js&Xm4z2zo4=e{WP(kL`WRN(2HO1?<%+_Dt=i)o+f)Oxo!B1Udj&WaV0*4bay zjGa=*vsOO7J;`n@w1e76OOG@#^{w*PIRm>K+CYg?YuAe+G=y82$%1OD>LmSr$zzyu zLLz}fyZW{UJhIq&1B)^alwBcU8cmV~&XpmODw>F>(_y$;(o{kRY?;$F2n2ruBmm*8>)y6|4 zPLaoa+py7Igj6v;=%g=fTItJwMzNKjlpaypIo)Du=94HXaj@xDP3tnFeXZi1BRQU( z^QoNGJVpv#(}8x5nth){?%bP94vf7lo$$P}>D#WqZJpQd0M^t$ANGef?@YOW6-qH0ant z_X>GHt;6un?ab`#zo6y@L=qvOx~US&8R1Y+NC;t{fsT$six{Zc*vmzg@G&ocW6Mgm z92B%FumpN`{*UuT9T5h~z@YHmqDlD!ZqDjw zY3as&zGwg5GWz)=xn=&={#LI|R^OacLfO2cRrO~3M+}6ew3h0ugxak$9}XKkQpa4L z_^rZjMqeMjaAp%7sE-dwpX_{{B-^#|B7ZkwFqkS|dnnpz$O*Fykin6b{z^6j|2HiS z4Vh?m6mQIJg(vlD3;$cua7c$_4{n&$0UDa?MZh*Io=2^jsKXw>hSrL=Fu}E7az=P*&Ss%_sezAK;)t) zLGnjVd!We7)kgj2eC<^{yy6nxI$vxfFls-*QXwEj;a)#++x3Ph)i!MIm7YWD7`<9waU|SLm{U*V_#&RyHCz08bMuf;HjDe< zZI?l}xoE;&pN+>NyLP>b5%s-kypzyN(YK#rbEbBTfn33lK=82oj-9(6bbvsxV4V6M zncs7INsU*CoHuU-E^5Xou#4kyrwp@i*T3ud%TVM5M7P`QO0xZ=^44R%QyMy71>{8W%sKX=!yru zdhGW+I?&~x`?|}-FLEVVzp&c z!O)uqjlZWqhnSVz?#Yc=nFta`G{zt4?eXg!458llISkq;#Cjc=#L~DqskPL05uT)< zWEFuNn}Xs)1@?Tetfcz0iDSPfPb)U%&g(t(Si96C7a*(^63LyI@<29mbh_W(?Ou~y zpbUAvLQekUeL_Lax_?$S9$cz^ch~P_rPKFqhh&e({D?UqV_;`z@=Y&))~32t_9VZq zU1R-wKP^@Z*J`pBa`KDfTTD;Ysycqp#Tykfbn@op2x)0}yT#_uc9q#xlp0z8BK_VT zW*d2H@Unq&6ZEto{w;e9usdKPWb#lDLDPUJ?^s(4d6Qcw!EzhBgjGfnRy{g0($Ust z1W_L>M>s#8NgufFe+eKTvI$I6+^-DB3I49AuRuBK`44t}lEfRvdFxXyvR8|~_jSNjh}H*gsrNQ*Bz;#x;`@8%8j z%oRU2!jW~4Q<^k7E{2nuTxKIf>uCY^Rs9|d>KjpqEBvCOii`R&Jj!&l?xL)4@1L!B zVSy+K`(yLK9x8`dtOJa&z zM2xDQp8MvyE3$G-&eZyO5GQQZ$z!Tre$~?%7#I*|@n}Pl^g#c%O;i?HS+aesFk&i1 zUXs|t(*&O!z8f7%`%o&clcM*^Lp2q`L)oA7ktfa0(L;DezkGm!b8Bn=j@OdTbf`?3qVs#B&muAI-c-?Jx9CABfxE^t?8 z?>Z+J<=19Ps+#G^lZVm?F;u76?KG#-R7>fPq9wWsicTGA5SVe0044v_0cD2AJN?D$qh2ACuFdGfjAcfuG;fwr%h~e@3DtY;5QZz7+D=YvYvqY!_ZPGn+<)l8zQIQ+ zh(AVhP>T+)?u4)2t5-C%wE5QEyyuVF85#Y=T85pe?X*F}BLb)b?2<$H=(`9v3{B#% zH3&Gh<%L)&*XyMko3<*mdAWs(x^&(?c8b^NON9J3&L+3D8v60hL!s>lJ!a3(a=+)@ zNr8yN$6{AG)lDFif`0BC?++t`Oa%BDzQW*d$fs+!AYCp4#$lV*MX6%JrNooclm(FK;SL^ za&AoLfbws#0sW5rS`9tRq&+5Ipc`_9oX57an zwrwXAik`bJBeMgUSGwHBM)ko9Y&!HR!LpJ3$1Ip(;+W$oO-WB=wrT*Rs%6BEb{hvR7ZC436zJD!cgYk2D&2GXC1Dy8YLe9Q)a*v&mm`j|bH59OZyr9ZVxAk}A5!$_zcsBbN{By}Z5aOmhk#XJC&A}k?~DBm0;7zFP2|5z3xPi6CeZ#pm@vH zlepcMpbUz>gdT);p{$0Sx~;VpQObL|SL8HJ9YmAS0VumsGEf`#+3+3Y>oFPAf6q?~ zZjxk_luh;ZP7bT3N#(#;KG^mZf(@~+tI=v0gCRQF+OqR@ZV=DGoSMIXLsK8wst9WN zlLxOTO|KcW%I?~u6J)zCMRQUuKhJ(3=K&D~y=F6I%o`pZN=lGq4^G_b{-zSJvGz^C zt!g2K^YWFFVv&P{TNB^7fN{G$-a(waU}AX@79LKAQi__ot*c8I#lM-E89p7Ft*a!j zUcLm!VldrJq5%%#n;UD!ydTj^xOz3n!3$&53b*v#$2uVI52>5kE!u30d3CQ@z7?1t^gEAeJ9VU+CL=eK) zr~5?F!#F3qOOXe_;-k;UPmZ~tl`89c@*uGDPW&hmpw@G0WBczg#O9?C&@@XvI)Qz$qIDKyMCcZg`O!IEV{Yos!mRS z@1l9z4jMpHguujbO)$tJh45s7*TMZ&Kd_FM{9K29#q{5`ab{&t&}$qWaU8QE&^+@C-AUW1PgNgqEF zMf`v{;VO_qLMH=`yyW`FosZ1T&(}6JT@p;+Mv#_~0W`EPm70mk&eF1{yPFPSG%Ksb zxF+cHXUQwS0jgt_p@RVJQcbu@K=OFp3KJDD-dP9-MAg~eP96a7W1<%{H+K_cz#yRq zks5d-Uu=DgQ9lNTNI=5CRN$iv^O7b&R_cY6{`c%l)BBmo*3L~h-aNaP^waw!krcv~ zU9lEwsO4{(j9Mu(S{wU~x_ABasi<%89LAd(pJAeT=Kt*3C(pIp7|sOP^#1J2n11Cm zUVHs1kjz2g6f&rga>P0SMu`3&Ab^Og_au*HXumT=2M}`!I|&dPMa_)W{4eBQk8ypUc{Kew|HCVjqI1)~G*%Y-o(nvSO(}lny*%M^T28*n z*MDo__DR|Phwu1x1NRbn#VP zK^A)6wJ$j^1583V#`!|O#DlI|g_Q8QX7}iV9|Mm)y`pO%wFH~kA92rmuZ1g3JKWW6 zGNvC-(eqrOQC&Yjb*(oxY`0(0UZdZEp85!+&0j04svav0qt{yKFtUf6dj{y+N$M4d z8WH!MH%deBHew~bk1{esPg5Z7V7TUqEC3Rq^qkFWzKi z>?9mHf2TQM56!cU^%XvXq?(!|wiXoUsX&>zbxRmo`Vo8jOM~jgEiWTyrFE4rsc4d{ znDe-N`?UNxwtu8{Y;)k5?{V(y-)KUdT%3+EyuJFNGh46u;toI5I{L9fp#JkNx@jN2EqtK8dtcYh>ETSIv+|P6&~V`uzdDZCiR22 z%!m7#oM-52@)|Tcszw`?OC5^e6tm8#4!!F>+SREuz?E?O1plN`_2P%7JVhpnzVC&6 zKi%59oZ{bPa!t+WQBUtZ7g@T#6LpNlw7A5H>6==5YtQy-Wo79GJ1k0R=`j!po$W{7 znOm&KY%o$#0DWYP6)ipe^N@oE>hqKnEREb0%VB@A5=)p@V{Pm|EmF9&ss09bi}QPD zt#k>FY>14a|AzJnnjtLID_(AONVl&g0$)TolvK`JP9A@yLxclXY zlM_TBQKOjiuj1f;*_x5DwN`kXnOPMW#tK9ezccS>?(BrSGN^nsTgq_Lz6z@V+$RyD z5rEf*n~qNRT?X__i1(_nM^yV`!AT}MxP0hn&t}@}NXL^um?UnOmi}Sh;EG82+by1y zxX-PQC(io$5$+;+HT<%5jn4DIJ>M6y`$y)F>YMc^O3$cO880{!=jA_Uy>_ZTX7%jK z)7TW%N^h?$2oxeY!=K?W1(s{%+ABjtA#@X3I|%<{Aso=|_q{m(O`gq)KWBBH+W)Ss zUt2AI`!J%awG5b&(0Z;XU&t;`XIg04-oGdZ+mY(;+S{C*PiWH=6hxhOoku)@P!qsV z%;#c$?_XROUGKjE_N_V?V0`-YDRA9EmfgF3QO!W)>1%hlj+|T?ba46#ol(nG54odZ zg#9P#H1-_2u5c8AG$F!w^O&6xIT|ZC3c0zsaL`&?T0VVBzZ&`h&^}I1#NKb6ok9Wv z;6l|5!(#_+3;ZOa1-{l0A+XotV?x4qe_2X8uD_)BS(Oqg7WioQ@Ad)0^Y>T1^gNhm z@sIWNY_56g(D}2B(;U{(=_>f>$Ruu?{e~372q%%-G0$k|sVmTJtyG-JRqre+X4+aW zA8B_C{oFa3l%1c?JCQkkns)fa_C5aJBKfG(2HLuHB4W~J1S5lT=-dkOI=*R+cUpe!@AJcY-$;5aq77Vz)Q4Wgq zU;!!tG#%d#(OCc%c3p38798GpM0gNZ29uK+2?=;$cnD|_9%5s&u=ow;2i!Bl!@}Sq z06_vi78WU8T{rdEZGS&~-k;L)wX&h3um8fzWi~1#&5w?B(Gfbkq}g8-_>}l_IPTsH zA)Rps+{?$D2ej0ZqP_yWKIbL8&|4AwhvuDwV+{jc1h-B->nYyl>j|f7kt27PZ2B$# zK2ub5n|0-{$S!Ku>-J~aH8l^?`|CfkvPMKYvVHr@h^Tb~8vYq;Tjt=)6eArX+Ofkw0nOEY`To|Dl6QmK@~`PZtrsjwBK<;DwXCWNVNKy$cx)^Y=)t{(Dg$7B zR4RbVq`py*60jK%Z4RMh2ok*?>0)!6^1s@+U2DTFe=Slfd zIeB?lC^0_%0u6cmJfzLfsur{C+xT$<=Y+Jz%ZV$c6gxXYUooF}oceUN^d_Uyg>ASO zR@Mnozs=3J6K?I^+j5fL$>lhLCpuU*s&j2WQ@FV)$)A1{P=9_U;nbIaCcn3P*$!}s z3>9reXsp`iJm<5?%ey@E6(yon{JF@IU4B-!virJRT~$vW+~Xf_TkBC{SgU*RixkC? zT?{wPn2`@XxsE6cxqpy{E{0c|p@E9Z)n!^A+uf~7_yW21qk9oh{XhOEo@zf{bc;)w zSFQ|{u%lKWKZ*7b<9l^^c`Hdpbkl~X(#pW0{$a`TbAMF2P(-e&!d6&xo3^U2hX*y| z7uHj!1WX3Epu0@7FW|Zd?Fj1*>fnE?{k65#5`FizeJKCm-rtUGN-~#eqZq=pjbP5N ztFNe0*HV&La?hbA)#aWv+afg?d3}9#)rX$K^5N0yv#fkMekHa_lRJ2QcM^^TU$&d6 zV37fYhKhL`L32}{!&^P0e%DB84txLIDgoX9S~hoO6FI0?0EmK41f4$YMdZnFY=Qp) z$%*+3%>{%@QL@3w#n+HShHmX?cZll0dQENa-1muD@$t?*90&bUOr`t%zUKu3mC-S9 zuY4o`gg0hkF<78IoAXQ>$MPW1W#bi6dYOZ4EOXzIRq%Lk?sAoKaoG%JW96o-wNg#& z--V2!uRCiuX#h%n%wDpI8IAr-dU-B`qUhk;`Jx#I4x5Jb-tAIav;;suI|!z>8z&qZ z9;sdL=Upv4c`&^sH-k2CN!;1*w)&2vp?CfMraFNh20$_lJq+F#Xm(FvMT4@2+6sMk zB&q1xz!(DpkHqGETzq`x8n?*v(8YEeo8G0#IG57~FH7Cj^t9{i%d!m7JUhvwpV#!T zBDQ~Yaqw2FnwJ+-3ZQ_w%*=CHN&pOeeLRD&8R%A4m$Rg0$`z+C+l@;Be<}>(l{ID8 zx#;QPDBo74OyX$9Dzp6R8)ef~w{xNoM@Cc+|6Pb%DD$O!?vhl^c2(xvcVhA+D@)Xu z8nr(=>V4$11Yh6p_IR}ug?%q`9DE#n*hZclc@|>y&db)Ylk32{RP9UJ8NJLIPpef= z^>Hw^#;--KY|QmV+lZP5Mc653j~Z=-t$3CESt4se1e8xfEgEjRbuub$B!tGpB&R!ic!Z4ET5xTCOVC?MLHEF| zSJV2L`yNsg2>cg;7d@*WPLZHMKs{vJU$g=WJq{dnP$3>mLC^n0bw<~KaLj`{ibsP| z_qwx2($>((c;%xY*h3hUa#hzyeW-gdtpXy1%{A!JVxAf=;HuCK$MKKQ0>*`G;87cN zd@+{LIAl%u?5%xdyKanMP|$Y^CeOW&X^rzVXWBxqi)VLyqV0>vZ|b1{7K^ZoG7}C? z@PuoEwOm~tT$&tVmW7dFbe)|@caA-|Rk>UDVZqCnX%w+ak?>?A<3W%@yovQ%NjsXY*&{BdHL91 zDL%0bwB>RzW#(VXba4z*WC|Sk*9yK#gzErYwJ8ETm@mjiXgQu`2ZKeiHE`J^TnGzvvXgc}$M2d&rDeuU6#VRzCB#+s%&m#!*m3qfURHs0`-NYmh zlrZETg*&#Bu^&{*JcE@}^CSCL^djA-TF?1K#l%qV;&+b9_O?fv*_i*Xti?SJaKGJ? zbxpvw;fh&P@w>p-%AFEv19G>eq-J*?Bp1fQB5Yk~7=qi5s)NHkn4t*Fh&SNzg7k+K z@dbrXvdaQAk3l)=-%i-2wxD}$zD{erQg+@ly4m@>DdmZBqkUI?DNF1cR#* zvV9ce;!e*a;x9~1?FtXKv+ZT~;d$s|tfApV`ZripeK1#3OS9rU`I+kam#UhA^fy=5 z%T4<3ZKNKhw@OGR+ZXZs;GbE0F91xRH*sw~&y{BqB})8_JKD{crZR1fs~w+I-WRxi zq=5VaEdp|C>PfJJ&?y1<1h%o^Dr^jLPc=%Hpoj*00+f7Eh(bd`baZtCAjB{ISG4Cp zTmWnsFzWTMUk9UiaPWq;HJkut(55}(zTHV%_-Ffgmw>=l-{)gK#+6>jd{hkP+E@nE zD1NKXz`e21KDcB_OG|U*%)^CH#V|{o| z$M$TQvSoTY88Zxr=2y8=Xiql;DA#Yj{IT^wbkt*is8_+xH-U9j`~XTy;jRIP4%Fs| zwJew!;N*1wQNF9t5d+kN)U>oISbOa3;JU%=Z4}53)K$5Gn{^~XmxH$_Gr4TIi>X`4|v zXNnic#E1vSzL1M{dRj;;O~z5feay!^j6P7Wc&IYq+A0mvaKhtqSi^kMIly>yQaZ|= z&2D!TW~u9TIf^iRX}ngyPLS&1hjF)+b&B?Pbqi*Jg8JwrTj4F(^!G~=q|4~ zYPeQ()@MY$9*#&q#k~K;vKg~1>*?cLA}IsjZH+t{bw%pr`)1&&=0%O{)K z)ij+Op55gv+*li@m>kfiOv@fvpWY0Ph`)CwaN02X+}SX=hia%^J;iZCZ+Yd}<}t^{ zm;=16FRqX1~o#phP_w67BihGqd&LLe_xq*_io?z z2S>%|qYvxE0$YG3?kGoO1JNu`UY?JK$NZKzast>$9XfQV(U)V~Is~#cDK~Z?Fg}0# zmPi;Sr94`M=|zNUX!Au2+Ydcv^16}Jo#%o>MP6Q>;ryMquoZ?A%h;8@|EyOFxHgoP zm4zgk{C+X>X>oWdkmc&0=(LE(ENA*=uNlxOnC4&j)khLeEj2G;a?sdxeBan5vKl{s zwdV2K-|=c@t|r$Q$LCYruJMdpKUdW}Q@c{`T5I_3siULGrpUI6gESG2y%Y7VheA8; zVv20k9*kPXME#u*H=b>e)=NvV+ir(5Vkx%q(6iEEhsD#Jr_-}ChPu^b)kho2 zUs+pSg+CPkH%dv;mg&7Iu(5;dTqM;2=Oyv2y(!75r@1(5no?}t>P+8FGtE!8DrV!< z^P!Sq%p9K8s`%)tKBXQMx+TK#ap}(Y)#xYka{Hyw^%fp=bR%b&AI=?k5_N>`_;IP~ zNQQizTAw=3Jx5xcRKFDSNfszDa5Pua*t?%&l7zUgf&pxI<(gVeFuzqw_!! zjcVnX^JfJFis5kyFN)IG?BEH^+JS>Mo>W&K2oHJQE*%>LE znXkhRuND=i*LFK{t6hFV#cTXZemzHpiB>Cdzot*w6R+9Jx~lf66B(<~2sqE=<*scG zmmt+OUusFqsv+V>Vd`B$+zg@%>) z`qVqhS_W>`b~Jo{!^xQxa*$f8TszNp;l_{iV!v*_4Xiu=;K#*1jwK#Smk%D;f0HM? zH*!4Zmi=l}nA4r7YJu?=znZ-MBc5ymZL zx~!n^S~De1=_>5Ihyy>c9zvY3y0t|N6`Y)okBf&&7i)m9O$$?`W@Y$!uICzs&C%J;84$MKefItGHr2L&a1@ly+hxcu&*z6WmQ^4>KX?{ zq)?=rE^ZdfVBnd)zX%bTZDzMU46iQBYbyFjT%Z&Y=*SnEA&(Jwpc`?&u;wcAH2jh! z<_C*@9~_rWB3sBf&nP-qW{O?8@^xbT>7HGgS;zn$Zs~9Y)KTf*?~vH1|7bAs>swkg zFMT<(vqD0Y6ci(W#<)@o3w!G8Ps0P{Pn!`yW0cOI6~l|Ba;uJP8{yo24DrxBGqJFc zs~ba`#L3a|&HBvt3UZPMR4jyn1Mx{b;RkSDr~~SNMHkw zbbk)v&AdRhCk2Ngk{zVpB*7vBOLwBb7fJmYW=lEw+guIGItInXOM_28OQbTiI9OPw zG53T=q^jEffMN$&fT)pJv6g@T#|IQ~x1wE2ilc#7Y z>Fsemc0%MK6)!;gveXDNW&js>0ka=2(SzwQrs6=o1DuMsa9WZzL~t;!0Q-I+pX0~H@g@yTh_AtWCegZj@pmneI7nU>Ak(I*rFSI75 zTuz#|&6gSvd>nS4f0>dU8(XzF1^=_@V~$sM{_vx&fR_>|XQ(>(+PW`^tw`wXJ(pbS z(L};1B1@*KruGcBPpwHmH{r;e1}y%HqGFP*%*f=VzIQB8Ozy+T;W?8G04~sHPYx$F#+qQizzi)2N-@C_Vhrd}AK5mq0{T&?kJ40o1dWGa_ zhEmMT(}%KGHemlf>3!wFaU!4n%O`As|{Ojxqy;>}2+B$ikCSQbvb|sfeRh zK(WVX3=nuUHQBiXC58tsU3?%c?D0p0bdvk<+E0CI{xcjL7DKP)c0D})c#G_}X=~)P zaC0N{!npgLZnO{U=+P)0J!jpuVAY8kSJ%=EG3qEjC7MFj-~JtAjJPW|Tmrip3Kwf1EZezLIMNxz1@C%kKx zmpj`|cw|Mt75?fXr>q>ybF&*64kNb9=mKlu!*- zva?^bVWhR`s(Sn*E>Wb=b0qll-kHRNWxkt~57qWU6!b5e{^)995_qAHEY20}G0dr> z-Q{btd#3^#;~1Bks!Jsnutr8|-c3kAaSUZF@*Vs&(Z}CZ)&;z$FaLDS%5jci7qd%F7foCdT)8? ztk9^QU>u$J(&7WVhiW=H;U7LU4zIk4^3wj^V|3xM^X6EVgxB}jps25pH6kDa`i^9ll){D zpo$J)l0c!?hQ=le5~<4=yIorP{qyG^+zOdXm()Bz?8gW?I)f0rju$0!Qo&;tn(Q{X zzQ2zC0%wrcq+wT%#GVsyT_nM0Om|FR1=1)cc1>A1yKDp0PxvOI`!}vHD*&}@G`v>V za=NjHtjF!0oduYOk$zFLEAR*kUe7TFYh&*KjgQSEjN11EQjn7iA8JH3R9d=)c4d#} z2c5jY9gGc)L`VmI}68t3f3XIj10ZRr-ED{FJEOu&Dwer)-Nb+*EcrOxD<^oENZ|eA%6sY zbEL;O1M4kXo12$^JZ4H(2u}b8ias6uuJJjrOwl+34|X4e;AyP5oD>XTVp0bK>PfF( z!vZ`eGE&d`Gz=&y7zC-{o2`yE{ZVm`>ePphHJU)oP+Oy0C?g|-VLk}@s*ARQkOP5m z*h8kgey#rLPmkvnIaD1u0$-ih!S-i4bqZ=w2$=Sbjp#N)|2`@OGQJ(n&4c7HD|!kQ z0Ss?!nY`Ej_;Oi zgAIGS#Y9{5_MNeXO8LXX#<;cT527PrBZI{VYhEZ#mZ0{4);<{KQ1XTXyuLx{5AJiA zEVaAkj*Kg^0VI=HJ~Q-w14c9T4k_-XI&!4mG^g7dAZd94uu7DgVoB($8epcDH zTR*0!8!d2p0oC0C*8v$JOg2BjD-runX#xXy;K^Xr0Mj}26FCJ1VZ>Bx5*#ltHGyFU{08`ZHD{*%1>f z2CYCXb0ORG*U|Uy*a(VR`syc-w|)L?b@$cr%OTSTxhT;dkc?!9s$17C`Mjpf z?Nx^Fx~vxwFJ7&!jvp9OyzClmXPFWg_ZFi1NStvj+7s1G)JC--se!S>I%8gRE7S4d zGct&C6`*>c9I?c7PMv_&H-PzYOm}s6MunTqx|Mnqi2`CbRCXiW>DDPJanKx|5kL{5Tl^XRqNNK zqk`gpgV&kI{YG!oL|!`kN72=Csk_T4ZWqqNyNmdpnT_+5Q5uct=VO=?o>}yV4u#NC zJF*_T;VgOgM|+yS8-j8!gn0P)_EJ*9=GZK!8wF`vx^qx^qc6Ak>0T@qGG=HfL?xJ` z=kG(+xJxGL5E;arg!wigpx&5cX30@bGO&H3wDgx?!Do_Cy<_v|{S>uM3=45DfNrpT z`(;VOySL_*h}yailb`rvzOOU~Dp3Z9Pcwv*AKf~y$EHkOb^qG~jRmxd-XN_(N`Lbv zp1-BN{hZgvDxwtn!FWL+V8cvHQ8A`iMp_!(8|$82IbGcdDySyVGB8-RWX$w}L=sg6 zbEq5dwAtC&8^%(+w>EvA!vMGP8?!YFwxASJ@oMbwZv5XAf zua(yo)@QaTQDQF#yUV?s`TCX3jq<~{Y1?|&-J!`ntwBRa`wDK@+I;WJz4ytgQl`Xh zi`R$euqR1i^SEhs@#u1DC-;3j(KG95O6@NTmXv3%v-+rEzPN{N6q7Xwl(I&@Hj!0~krPu?4)9(cUD;1?r)vyIThDHu65HdcV!L}a8wq|0;F z3Hug#SEinTfFd?MZXT*ys0!eiMF-#6t(WDU*5IGBl{%YS^AV_P$=d735jz zxYjC1qY-k*=XrYVQw=57#mwlf;}dH2k+jdO*P@p;L)?f@qhHK>NZi?6M#n-ZSbTwW zVcEX2_V+h?)&1d2)Gmdhs7mXKM}3yEH^lM<4(Ew$DmEy&gle>91{)5TBp=VTKiVL& z>veKczM22`9QV%M%!f>p^k@|~W(D;X-^i7Aw#SHfUUiM&)pWI}L7E-glXG@U{3B%)|+>;Pmaz@ALa$T$xW0n%z8 z*;|3KB7;HBW1z2p9va@GE>qLw805vs=5fTdeuR29*k&x{sb{vqJp@c$H z9!C|Q+2+Q?JkD7!WDnbRkYE!a3))!z83+JnxH}%n4P+0}|mdGQrERqg}Wl^RUH?6j}KA2gAx^(amuTUn&)g9cuZ0Y(xex z4REAc9*}a=(RQ=dH$3Z5blb%U_K>y@vSP#vZq_6$xKEk#zhxOqqF%c=z4hDk=fm4V ztfwwoN|7`BxHtLBFk15c?(VZf6>h(}_49B1;ODy=v`pcD85GFg#SH#!^Lz2?b{qeK z8~NKKKmUH|DYoi$qNrcrXUoOKas5+MXxR;O7on^HNO4}YFt0ipyLK-zW*?U86YVF{DDd-khN`Pr*JXPm~ zBnm{S374y*$@x)Lr5lTSQ+<}%)5qA@azSoH>iEY`{Zh0zki36zb^t&SEbxF-LXV!X z)w52za!jgJR6KOUGafznZ~_}AjZ}Z15fnY}Os(wFJdYIk3x9&Vn3c2PR0rstjGD)M)wf+Fqx;D-np%}kTjrAciNVn#;lr}K?I(v;#~c^QtsjCu zRD#c(f4wE`U^~Sw?%5K7o5m~{oN71aLzVpexe_Jy^aBT9-GMI>+<*D=Uzco9ODU{T zwoIG;JvqywQD3j~?)a|-$ECE3&-Tp2O-!xhvgd-4&|I^p)zO$3i9!MENn@qP-DjQ& zKcrrYVUX|Yn%ioO+D<}b9S{iX^4i+c(&~PH)FI?iSooAGD0rpD>9b1X?d0bwW)){d z!Yz6u$(RKMIyyIs-6=mz3+3K>xW=&}(oONfVdmqz)CCv{@`Ts-$bX0BnSDAv;5ggW zBF4HXQtg1VV*+vSo}bTCKN{nZ!%ITW^u_hman2^XP%M@I;|W5;PVK5jQ$yqMd6SOz zVb7Z6#$EOnEIwqrch7v9ogLLN5_=_*EjoDOG)wIb-ifI9&$Y(qMOddINk)?UBf=e? z)+)qr^?s>!O9)P$9{AJX@V>QJ@KdDT_mVpvqh$+@tn7{EZ(~>AMUFH4nSC9X@GA7r z%uSBXh^CKW>8@fzx7SPgQtn>(fu1v$?;80zf_dp_*#L>rg}Ts=qfbwb`#k@owa&>| zi;wi9UmADbiDz&wB0N!uE39Z`EUAa{qw49Y2q4zpI43_;HDTtM5r-O;c_}UJ}a@bV$|VoQ~!erS{J_Q zixsKZ1RiQJ$%oAarX#XDdt=YP9yv!XwY@2JkY6Bsv@(Dg26#?J5ePf4X&;V1)1#C3 zw7pP(i%i&Ky16yE-r0L@Y%xfV=3-SB?V(|b5?71Hr(ErMvicFi>il_>Bpgxc%nKddS?1{qpSLl#F~jS2U+>%-iXU%h=9 z2DHwZXZJZC>D5Gj=E8W>TD%-yOyXk4nMHo}oomYRc|PEEE%en9m(x7@moML0rL;=C z{>WO7w_(CEwZJ%Kb%TGV*%O~E?3~?7o2d6X&&|(qs?=B?K@!qeN9V|x8zw%!`?(b@ zvdga-?ZB}{tkO&l{+F;WO-S_hr#Sm-&gQ2crp7@|gmxk4DH21DyZ_+=ocdthl-U3+ z6!=f|^hER@-a)!A1F|8V*@vc|wMN8>=4N1^LNF3JeP7QG*E@H}8H661b;QSISZYqZ zXOTMmsF=h_wG;9?N5xEDX$mDioqvDE^4e(jn)6s#P5V*(2uqifEpk1UMMgI-TsLvm zi8kqm@BFRrX~kR_D4K@PaVqM~stv@mM)o^Kry3pzVx2VOAMPfHu(Pi@#A*$9h+z??@a9c>I`Df;4kW3B}yR&=5RbPqO~GMtzUI`Ja3H zA9TOFX9qw98)1)toK*T;tF*bZQSR-Vu8Uzy-wut&9Cy~#OcFXYGS?t~RH6|^Ys*J9 zxlaBA@PGT5cX6T&!iog*WE9g73ETip&56{a3dAMI*Gx@Je8MDMVGcpk-NC%=DhHhi zMYJswwM3DdoA-~c+xaij zIuJELJAy;?8I*u_cCjHLGE>&*YB+Opb4xglHG=>y^wUODLjz09X{I0CtKP1z<@#{G z_C?fAkZ!{S$rG@d>FLpsjQVo`3|%C+;Os;721OYXWd21ZI`T?Ds>rtb{B97MUrdQ^ z-FVX!vLdlnxbd|^?_I@WmPBjx<=OaK+hN&EY=^ISYcbyXpDS6Z%ZOP(2mZDxONe=I z79}TF!Zlb%=3$|nt+jOqILOH7x~&Bx80i`As6<1RetFY%0wj9kksBa|FU>`&+-WZr8q z-8;NxO+5JG!a>tlS#wy#Wue@&{r;h$zaJoDPh}-EQU#(WTxm{g^PnI?AD7FZ1mk{0 zeJEtY6u0Y&nWU=!t!LRd*JgtB`Aq9^<3e7%`28*O`~6*ep*1k^H|@XI)ShkbSdhf} z8IZsUg)j(e85tWpVO$rG6rLss3PiMT@bf)%31Efq2ANPIo1VTbk%EE~S zB_ZqGIR~BM=1daZMON}Y$PnFv|G*~A3cGgg$_wScv$-z9 z{I#($AjhQoIWyduAWYca24$6}zP?Bmqt7{C0bcgb)^!o`yPBiN#oX3Eoe#wz+2~}$ z|5OWaBrh$`kH|}1-l$k&VP)OT3|KLXkrxV+xw%e&|A371oIR_PXW4-y36pFeDK9X7 zK{{`@hoqVOn!36JePIoUWZi1eg4{=W+W%bb{l@b9J9j?6OEA3I@}3b0Qb*Pv?b9^O z(pp-fbAiAPU+Ct4g-V*TvNG*~15f?^M_Rd>yii|^7x~m!4>swTnkM`E`$JF=015>0 zA{(Xw{X_jwsJJRQTTFfmpc)44uyeiEri3t4VBocq1i+(Ry|_}PN<~R&I`aP9H%lDz z27uUh&lnJaCCWM+mrH4P0B`vBtt-6Nc1#kgXU0f?`OgqPjG2HDWdnQQ*%qBUQ=%D%{? zp{3EvxO1nDhDpUl^Civ9(jxJ#e>XY(Swrcm+A_2tkd;Eejg1YCm~7y=L+5bcR__IK zfK6Cc=mrtlO18GB=A!auaMq*llH(Gq%85;$Xi0nwLS25o3r-sxOMs?82q`IqiS>iB z8wY7=JMDM{1frqAgTiI|jvWw`!gK&O)WX7q77+t=cZZ`7N)Hg)iAp^XY5~yA?t@_v z2cW_&EiEVop+5)6<<~(O=Y9^Tk$$bO&*p}s->p4bW}CZ zd9B|meDE(y*sOpH$BC0?bpliHq@<)mLivyZT$<>dfgT8hp!G2yOzi+nx?bqyTNqQ- z)}{tYwwfB>a~tnbX>uEsoJ0qn=C^G|tX%?XtkF@I`C&P15S(5BtSAoi#FdGm9tKo6 z-b8o}k#KJ9w>KbQ2K==xSrI1p2lLK6#4}G-O=MRHi%U%{02P;;I~%d&fYcF2MnJNu zyV@@K(-V8xnM_@SqM-E>3uR~Ljc+cb&E%lv8C3=pJIqVAjmB;Fpcahu92vfM)~E`r zp)ERT)i2&2sJ|P#@WYYd(IuXhp0`3Fak? zqPKxj7Sna^%VR_z9(d=E-c{cwNbuw$7OE?L7DB`3Pj9c%Ot*?|y;1R{yLKA7`gh!B zNb* zx8Jp!X zpY93SqWu#%E&MM}n;=OF9?YQw^9p*37DaEt)+#A6|>SHqvTaSV2`5-lwq#U3l~0Y&z;ER+6Ivq@gURJ73T$u1%YU2yBi{my{< z_dN=!FEAWGG2r?)^+jaoCfLxdY;4jlM@poKRSkiFHg+}Q`L}Pc8ce}lMsEPX=UeU5 zg^m{@KO6Hx&nXu~jl4WMa*{s#v3ta3k&)HpjDZp7K_e(MN_@^Y;yK*DWK{TokjoX8 zzlYF#cIQs2y?YBU5}0(fapL121hRcm_S*?mP7x8_17vv@{B7*W7wx#$tjyOpK3Z9N zeW$|xrXsPWrN9MACjKW`lyjlFdz<~g_#Gla5?^knA0=Kgfj~(N^TgL3$$viu;qwmS zx*@)f5>a5{YxXV?1HkJpDY4H$e4UR&N<@4OZu_^&{r|t}|DAjFfT!=@iy>nk#`GYB zf&&8r&YV1n94by!DUuZ+BywtV^Z(V}mxn|Bwtf4x(S{Nwgch2k?NvavQ-}zfabbT~ z7XYHO=`-;MN5S8i1x%QXPl<1!DWJtZ;^d%1A5fLX(+FGY!9~7)k(Z zhnjvT{jdS9k@Qn0oM7NOdH|z&+o!VD!qAPvuCj3|izoM0T+I z{xpPMkx^9>&)r%r&*%Apw55g)WUa^UZ18pt)1_Fn-#ysfImC%?366u2e9Zq!GbK4w zsNW_auq7DM%;54D5Bk?V2S_ZItLy?kJr^te$!cfc{2+TBWE4JoI_G0L*H%~P zL|p_H2O3FXG?UVh@I?~hRpP#n2mA>fkfJw4j9cBCX-Kid9tG_EL z@9z0d1>X{@u~YL`RPryrK|j2klV|yuVrQu(<8I$E^X?0Y4SyxP&9@uvW|*4i(#4pD*NnH6SJ-*5!LO{LmR9sZK2FQQVhkeE!dLh+ zvXf;8x}myEa=~c1Gv?!^FIT>u(?AJxWTiGsLu~WndO>38^pg}nq^#QSFF&O9-xN7L z#t)BuJ0$t4IJ-JJA|4z(!VTA&s;|5NN3QMG@Qa9mzgy336kC(zlc#v`enBB^o^D-fkCN@$m9*?1F2hUWjzxUF`a-NzE)TVQ{FPge*95+O z==L>XZf%jeu5qU9#rtnNBOS#PQSAc4+&i!5SlOmVQ;&wVx64ykrqfJLyYMw-F5>?l zHhA4CoHIV_{h2jn(Fmco`;~@TQQxSxg!aPs5+2^;t*DJplYK7}5X*1oGi~&u-O2IG ztu;00FI`wKNYBkhS9DB9PV)Ixtt-jSVC|Yj5Yt14TZX$Ib#W-Wcz&Xkgcxq~=Gvsm zwOR^e805OC$?Q+29+>R`A&#=Mk~DTBT^{}0TFhB-GBIn6k5MhL8fq);LE2l*H3IZv z;0V3Avb71Zk6uFTo5Q}}`1kj2H;r^1xkAvp*fP_=PcN;x(W#93U-q zocU!9DS4TTdA=)6oqJ3w@DJ8+a zOjF9rzJ7y?yJI^xqg#3*L@jVfv`ntGjqQ5Yi8rsHuE>O`8KvY+wXh5KQ&Vl%{TgQI zq;{zBHi2h#4*lKjZ-iUFpOuskI+?*I{^EV_*kvQ5GY+jv;O|@KagClIw8(X-9fi!hJt3iwC{oc!;GU505t}yJ zxdmN+IZ{_Ybk>p3b;)!WVtEy}mgpxplXR_V-gwe)F}-KIifYLATVQZ^MHU4fTfJF! zj^<2UjrU6J3dL=L4Pq})M{6`2|3p$YPeKzF554L8Ft&I43g_92c()4zZ&r8e72}O1 ztiBTM1+W;X@bA0=kB#yy3d-tz35)+6^&zMk&-jCWcu7sJXCT*8G#*oNk#=tYE>GN_ z?pq(?3M}d;c>DCk&5}1625;7zgj#CFp%H(6$C^=`R-O4$YQ7u4pb(eZp`U7HuBoGk z-_wv)?Wlr~(CW;Pp-%2feE&+bFmm@p_)^t?67uY{Jp0A4X>LTZg|?Aze4*z+Rpf4= zSc<%?yibEs0L}9QS%Q9Xbl$gSrf406LtDFi`s8=B8`$j8&Y8Tb0RwTb#LSd=7cTXI zuOHD-3Th$oht+S<OIqW*)M)w?iK4 zj1u#M1GV_hJOtJW(UEuEf`U_c2yehe@gIkaJ{Zt!OFa)eqU;8(T`eW=gX3a`{PMql zd-1mYBRLf#y$KHJ<2i@WJo%s#kRCkyA5FkV(BF;n_ME05Hc_@S?D>rbR`!pJOoxsh zochJwfO|As`wfH1-X=ebyu1N_aQbU8d|m=@%%1+c@m!!{Q)WhXxxKX@e2WF8$tsim zJhz^#8>Pg4bdQ8YCk{%|ygWUBI2hM1ukac1hG{!?X=&Mx6g=9%k0j+r^RJd0MnD^i zM(b=3aDfQ^f_U>N6C`m}bB>i(C!_Div;WXZ{9nEL-gNT(*~^9=wh!;S(bP}WxOj{V z|G{>}1Gy92gyiqJ>izi1lZokRFI*u3XMlj`F!xCrlL2Szx_X#fykHmF$!AkUvchn10~9yK!x21H7gg(1)? zyA=z(>ojcvJcH+UTTQz!zef0QnT>w6JFlky&%?*S5sZM0B9c2T)aTAMJ}v;L)-1VX z45(s&itDSbowcw4?Wnklw)Hzl&?_*rvpO>}ufviHi>6dlRZkx(nU5VRf{7dq#SQ%D z%05`2-Nyr{TEI&j55zrC{Nllb2L=X8Zm|L~kkbo*R;X_RAWq_Xx{V)q`t>5ilPICO zS%4qRh|R{lDF61pRr^0}kN-6h|NpdsjVg)DlH|@wNN58;_<<`N0vC(7Nlrhy83ph% zAY_IYFif$=^+p2ug!PO!fiKcjTyE1iGq$8d0kYTf!R zYTu@}{uU)w=dTO736`Rd8-Lvm#N*L;Lh}YcaSjvXJOH;2;SjZ(j%$YA_?3VB)D^px zGAw3u5I^e(V@asDu@e5r;89*JN{t-&KFpPs;zcY3eZ3Qm1md;!Zq5pRf+xndCu2bY z^;@MiH5T;Uf$~wa!F|{7_Y+6d915^hmp^Ge8)-sk$~`=|NOSG5`P=kQ8(pM3{h<74 z7fQ*?gM%$}QR?)8hTJVy4Gc5CzDcW1b0tjHzFy=c;eygpP)u4~Q}32v{ULCVL$NQ& z1q(RXzYBMu7FeTPnCI!jc*07av)Mo9Tql1l%<;KTsFMbcjObMsp$_bYM25ji8@d>> zUGJ|H3h(?$jCrEO8UGklea;y!?TJg_-f7tH@;m@KmG{<$NB9v}Q=ZHq4|P|jI6r##*?+JgOCzY7ag}n;;Z*ZS501r=S_ne2Ru=7?Jn+B8xB?vmC~E%q6cZ6-B!p9!L{;ufE(7r0 znRN5~!NdzJsMy=za8fWjqXI6oKOyBrr!S@+4cp|RCgddi!Dq{QpV1Ha84unDR{h9>Dsj>=d_J~ z-57-W3KZFr5#$c;rH1(3RF}PX_eET~Yr;EGnhQBgsVuANr*?L4ca4Ik8q;Z8?@&i| z&}Ua%eF;`(HmEypjILPyXXy_LGM)oVmnlEH8G%vGgt$0Oe!)}1-+tJI*y`=LOwvn! zzpfvuQhB+Z;icMe10!~~$G7|TVYY1p`Qga>gxICfm9yN6dW|wQ7#_PXJ~ysyW7-g- zW>cnS_PB+$CbjWX$pEp-|DKC=r>YpzJhq;@;dGpyan*BoWQnTt-0!z0f*moR!XqSY z)&cLu*}m8ma1_;76ez+H?W&{@WR;yDOd817mz}a~pM9S(71%(#KEEWMn^ z$LOsZ3P!J)k>gyq$1>0>eHQ^>06;oFDkp>6rNbuaz6)IAiW9bmB2BdG7;3^%W3OS_ z){X*!Q{<=2^TV3O=F5yiGLp>t6ul!%+!ErfATWPB&(m`{q~gjup}^4Zgw6dV zprb#U2z-O`l3h!?~AxXa~yh;%>hSuDt3q2G9W3X zTqo^lE=5G;HH_{eZbM;rmiT0P}7{!s<28h0Tv>HkvGtP;!_#X7Fc2)XH%qpCs?x1mIb5}C8@8={7aQiM zk28OWOBVDXt@idLH0FupoD+n=5J?#=Hf4;$b@iP)AA(!3u$|@cOZk`$c(!qBM6f{3 z^f4*{BJ9V^M%)&WZDr1K?aDNdpUI7rSu2>Tx!>I%2~J=e6G0Uf)(wEXdZ3H+!ri3f zK{@nTvT1whA68puz;u59L31E(Dets0UVgWIdQ3!PAv394noDR=be$zQI@;25svkCo zoGA5iW>BO(qbbaI=6$^;FfsYB(t}b3(lqXA*7As#)qgFpGr(VZ!o|*_BuX9mJJ}A! z@oU#=E(1DzEr$FEJvJ>nwF1nkW{k`3pi418s#L|KXz{T07i=u)N`32+H zhjt7Gt>%Fm#Hn}tosKgrPlO2J8&Ttb)j^vvFgpSrxMoN8J(tt zR$_6n8`CjPNU9zY4a%-u@B>%J%5yz7a5ORFx@&pwUUQ4>p1x(mvZi$2#Pa=MB)KkINHr!(?fhdr+qqBnEq`3W2^Bg8&1v~W8c#;^9Wg=^M)A&{hJcXR`c`p zP2eE@`jeJc3u-iFJTUi-#CBIqPL`*2r6*%*!k7N|HVDR8G4_6|(Aa+A#Ht~0lJVwJ zm*8;GvpC%nyZ%=F-Rzzs^528*Te9B;>stmoVrnPGc@=!g)LPtKZ+lrONx%2vKr z;+AvS^O56aIk5?0QNA}en^g$~s}}`kf7q3;F>~EhPViaJo9C$ewDVKR(Lm|P>%&#P z7<{Kw*P8WD3e%2vVr%WW?>KtZ)Pmleurt`aVjoJFy~6yQNw3b?sNq`|OP6-fmzv=b zm#PnA#=d$hE*>i)34R~bF2CINb>-b^jOWS%m)(av*4%i61|Qy=FVby~Lrga-*zP>_ z6mGApO#0}i8=q9=ft5@rPcM{~Xba;Xgf+x!Zj_fis>L zomG(G$-mItIn0Tszv#y9Ej4{ijkNqny7oL)BJkb2EDOfoFQE$a;o>r>qUD0Kqpo73 zG4Y5?Q$qGA;y^q~OXbp95DItZZ7x$DW?rC=*bH$=A5K(TcZ0st++TH_=l@yL6LwT0 zeIUOzjesfl>HKn1rKLSqMvFDST7){bJ0)&DTSJ1>&6<8oGfrq6J1=PY;dO>KzgpjP zd`0z&;nL8Ypd|Gt=r`R@5i*m0jyrR^w_!zj(g!ct`lK zj_Zt$)RoiEEc1Qte8wMPKGcr1%a+M*qtX0K5M+q z6^;5|`nm(&n?0X7JXA?H8Ce@#Z$yh_LK;;y1K>p_9V;La%6HkGxNk_hYwY$Wx6K|) zIvCZjDlD}hZbsA&RX6GCH;TW^3_1vPj5_(G;o5Gnuo@~CmlWCc4Has$Ml96et^3x9!KALC;OKoam;;Ktf+QF~T zx(jH7iVIg}h&00F1M9vO|9FNf2Amj}~>Jns}h_&wO~zc4`S^QO8e zMr(gvJ1^mX*p%Z zC~=GYs;a7xkPwu%d=l}&E|65{U81MAw$k5im-7dxa7ysu83PrGy~wa*!#WyRT6)e% zt%`Wn$wSaM@jmz}K5ws!%U3LjXOa%Y{rLbFU1IDXS7}@5?%sv}s@1m3Tw_25rAjc~UgMVF*CxV~GlzEo{waSwes z@P6Yne6ZUZVxl^zL@^XO>DMfV_N|Dni0Km_n z)Ou)&OV_EeD7tj9J3Gf}^ra$ajt$ghcV?jK{wF{(G$t`JVNYX@FHB0e3j*wxhfP&^Pu`0L5XwzguAfOZ8C{R~Ikqn6(8JN#ZH?uWIX zk`YIMgyere!dQ{~KOYUA2w~!E7#xR+e}Uu-L1J!@(GOf7S>@@nb5b{`)qrzfR~INk z29)A3KI@|pp_GrCF}X|JpkGfWt7ZV6Fp^6*{^Q3DPoEae+)Mr}_>v5jzDCsjIrAIg zEltuxQM0XDH*B_f-2oTb8C`MYh_@I-iXnT=r8x4)zLdSu7I5;s*xp26`AR{&KPI6T zzsK+LrNwDqfo{u>aqN> zuC5NHed@yglM558rUM0BmzK4QZNI@Br+XXdVeknud`F5c!k{7be#1%!!rm@Gwcg=l zW-(^3P}&coy%Lz=a0E`~dC0d>HRF}tR}*HMJEDrLEzu#-!U}Ut*N3Zo_JvjAVPHC~a$ShMZAI%hRN9tl`dFCxQ7ba89=?YQi5y($D{v9S+_D>=;(sv5 z)ZN@^^(bu0=0_fu$%V3EfBx^703Z%{Uh2x$-81~}=-J_xz!Am4%^e~9>e*-F6eSh{ zCiujOWqmKu#>pBh)@F1cyl14QzUD%C`0pk3%kArbt!}NA%*!zx8T)NDkfo7k;O$+F zk~np0|H;Fl7G@3%bBfZlpv-}MIY-Ar6x+Z42ZdN|j7;FTQ~wwct_a20{`+4k53Wz# zYxYFwnRjo!>0!mYmaDE=YrC)^^BE~W(9v?7JCUJw;ljQ!!au=MSWzM4vUfy2OU#dT z$!o^0UG#PM=Cm)e?kKMj@>!Vgkv1Lg7T?uZISMO3i}RMbkCLnDw~8={Z-*o(J;}Ec zk#whzO2}6Eu}%#%0KI|>#(u7MMU+a7uT!S@ltrkwDDUEgiUg%jm8Zz&_EJiDx>0Sy ziRbxd?U|`L2=%hU*CAW0tzmV6$~&Ci%H956te~--!^8y2)?W7ZY#mh=AN@v=FZpy{sZ6BN@! z)STV~#d4_AYY`7_rl|C!ZJ$a(1l^K?<~^P6%sdwN5>Nck_?h=KV9h9dmW{$g1+L>b zqXou>qo~{n)4HqO7_KbMt~K4Cf+GBr5%MYQn;BkZwwx=Bf?gwD(d+BB0K{GU=s`s~ zS{v%VDTz;Z8xFvo?)~lOO;9%6JYD5;Wp)nd(09yLtkzE^%1DWRaB{e+lX1FBq}tD{ z9`);5!|#Vx8(ob@I^$p0N#jNf<#)G22K$UfV%Kf;=CIaVh;uYkc48kM znX2g53|Y-w=LX+&yOS}gy+OD zk+Fw6HauJDzkmOzM1FC>X-s}`%hz><0JiV#+Jc1fGiry#cJLe$l=qZlM3F@SBj07W zwb{7=4DKS;_k)4PhCG~(HsfQPHsji8p*0dT^e*23kijt#JM%M`MCNf*vghwNuk+8% z>~%%h_WF{EFz#=Ft6Otw(8e0?4{DqH<2Y)LjlHCn4|hmTi6Ep}x4 zlx7)=1m#vp{JCP!dRQOG_}!xtGrdkvEBTK<|2a~)8=6q(Cve}_*41??Y5ktEW}UHq zlIi+-werh_9$%%gB;_Y5;`FnEYWf9F96bo@tX#1IH-EP00e4V>KdSAu;OD#1Xj(5BUSi5l>3!(Zo@ zW{Dhd@03^x*3S{X=9Zsfk>`=4ejRL}+H-EDeFz^*^Z>5_Z)od;kTz{JgXIrTPv_z2 z5&+Ei?GX$lPAYJ8z7H+v31jt(++2VTp58_)vvMxEwC$dtP(31X+imC3&X8e0E;%jr z`Z?uGn5rb-tJxD;lt+Hm^r*So5v@WgI<1iWpPdGGeb_gyUf5$h5J@SG`cBW81_yFE z$Rs`Id|a-(Xm84!p$m5`;z(q!0V`COz z7jd31P*|lC%EBJUQmH!z;se>D2efA?sDoJN)F;`fS;Pf(Q`AjUMY}(i;ZbQ+7wNRr zuE(1ToLqK9-LS0IRG>Uku`|oy!_Qzqc+{*1l_YLb%st4HU=0x?^&NSr_wcBY z`bkqa#E)ePI^FD3-YHbz)0uwva$xV3TAlCm`gr=E2dne0`d)*BLkN@&k7=_=XI-g2 zrhvm?GV>$sZsetH6A+6Fm7cYjM3pA0F~(m9L!EqAFz+xzpzYmTuurohuMj5YR}H%^ z_)JgrZz&-QSVN#1zpydBym ziz9`12kvp_9LC@#r}+Q$_uXJAfP2ibSa&CO49BGYmjQm*y zew*DXpQ;W&z2%bjlDXP53=WCSRwadeef>#SQjc)%I$QhN+IH%cj4K6LK15QC z)Y#9x;*(hy;ItPagoN@w}OZxdq2M3iuFH?^9gwjN49&X-{W0=0yLQQn;usJjx-)f;woBo_w)z&>X3-?$17JOnMgsS=HMHA;ZI=V^<3(sOHuI-!D5452|M93mG zRQM=6yXa~>ASE|^uRq&2+}kXN3MUt022g&gG#Ywf6~lWdsKor=8dybD6$f z4>>HE`Dw79g8~*||Eu;v496jsWQ<~j z@JV@vnwaX#kG|R4*+KeNM$v_<`}^A2)c8@Nn!liF$b3R%*fkd#5smi=2)nVwt-OJu zeBYXX>(;`?Mn+33T~&|~Ikia+Y1xs&m1PN%y^17Of%J){u*`TCrI{T$lM-b#x?W_n71-++&oKTPR`_Wmu zyA`l7Jesa@B_pZk>i&ScKf4IoBZY2uP${9*W|;hCz#_U_60F0DX2s}Jj3Qs5m;{tS zQ8n|(_^!?#j-rJXY@iSBIQf*`hK9RyOr9TrG#4`e!oz{?=&DOZWDrE}AOi_%-p0kn zp|tT=Z{Aepj)VeTbJO;E`{HU3^2#7DLoV*nMhh^x!xc%S_SZVeodcWk|Mc;X8&PMy z8j+BY5F5+sa^mY(fVx0k=Gg`NeYM~)%R<)oFQawQ)<|1Xq?_L=|y diff --git a/context/config-resolution.dot b/context/config-resolution.dot index 249df50..83c06f7 100644 --- a/context/config-resolution.dot +++ b/context/config-resolution.dot @@ -1,19 +1,26 @@ -// ConfigResolver โ€” lazy fallback chain for hook configuration values. +// Config resolution โ€” two resolvers, lazy fallback chains. // -// Each property is resolved on first access and cached. -// Empty strings in config are treated as absent and fall through -// to the next source in the chain (standard or-chain falsy semantics). +// HookConfigResolver (write/upload side) โ€” owns workspace, paths, and the +// `destinations` fan-out map. +// ToolConfigResolver (read/query side) โ€” used by the graph_query and +// blob_read tools; resolves the query endpoint via +// resolve_query_endpoint(), EXPLICIT-READ-CONFIG FIRST, +// then falling back to the first hook destination, then env. +// +// Each value is resolved on first access and cached. Empty strings are treated +// as absent and fall through to the next source (or-chain falsy semantics). // // Render: dot -Tsvg config-resolution.dot -o config-resolution.svg -digraph ConfigResolver { +digraph ConfigResolution { rankdir=TB; fontname="Helvetica"; node [fontname="Helvetica", shape=box, style="rounded,filled", fillcolor="#f0f0f0"]; edge [fontname="Helvetica", fontsize=10]; - // --- Central node --- - resolver [label="ConfigResolver", shape=component, fillcolor="#d4e6f1", style="filled"]; + // --- Central nodes --- + hook_resolver [label="HookConfigResolver\n(hook / write side)", shape=component, fillcolor="#d4e6f1", style="filled"]; + tool_resolver [label="ToolConfigResolver\n(graph_query / blob_read โ€” read side)", shape=component, fillcolor="#d1f2d4", style="filled"]; // --- Input sources --- subgraph cluster_inputs { @@ -22,14 +29,16 @@ digraph ConfigResolver { color="#999999"; hook_config [label="hook config\n(behavior YAML)"]; + tool_config [label="tool config\n(overrides.tool-graph-query.config /\n overrides.tool-blob-read.config)"]; coord_config [label="coordinator.config\n(set by app at session creation)"]; session_cap [label="session.working_dir\ncapability\n(set by foundation bundle.py)"]; env_vars [label="Environment Variables\nAMPLIFIER_CONTEXT_INTELLIGENCE_*\n(expanded in YAML before mount)", shape=note, fillcolor="#fff3cd"]; } env_vars -> hook_config [label="expanded into", style=dashed]; + env_vars -> tool_config [label="expanded into", style=dashed]; - // --- project_slug resolution --- + // --- project_slug resolution (hook) --- subgraph cluster_project_slug { label="project_slug resolution"; style=filled; @@ -46,7 +55,7 @@ digraph ConfigResolver { ps_working_dir -> ps_default [label="empty?"]; } - // --- base_path resolution --- + // --- base_path resolution (hook) --- subgraph cluster_base_path { label="base_path resolution"; style=filled; @@ -61,7 +70,7 @@ digraph ConfigResolver { bp_coord -> bp_default [label="empty?"]; } - // --- workspace resolution --- + // --- workspace resolution (hook) --- subgraph cluster_workspace { label="workspace resolution"; style=filled; @@ -76,19 +85,35 @@ digraph ConfigResolver { ws_config -> ws_slug [label="empty?"]; } - // --- Simple properties (no fallback chain) --- + // --- destinations: the hook's named server map (write / fan-out) --- + subgraph cluster_destinations { + label="destinations (hook write side โ€” fan-out)"; + style=filled; + fillcolor="#ede7f6"; + color="#673ab7"; + + dst_map [label="destinations:\n{ name โ†’ Destination(url, api_key,\n include, exclude) }\nnamed map, declaration order"]; + dst_legacy [label="legacy scalars\ncontext_intelligence_server_url / _api_key\nโ†’ synthesize {\"default\": โ€ฆ}\nONLY when no destinations block\n(both fields required)", shape=note, fillcolor="#fff3cd"]; + dst_fanout [label="fan-out: send to EVERY destination where\ninclude matches AND exclude does not\n(exclude wins; zero / one / several)\nlocal JSONL always written"]; + dst_first [label="first destination\n= next(iter(destinations.values()), None)"]; + + dst_legacy -> dst_map [label="synthesize", style=dashed]; + dst_map -> dst_fanout [label="route"]; + dst_map -> dst_first [label="for queries"]; + } + + // --- Simple hook properties (no coordinator fallback) --- subgraph cluster_simple { - label="Direct config properties\n(no coordinator fallback)"; + label="Direct hook config properties"; style=filled; fillcolor="#f3e5f5"; color="#9c27b0"; - server_url [label="context_intelligence_server_url\nNone if empty"]; log_level [label="log_level\ndefault: INFO"]; exclude [label="exclude_events\ndefault: frozenset()"]; } - // --- Derived paths --- + // --- Derived paths (hook) --- subgraph cluster_derived { label="Derived Paths"; style=filled; @@ -99,16 +124,42 @@ digraph ConfigResolver { blob_root [label="blob_store_root\nbase_path / project_slug /\nsessions"]; } - // --- Edges from resolver --- - resolver -> ps_config [lhead=cluster_project_slug]; - resolver -> bp_config [lhead=cluster_base_path]; - resolver -> ws_coord [lhead=cluster_workspace]; - resolver -> server_url [lhead=cluster_simple]; + // --- Query endpoint resolution (read side, ToolConfigResolver) --- + // resolve_query_endpoint(hook_resolver, tool_resolver): per-field, EXPLICIT-FIRST. + subgraph cluster_query { + label="resolve_query_endpoint() (read side โ€” per field, explicit-first)"; + style=filled; + fillcolor="#e0f2f1"; + color="#009688"; + + q1 [label="1. read_destinations[first]\n.url / .api_key\n(explicit read override;\n absent โ‡’ synthesize default from\n tool's explicit scalars)"]; + q2 [label="2. hook destinations[first]\n.url / .api_key\n(bug-fix bridge: destinations-only\n setups 'just work' for reads)"]; + q3 [label="3. env\nAMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL /\n_API_KEY\n(single canonical last-resort fallback)"]; + q_none [label="else โ†’ None\nโ†’ configuration_error", shape=note, fillcolor="#ffcdd2"]; + + q1 -> q2 [label="empty?"]; + q2 -> q3 [label="empty?"]; + q3 -> q_none [label="empty?"]; + } + + // --- Edges from the hook resolver --- + hook_resolver -> ps_config [lhead=cluster_project_slug]; + hook_resolver -> bp_config [lhead=cluster_base_path]; + hook_resolver -> ws_coord [lhead=cluster_workspace]; + hook_resolver -> dst_map [lhead=cluster_destinations]; + hook_resolver -> log_level [lhead=cluster_simple]; - hook_config -> resolver [label="config dict"]; - coord_config -> resolver [label="coordinator"]; + hook_config -> hook_resolver [label="config dict"]; + coord_config -> hook_resolver [label="coordinator"]; session_cap -> ps_working_dir [label="working_dir", style=dashed]; + // --- Edges from the tool resolver --- + tool_resolver -> q1 [lhead=cluster_query]; + tool_config -> tool_resolver [label="config dict"]; + coord_config -> tool_resolver [label="coordinator"]; + // tier 2 reads the hook's first destination (shared model) + dst_first -> q2 [style=dashed, label="first hook destination", color="#673ab7"]; + // --- Derived path dependencies --- ps_default -> session_dir [style=dashed, label="project_slug", color="#999999"]; bp_default -> session_dir [style=dashed, label="base_path", color="#999999"]; diff --git a/context_intelligence/config.py b/context_intelligence/config.py index df45f03..d0c9a66 100644 --- a/context_intelligence/config.py +++ b/context_intelligence/config.py @@ -16,6 +16,7 @@ import logging import os +import re from pathlib import Path log = logging.getLogger("context_intelligence.config") @@ -29,6 +30,54 @@ SETTINGS_PATH = AMPLIFIER_DIR / "settings.yaml" +# --------------------------------------------------------------------------- +# Shared env-var helpers (used by HookConfigResolver and ToolConfigResolver) +# --------------------------------------------------------------------------- + +#: Environment variable prefix shared by all CI configuration. +#: ``AMPLIFIER_CONTEXT_INTELLIGENCE_WORKSPACE`` โ†’ workspace +#: ``AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL`` โ†’ context_intelligence_server_url +#: etc. +_ENV_PREFIX = "AMPLIFIER_CONTEXT_INTELLIGENCE_" + + +def _env(suffix: str) -> str | None: + """Read ``AMPLIFIER_CONTEXT_INTELLIGENCE_`` from the environment. + + Returns the value as a string if set and non-empty, otherwise ``None``. + """ + value = os.environ.get(_ENV_PREFIX + suffix) + return value if value else None + + +# --------------------------------------------------------------------------- +# Shell-style placeholder expander (used by ToolConfigResolver) +# --------------------------------------------------------------------------- + +_PLACEHOLDER_RE = re.compile(r"\$\{([^}:]+)(?::([^}]*))?\\}") + + +def _expand_env_placeholders(value: str) -> str: + """Expand shell-style ``${VAR}``, ``${VAR:}``, ``${VAR:default}`` placeholders. + + - ``${VAR}`` โ€” replaced with ``os.environ[VAR]`` if set, else ``""``. + - ``${VAR:}`` โ€” same as ``${VAR}`` (empty default when var is unset). + - ``${VAR:default}`` โ€” replaced with ``os.environ[VAR]`` if set, else ``"default"``. + - Non-placeholder strings pass through unchanged. + + Note: ``os.path.expandvars`` does **not** support the ``${VAR:default}`` + colon syntax used by the agent behavior YAML files shipped with this bundle, + hence this small regex-based helper. + """ + + def _replace(m: re.Match[str]) -> str: + var_name = m.group(1) + default = m.group(2) if m.group(2) is not None else "" + return os.environ.get(var_name, default) + + return _PLACEHOLDER_RE.sub(_replace, value) + + # --------------------------------------------------------------------------- # Settings.yaml parser # --------------------------------------------------------------------------- diff --git a/context_intelligence/tool_resolver.py b/context_intelligence/tool_resolver.py new file mode 100644 index 0000000..e3c26f4 --- /dev/null +++ b/context_intelligence/tool_resolver.py @@ -0,0 +1,267 @@ +"""ToolConfigResolver โ€” lazy config resolver for CI tools in analytics-only mode. + +Used by tool-graph-query and tool-blob-read when the hook-context-intelligence +module is NOT mounted. Constructed **eagerly** inside the tool's ``__init__`` +(both tools always create a ``ToolConfigResolver`` at construction time). Its +properties mirror HookConfigResolver for the shared config keys. + +When ``hook-context-intelligence`` IS mounted it registers a +``HookConfigResolver`` as ``context_intelligence.hook_config_resolver``; the +tools then use ``resolve_query_endpoint(hook_resolver, tool_resolver)`` which +prefers the explicit read-config over the hook's upload destinations. + +Resolution priority for every scalar property (mirrors HookConfigResolver for +the shared config keys): + 1. ``config`` dict (mount config / settings.yaml overrides) + 2. ``coordinator.config`` dict (coordinator-level overrides) + 3. ``AMPLIFIER_CONTEXT_INTELLIGENCE_*`` environment variable + 4. ``~/.amplifier/settings.yaml`` (``overrides.hook-context-intelligenceโ€ฆ``) + +workspace resolution differs from HookConfigResolver by design: + HookConfigResolver.workspace falls back to ``project_slug`` which is + auto-derived from session.working_dir (a hook-only capability). + ToolConfigResolver.workspace falls back to the env var then ``"default"`` + because there is no session.working_dir in analytics-only mode. + +See resolve_query_endpoint() for the full three-tier fallback used by the tools. +""" + +from __future__ import annotations + +import logging +from typing import Any, NamedTuple + +from context_intelligence.config import SETTINGS_PATH, _env, _parse_settings_yaml + +log = logging.getLogger(__name__) + + +# --------------------------------------------------------------------------- +# Data model +# --------------------------------------------------------------------------- + + +class ReadEndpoint(NamedTuple): + """A single read-config entry (mirrors Destination shape, minus upload fields). + + url and api_key may be empty strings (โ†’ falsy โ†’ that field falls through + in the per-field resolution chain). + """ + + name: str + url: str + api_key: str + + +# --------------------------------------------------------------------------- +# Resolution helpers (free functions โ€” shared by both tools) +# --------------------------------------------------------------------------- + + +def _first_entry(mapping: Any) -> Any | None: + """First value of an insertion-ordered ``dict``, or None. + + Defensive: returns None when *mapping* is not a non-empty dict (e.g. a test + double, or an unset attribute). Used for BOTH read_destinations and the hook's + destinations so the 'first' rule is identical on both sides. + """ + if not isinstance(mapping, dict) or not mapping: + return None + return next(iter(mapping.values()), None) + + +def _first_destination(hook_resolver: Any | None) -> Any | None: + """First upload Destination on the hook resolver, or None.""" + if hook_resolver is None: + return None + return _first_entry(getattr(hook_resolver, "destinations", None)) + + +def _pick(*candidates: tuple[str | None, str | None]) -> tuple[str | None, str | None]: + """Return (value, source-label) for the first non-empty candidate, else (None, None).""" + for value, source in candidates: + if value: + return value, source + return None, None + + +def resolve_query_endpoint( + hook_resolver: Any | None, + tool_resolver: "ToolConfigResolver", +) -> tuple[str | None, str | None]: + """Resolve (server_url, api_key) for the query path. Per-field independent. + + Explicit-first order (each field, first non-empty wins): + 1. first entry of tool_resolver.read_destinations (.url / .api_key) + 2. first upload destination on the hook resolver (.url / .api_key) + 3. AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL / AMPLIFIER_CONTEXT_INTELLIGENCE_API_KEY + Returns (None, None)-able per field; each is None only if all three miss. + + Emits one DEBUG line naming which tier supplied each field. + """ + read = _first_entry(tool_resolver.read_destinations) + dest = _first_destination(hook_resolver) + + url, url_src = _pick( + ((read.url if read else None), f"read_destinations:{read.name}" if read else None), + ((dest.url if dest else None), f"destination:{dest.name}" if dest else None), + (_env("SERVER_URL"), "env:SERVER_URL"), + ) + api_key, key_src = _pick( + ((read.api_key if read else None), f"read_destinations:{read.name}" if read else None), + ((dest.api_key if dest else None), f"destination:{dest.name}" if dest else None), + (_env("API_KEY"), "env:API_KEY"), + ) + + log.debug( + "CI query endpoint resolved: url<-%s api_key<-%s", + url_src or "none", + key_src or "none", + ) + return (url or None, api_key or None) + + +# --------------------------------------------------------------------------- +# ToolConfigResolver +# --------------------------------------------------------------------------- + + +class ToolConfigResolver: + """Lazy config resolver for CI query tools (graph-query, blob-read). + + Created eagerly at tool construction time alongside ``_hook_resolver = None``. + Provides scalar config properties that mirror HookConfigResolver and a new + ``read_destinations`` mapping property for the explicit read-config model. + """ + + def __init__(self, config: dict[str, Any], coordinator: Any) -> None: + self._config = config + self._coordinator = coordinator + self._workspace: str | None = None + self._read_destinations: dict[str, ReadEndpoint] | None = None + + # ------------------------------------------------------------------ + # Private helpers + # ------------------------------------------------------------------ + + def _coordinator_config_get(self, key: str) -> Any: + """Safely read *key* from coordinator.config. + + Returns ``None`` if the coordinator has no ``.config`` attribute or + if the key is absent from it. Mirrors HookConfigResolver._coordinator_config_get. + """ + coord_config = getattr(self._coordinator, "config", None) + if not isinstance(coord_config, dict): + return None + return coord_config.get(key) + + # ------------------------------------------------------------------ + # Scalar properties (used by legacy synthesis in read_destinations) + # ------------------------------------------------------------------ + + @property + def context_intelligence_server_url(self) -> str | None: + """Server URL: config โ†’ coordinator.config โ†’ env โ†’ settings.yaml. + + Note: the query path (resolve_query_endpoint) does NOT use this property + for env resolution. Env is consulted only at tier 3 via _env("SERVER_URL"). + Kept for PR #27 API parity. + """ + value = ( + self._config.get("context_intelligence_server_url") + or self._coordinator_config_get("context_intelligence_server_url") + or _env("SERVER_URL") + or _parse_settings_yaml(SETTINGS_PATH).get("server_url") + ) + return str(value) if value else None + + @property + def context_intelligence_api_key(self) -> str | None: + """API key: config โ†’ coordinator.config โ†’ env โ†’ settings.yaml. + + Note: the query path (resolve_query_endpoint) does NOT use this property + for env resolution. Env is consulted only at tier 3 via _env("API_KEY"). + Kept for PR #27 API parity. + """ + value = ( + self._config.get("context_intelligence_api_key") + or self._coordinator_config_get("context_intelligence_api_key") + or _env("API_KEY") + or _parse_settings_yaml(SETTINGS_PATH).get("api_key") + ) + return str(value) if value else None + + @property + def workspace(self) -> str: + """Workspace: config โ†’ coordinator.config โ†’ env โ†’ "default". + + Deliberately does NOT fall back to project_slug (which requires + session.working_dir, a hook-only capability). + """ + if self._workspace is None: + raw = ( + self._config.get("workspace") + or self._coordinator_config_get("workspace") + or _env("WORKSPACE") + or "default" + ) + self._workspace = str(raw) + return self._workspace + + # ------------------------------------------------------------------ + # Read-config mapping (the new explicit read-config model) + # ------------------------------------------------------------------ + + @property + def read_destinations(self) -> dict[str, ReadEndpoint]: + """Parsed ``read_destinations`` mapping, or legacy-synthesized ``{"default": ...}``. + + Parsing rules: + - If ``config["read_destinations"]`` key is **present**: parse it + (may be empty dict {}). Each value must be a dict; ``url``/``api_key`` + are ``str(...).strip()``; non-dict entries are skipped. + - If key is **absent**: apply legacy synthesis. If BOTH explicit + ``context_intelligence_server_url`` and ``context_intelligence_api_key`` + are non-empty (from ``config`` dict or coordinator.config **only** โ€” + env and settings.yaml are excluded so env cannot enter tier 1), synthesize + ``{"default": ReadEndpoint(...)}``. Otherwise return ``{}``. + (Mirrors the hook's destinations D10 synthesis.) + + Cached after first access. + """ + if self._read_destinations is not None: + return self._read_destinations + + _sentinel = object() + raw = self._config.get("read_destinations", _sentinel) + key_present = raw is not _sentinel + + if key_present: + result: dict[str, ReadEndpoint] = {} + if isinstance(raw, dict): + for name, spec in raw.items(): + if not isinstance(spec, dict): + continue + url = str(spec.get("url", "") or "").strip() + api_key = str(spec.get("api_key", "") or "").strip() + result[name] = ReadEndpoint(name=name, url=url, api_key=api_key) + self._read_destinations = result + return self._read_destinations + + # Key absent: legacy synthesis from EXPLICIT config only. + # env and settings.yaml are intentionally excluded โ€” env is consulted only + # at tier 3 in resolve_query_endpoint() so it never outranks the hook + # destination (tier 2). + legacy_url = self._config.get( + "context_intelligence_server_url" + ) or self._coordinator_config_get("context_intelligence_server_url") + legacy_key = self._config.get( + "context_intelligence_api_key" + ) or self._coordinator_config_get("context_intelligence_api_key") + if legacy_url and legacy_key: + self._read_destinations = { + "default": ReadEndpoint(name="default", url=legacy_url, api_key=legacy_key) + } + else: + self._read_destinations = {} + return self._read_destinations diff --git a/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/__init__.py b/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/__init__.py index c07e0dc..2345e41 100644 --- a/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/__init__.py +++ b/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/__init__.py @@ -169,10 +169,10 @@ async def mount( """Mount the context-intelligence hook. Always: - - Registers ConfigResolver as ``context_intelligence.config_resolver`` capability + - Registers HookConfigResolver as ``context_intelligence.hook_config_resolver`` capability - LoggingHandler โ€” writes events.jsonl + dispatches to CI server(s) """ - from .config_resolver import ConfigResolver + from .config_resolver import HookConfigResolver from .handlers.logging_handler import LoggingHandler from .skill_fetcher import ( TOOL_SKILLS_DISCOVERY_CAPABILITY, @@ -181,9 +181,9 @@ async def mount( _is_skills_capable, ) - resolver = ConfigResolver(config, coordinator) + resolver = HookConfigResolver(config, coordinator) log.setLevel(resolver.log_level) - coordinator.register_capability("context_intelligence.config_resolver", resolver) + coordinator.register_capability("context_intelligence.hook_config_resolver", resolver) unregister_fns: list[Callable[[], None]] = [] @@ -286,7 +286,7 @@ async def cleanup() -> None: except Exception: pass try: - coordinator.register_capability("context_intelligence.config_resolver", None) + coordinator.register_capability("context_intelligence.hook_config_resolver", None) except Exception: pass try: diff --git a/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/config_resolver.py b/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/config_resolver.py index 80f5be3..18cd124 100644 --- a/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/config_resolver.py +++ b/modules/hook-context-intelligence/amplifier_module_hook_context_intelligence/config_resolver.py @@ -71,7 +71,7 @@ def _slugify_path(path_str: str) -> str: return slug or _DEFAULT_PROJECT_SLUG -class ConfigResolver: +class HookConfigResolver: """Resolve configuration values with lazy fallback chains. Resolution order per property: @@ -453,3 +453,9 @@ def validate_destinations(self) -> dict[str, Destination]: f"overrides.hook-context-intelligence.config.destinations.." ) return dests + + +# --------------------------------------------------------------------------- +# Backward-compat alias โ€” import either name (HookConfigResolver is canonical) +# --------------------------------------------------------------------------- +ConfigResolver = HookConfigResolver diff --git a/modules/hook-context-intelligence/tests/test_config_resolver.py b/modules/hook-context-intelligence/tests/test_config_resolver.py index 13e9ceb..4b2194e 100644 --- a/modules/hook-context-intelligence/tests/test_config_resolver.py +++ b/modules/hook-context-intelligence/tests/test_config_resolver.py @@ -1,11 +1,13 @@ -"""Tests for ConfigResolver resolution chains.""" +"""Tests for HookConfigResolver resolution chains.""" from pathlib import Path from unittest.mock import MagicMock import fnmatch -from amplifier_module_hook_context_intelligence.config_resolver import ConfigResolver +from amplifier_module_hook_context_intelligence.config_resolver import ( + HookConfigResolver as ConfigResolver, +) # noqa: PLC0414 from amplifier_module_hook_context_intelligence.config_resolver import _slugify_path diff --git a/modules/hook-context-intelligence/tests/test_mount_dispatcher.py b/modules/hook-context-intelligence/tests/test_mount_dispatcher.py index af765bf..99c8e02 100644 --- a/modules/hook-context-intelligence/tests/test_mount_dispatcher.py +++ b/modules/hook-context-intelligence/tests/test_mount_dispatcher.py @@ -326,22 +326,24 @@ def test_mount_signature_has_coordinator_and_config(self) -> None: # TestCapabilityRegistration # --------------------------------------------------------------------------- class TestCapabilityRegistration: - """Hook registers ConfigResolver as a coordinator capability.""" + """Hook registers HookConfigResolver as a coordinator capability.""" async def test_config_resolver_capability_registered_on_mount(self) -> None: - """mount() registers the config_resolver capability with a ConfigResolver instance.""" + """mount() registers the hook_config_resolver capability with a HookConfigResolver instance.""" from amplifier_module_hook_context_intelligence import mount - from amplifier_module_hook_context_intelligence.config_resolver import ConfigResolver + from amplifier_module_hook_context_intelligence.config_resolver import HookConfigResolver coordinator = _make_coordinator() await mount(coordinator, config={}) reg_calls = coordinator.register_capability.call_args_list - cap_calls = [c for c in reg_calls if c.args[0] == "context_intelligence.config_resolver"] + cap_calls = [ + c for c in reg_calls if c.args[0] == "context_intelligence.hook_config_resolver" + ] assert len(cap_calls) == 1, ( - "register_capability should be called once with 'context_intelligence.config_resolver'" + "register_capability should be called once with 'context_intelligence.hook_config_resolver'" ) - assert isinstance(cap_calls[0].args[1], ConfigResolver) + assert isinstance(cap_calls[0].args[1], HookConfigResolver) async def test_hook_state_capability_registered_on_mount(self) -> None: """mount() registers the _hook_state capability as a dict with required keys.""" @@ -375,5 +377,5 @@ async def test_cleanup_vacates_both_capabilities(self) -> None: null_calls: dict[str, Any] = { c.args[0]: c.args[1] for c in coordinator.register_capability.call_args_list } - assert null_calls["context_intelligence.config_resolver"] is None + assert null_calls["context_intelligence.hook_config_resolver"] is None assert null_calls["context_intelligence._hook_state"] is None diff --git a/modules/hook-context-intelligence/uv.lock b/modules/hook-context-intelligence/uv.lock index b81a47e..d76de56 100644 --- a/modules/hook-context-intelligence/uv.lock +++ b/modules/hook-context-intelligence/uv.lock @@ -5,12 +5,12 @@ requires-python = ">=3.11" [[package]] name = "amplifier-bundle-context-intelligence" version = "0.1.1" -source = { git = "https://github.com/microsoft/amplifier-bundle-context-intelligence?rev=v0.1.1#b722074f17a354816ebf5adcf0881b1562a2cbc5" } +source = { git = "https://github.com/microsoft/amplifier-bundle-context-intelligence?rev=main#2e47dc7c331b60210814f711129a10fdffd76ee4" } [[package]] name = "amplifier-core" -version = "1.4.1" -source = { git = "https://github.com/microsoft/amplifier-core?rev=v1.4.1#12f3d383de723993c9d15cf61d8f0f77e5e874d4" } +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "pydantic" }, @@ -18,6 +18,14 @@ dependencies = [ { name = "tomli" }, { name = "typing-extensions" }, ] +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/90/d520390cd91aae3d02db53653f828046089c79203dbb142e9bda346fa1d6/amplifier_core-1.6.0-cp311-abi3-macosx_10_12_x86_64.whl", hash = "sha256:d35130e4262cf0db2d6c5f7e65e244a9ef2c7397bfe2a9853bc9b0d9fd05be64", size = 8113151, upload-time = "2026-05-18T16:13:46.825Z" }, + { url = "https://files.pythonhosted.org/packages/94/75/3ab3126ba5a6f2fc6051a4d08e42364899e4c9ac4daa9d0a60947bf8acd1/amplifier_core-1.6.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:387a2c58fcf4caefdb45c52ec228307bc225e73606897f242154782bc3e123da", size = 7268223, upload-time = "2026-05-18T16:13:48.749Z" }, + { url = "https://files.pythonhosted.org/packages/21/22/5a36160b3487170bcba0cbc61535101ff624e8314ed38fd35e561cb711a1/amplifier_core-1.6.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8344fccdedd725a51c018de17867cdf1c35abb571dabc0bbccdb5c1242324a47", size = 7532259, upload-time = "2026-05-18T16:13:50.614Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d7/3874c2308523209411367cf3b8b690e14e869f5f6bfb64cb1b1971e06a96/amplifier_core-1.6.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a8e0103242a2e2a975c880b1de0e5a02501e0421c1e5386dadae3f111e1d2b5", size = 8507642, upload-time = "2026-05-18T16:13:52.977Z" }, + { url = "https://files.pythonhosted.org/packages/86/59/3646a89537b4556274183519f6db9c354fb3d183f52ef4a2179af12dd386/amplifier_core-1.6.0-cp311-abi3-win_amd64.whl", hash = "sha256:5113aa2d88038776eb257af9e7d9de7af13b3cd9097d2ac67aef5730fa0678e3", size = 8910313, upload-time = "2026-05-18T16:13:55.249Z" }, + { url = "https://files.pythonhosted.org/packages/9f/9e/58b141115e5eea65703f0b01459eefed36b561e9642ba96d48542345cd8f/amplifier_core-1.6.0-cp311-abi3-win_arm64.whl", hash = "sha256:e1b2731dc09d1cbc668b411007e7f9a2c7edbd75b2525407cae1e6b4a4de0b83", size = 7661416, upload-time = "2026-05-18T16:13:57.513Z" }, +] [[package]] name = "amplifier-module-hook-context-intelligence" @@ -42,7 +50,7 @@ dev = [ [package.metadata] requires-dist = [ - { name = "amplifier-bundle-context-intelligence", git = "https://github.com/microsoft/amplifier-bundle-context-intelligence?rev=v0.1.1" }, + { name = "amplifier-bundle-context-intelligence", git = "https://github.com/microsoft/amplifier-bundle-context-intelligence?rev=main" }, { name = "httpx", specifier = ">=0.28.1" }, { name = "idna", specifier = ">=3.15" }, { name = "pathspec", specifier = ">=0.12,<2" }, @@ -50,7 +58,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ - { name = "amplifier-core", git = "https://github.com/microsoft/amplifier-core?rev=v1.4.1" }, + { name = "amplifier-core", specifier = ">=1.6.0" }, { name = "pyright", specifier = ">=1.1" }, { name = "pytest", specifier = ">=9.0.3" }, { name = "pytest-asyncio", specifier = ">=0.24" }, diff --git a/modules/tool-blob-read/amplifier_module_tool_blob_read/__init__.py b/modules/tool-blob-read/amplifier_module_tool_blob_read/__init__.py index 9e15876..5266003 100644 --- a/modules/tool-blob-read/amplifier_module_tool_blob_read/__init__.py +++ b/modules/tool-blob-read/amplifier_module_tool_blob_read/__init__.py @@ -15,6 +15,6 @@ async def mount(coordinator: Any, config: Any) -> dict[str, Any]: # noqa: ARG001 from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool - tool = BlobReadTool(coordinator) + tool = BlobReadTool(coordinator, config) await coordinator.mount("tools", tool, name=tool.name) return {"tool": tool.name, "status": "mounted"} diff --git a/modules/tool-blob-read/amplifier_module_tool_blob_read/blob_read_tool.py b/modules/tool-blob-read/amplifier_module_tool_blob_read/blob_read_tool.py index d6fb9d1..974b99c 100644 --- a/modules/tool-blob-read/amplifier_module_tool_blob_read/blob_read_tool.py +++ b/modules/tool-blob-read/amplifier_module_tool_blob_read/blob_read_tool.py @@ -1,4 +1,14 @@ -"""BlobReadTool โ€” fetches blob content from the context-intelligence server.""" +"""BlobReadTool โ€” fetches blob content from the context-intelligence server. + +Configuration is resolved via the three-tier fallback chain in +``resolve_query_endpoint`` (same as GraphQueryTool โ€” parity guaranteed by the +shared helper): + + 1. Explicit read-config (``read_destinations:`` in mount config, if set). + 2. Upload destinations from ``context_intelligence.hook_config_resolver`` + capability (fixes the destinations-only config bug). + 3. ``AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL`` env var (canonical last-resort). +""" from __future__ import annotations @@ -9,6 +19,7 @@ from amplifier_core import ToolResult from context_intelligence.client import AsyncCIClient +from context_intelligence.tool_resolver import ToolConfigResolver, resolve_query_endpoint _URI_SCHEME = "ci-blob://" _BLOB_DIR = Path("/tmp/ci-blobs") @@ -22,9 +33,11 @@ def _sanitize_path_component(s: str) -> str: class BlobReadTool: """Tool that fetches a ci-blob:// URI from the server and writes it to disk.""" - def __init__(self, coordinator: Any) -> None: + def __init__(self, coordinator: Any, config: dict[str, Any] | None = None) -> None: self._coordinator = coordinator - self._resolver: Any = None + self._config = config or {} + self._hook_resolver: Any | None = None + self._tool_resolver = ToolConfigResolver(self._config, coordinator) @property def name(self) -> str: @@ -51,22 +64,14 @@ def input_schema(self) -> dict[str, Any]: } async def execute(self, input: dict[str, Any]) -> ToolResult: # noqa: A002 - # (1) Lazy capability resolution - if self._resolver is None: - self._resolver = self._coordinator.get_capability( - "context_intelligence.config_resolver" - ) - if self._resolver is None: - return ToolResult( - success=False, - error={ - "message": "context-intelligence hook not configured", - "type": "configuration_error", - }, + # (1) Lazy hook resolver resolution + if self._hook_resolver is None: + self._hook_resolver = self._coordinator.get_capability( + "context_intelligence.hook_config_resolver" ) - # (2) Get server_url from resolver - server_url: str | None = self._resolver.context_intelligence_server_url + # (2) Resolve server_url + api_key via three-tier chain + server_url, api_key = resolve_query_endpoint(self._hook_resolver, self._tool_resolver) if not server_url: return ToolResult( success=False, @@ -105,7 +110,6 @@ async def execute(self, input: dict[str, Any]) -> ToolResult: # noqa: A002 safe_key = _sanitize_path_component(key) # (5) Construct AsyncCIClient - api_key: str | None = self._resolver.context_intelligence_api_key async_client = AsyncCIClient(server_url=server_url, api_key=api_key or "") # (6) Fetch blob using original unsanitized values for the server request diff --git a/modules/tool-blob-read/tests/test_blob_read_tool.py b/modules/tool-blob-read/tests/test_blob_read_tool.py index 856ecd7..29b8b66 100644 --- a/modules/tool-blob-read/tests/test_blob_read_tool.py +++ b/modules/tool-blob-read/tests/test_blob_read_tool.py @@ -7,9 +7,11 @@ from __future__ import annotations import json +import os import pathlib import shutil from contextlib import contextmanager +from types import SimpleNamespace from typing import Any, Generator from unittest.mock import AsyncMock, MagicMock, patch @@ -25,6 +27,7 @@ def _make_coordinator(resolver: Any) -> MagicMock: """Return a MagicMock coordinator whose get_capability returns *resolver*.""" coordinator = MagicMock() + coordinator.config = {} coordinator.get_capability.return_value = resolver return coordinator @@ -33,10 +36,18 @@ def _make_resolver(server_url: str | None, api_key: str | None = None) -> MagicM """Return a MagicMock resolver with context_intelligence_server_url set. api_key defaults to None so tests that don't exercise auth get a clean mock. + Also sets destinations so _first_destination() can iterate it safely. """ resolver = MagicMock() resolver.context_intelligence_server_url = server_url resolver.context_intelligence_api_key = api_key + # destinations must be a real dict so _first_destination() can iterate it safely + if server_url: + resolver.destinations = { + "default": SimpleNamespace(name="default", url=server_url, api_key=api_key or ""), + } + else: + resolver.destinations = {} return resolver @@ -141,7 +152,10 @@ async def test_capability_not_found_returns_configuration_error(self) -> None: # get_capability returns None โ†’ capability not registered tool = BlobReadTool(_make_coordinator(None)) - result = await tool.execute({"uri": "ci-blob://session/key"}) + # Clear CI env vars so tier-3 fallback does not accidentally succeed + clean = {k: "" for k in os.environ if k.startswith("AMPLIFIER_CONTEXT_INTELLIGENCE_")} + with patch.dict(os.environ, clean): + result = await tool.execute({"uri": "ci-blob://session/key"}) assert result.success is False assert result.error is not None @@ -153,7 +167,10 @@ async def test_server_url_none_returns_configuration_error_with_url(self) -> Non resolver = _make_resolver(None) tool = BlobReadTool(_make_coordinator(resolver)) - result = await tool.execute({"uri": "ci-blob://session/key"}) + # Clear CI env vars so tier-3 fallback does not accidentally succeed + clean = {k: "" for k in os.environ if k.startswith("AMPLIFIER_CONTEXT_INTELLIGENCE_")} + with patch.dict(os.environ, clean): + result = await tool.execute({"uri": "ci-blob://session/key"}) assert result.success is False assert result.error is not None @@ -165,7 +182,10 @@ async def test_server_url_empty_returns_configuration_error(self) -> None: resolver = _make_resolver("") tool = BlobReadTool(_make_coordinator(resolver)) - result = await tool.execute({"uri": "ci-blob://session/key"}) + # Clear CI env vars so tier-3 fallback does not accidentally succeed + clean = {k: "" for k in os.environ if k.startswith("AMPLIFIER_CONTEXT_INTELLIGENCE_")} + with patch.dict(os.environ, clean): + result = await tool.execute({"uri": "ci-blob://session/key"}) assert result.success is False assert result.error is not None @@ -405,3 +425,152 @@ async def test_none_api_key_passes_empty_string(self) -> None: await tool.execute({"uri": "ci-blob://my-session/my-key"}) mock_cls.assert_called_once_with(server_url="http://localhost:8080", api_key="") + + +# --------------------------------------------------------------------------- +# Helpers for config-fallback tests (ยง7 case #8: blob-read parity) +# --------------------------------------------------------------------------- + + +def _make_hook_resolver_br(destinations: dict) -> MagicMock: + """Hook resolver mock with specific destinations dict for blob-read tests.""" + resolver = MagicMock() + resolver.destinations = destinations + return resolver + + +def _make_dest_br(url: str, api_key: str) -> SimpleNamespace: + """Quick Destination-like SimpleNamespace for blob-read test doubles.""" + return SimpleNamespace(name="default", url=url, api_key=api_key) + + +# --------------------------------------------------------------------------- +# TestBlobReadConfigFallback โ€” ยง7 case #8 parity tests +# --------------------------------------------------------------------------- + + +class TestBlobReadConfigFallback: + """Case #8: blob_read uses the same resolve_query_endpoint as graph_query (parity). + + Re-runs cases #1, #2, #5, #6 against BlobReadTool to prove identical resolution. + """ + + # Case #8/#1 โ€” read_destinations wins over destination + async def test_read_config_wins_over_destination(self) -> None: + """BlobReadTool case #8/#1: explicit read_destinations wins over hook destinations.""" + from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + + hook_resolver = _make_hook_resolver_br( + destinations={"default": _make_dest_br("http://upload.example.com", "upload-key")} + ) + coordinator = _make_coordinator(hook_resolver) + config = { + "read_destinations": { + "default": {"url": "http://read.example.com", "api_key": "read-key"}, + } + } + tool = BlobReadTool(coordinator, config) + + with _patch_async_client(fetch_blob_return={"ok": True}) as (mock_cls, _): + result = await tool.execute({"uri": "ci-blob://my-session/my-key"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + assert call_kwargs["server_url"] == "http://read.example.com" + assert call_kwargs["api_key"] == "read-key" + + # Case #8/#2 โ€” destinations-only falls through to tier 2 + async def test_destinations_only_falls_through_to_tier2(self) -> None: + """BlobReadTool case #8/#2: no read_destinations โ†’ uses hook destination.""" + from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + + hook_resolver = _make_hook_resolver_br( + destinations={"default": _make_dest_br("http://dest.example.com", "dest-key")} + ) + coordinator = _make_coordinator(hook_resolver) + tool = BlobReadTool(coordinator, config={}) + + with _patch_async_client(fetch_blob_return={"ok": True}) as (mock_cls, _): + result = await tool.execute({"uri": "ci-blob://my-session/my-key"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + assert call_kwargs["server_url"] == "http://dest.example.com" + assert call_kwargs["api_key"] == "dest-key" + + # Case #8/#5 โ€” env hit + async def test_env_hit(self) -> None: + """BlobReadTool case #8/#5: canonical env vars work as tier-3 fallback.""" + from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + + hook_resolver = _make_hook_resolver_br(destinations={}) + coordinator = _make_coordinator(hook_resolver) + tool = BlobReadTool(coordinator, config={}) + + env_patch = { + "AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL": "http://env.example.com", + "AMPLIFIER_CONTEXT_INTELLIGENCE_API_KEY": "env-key", + } + with ( + patch.dict(os.environ, env_patch), + _patch_async_client(fetch_blob_return={"ok": True}) as (mock_cls, _), + ): + result = await tool.execute({"uri": "ci-blob://my-session/my-key"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + assert call_kwargs["server_url"] == "http://env.example.com" + assert call_kwargs["api_key"] == "env-key" + + # Regression: env is below hook destination (tier 2 beats tier 3) + async def test_env_does_not_override_hook_destination(self) -> None: + """BlobReadTool regression: canonical env + hook destination โ†’ destination wins.""" + from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + + hook_resolver = _make_hook_resolver_br( + destinations={"default": _make_dest_br("http://dest.example.com", "dest-key")} + ) + coordinator = _make_coordinator(hook_resolver) + tool = BlobReadTool(coordinator, config={}) + + # Canonical env set โ€” must NOT override the hook destination + env_patch = { + "AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL": "http://env-override.example.com", + "AMPLIFIER_CONTEXT_INTELLIGENCE_API_KEY": "env-override-key", + } + with ( + patch.dict(os.environ, env_patch), + _patch_async_client(fetch_blob_return={"ok": True}) as (mock_cls, _), + ): + result = await tool.execute({"uri": "ci-blob://my-session/my-key"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + # Hook destination (tier 2) wins over env (tier 3) + assert call_kwargs["server_url"] == "http://dest.example.com" + assert call_kwargs["api_key"] == "dest-key" + + # Case #8/#6 โ€” all miss โ†’ configuration_error + async def test_all_miss_returns_configuration_error(self) -> None: + """BlobReadTool case #8/#6: no config, no destinations, no env โ†’ configuration_error.""" + from amplifier_module_tool_blob_read.blob_read_tool import BlobReadTool + + hook_resolver = _make_hook_resolver_br(destinations={}) + coordinator = _make_coordinator(hook_resolver) + tool = BlobReadTool(coordinator, config={}) + + # Exclude ALL CI env vars (including canonical SERVER_URL / API_KEY) + clean_env = { + k: v + for k, v in os.environ.items() + if not k.startswith("AMPLIFIER_CONTEXT_INTELLIGENCE_") + } + with ( + patch.dict(os.environ, clean_env, clear=True), + _patch_async_client(fetch_blob_return={"ok": True}) as (mock_cls, _), + ): + result = await tool.execute({"uri": "ci-blob://my-session/my-key"}) + + assert result.success is False + assert result.error is not None + assert result.error["type"] == "configuration_error" diff --git a/modules/tool-blob-read/uv.lock b/modules/tool-blob-read/uv.lock index b385fab..4e71a98 100644 --- a/modules/tool-blob-read/uv.lock +++ b/modules/tool-blob-read/uv.lock @@ -5,25 +5,12 @@ requires-python = ">=3.11" [[package]] name = "amplifier-bundle-context-intelligence" version = "0.1.1" -source = { editable = "../../" } - -[package.metadata] - -[package.metadata.requires-dev] -dev = [ - { name = "httpx", specifier = ">=0.25" }, - { name = "idna", specifier = ">=3.15" }, - { name = "pyright", specifier = ">=1.1" }, - { name = "pytest", specifier = ">=9.0.3" }, - { name = "pytest-asyncio", specifier = ">=0.24" }, - { name = "pyyaml", specifier = ">=6.0" }, - { name = "ruff", specifier = ">=0.4" }, -] +source = { git = "https://github.com/microsoft/amplifier-bundle-context-intelligence?rev=main#2e47dc7c331b60210814f711129a10fdffd76ee4" } [[package]] name = "amplifier-core" -version = "1.2.5" -source = { git = "https://github.com/microsoft/amplifier-core?branch=main#308b2455728378be896266cf620c00da2a408b65" } +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "pydantic" }, @@ -31,6 +18,14 @@ dependencies = [ { name = "tomli" }, { name = "typing-extensions" }, ] +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/90/d520390cd91aae3d02db53653f828046089c79203dbb142e9bda346fa1d6/amplifier_core-1.6.0-cp311-abi3-macosx_10_12_x86_64.whl", hash = "sha256:d35130e4262cf0db2d6c5f7e65e244a9ef2c7397bfe2a9853bc9b0d9fd05be64", size = 8113151, upload-time = "2026-05-18T16:13:46.825Z" }, + { url = "https://files.pythonhosted.org/packages/94/75/3ab3126ba5a6f2fc6051a4d08e42364899e4c9ac4daa9d0a60947bf8acd1/amplifier_core-1.6.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:387a2c58fcf4caefdb45c52ec228307bc225e73606897f242154782bc3e123da", size = 7268223, upload-time = "2026-05-18T16:13:48.749Z" }, + { url = "https://files.pythonhosted.org/packages/21/22/5a36160b3487170bcba0cbc61535101ff624e8314ed38fd35e561cb711a1/amplifier_core-1.6.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8344fccdedd725a51c018de17867cdf1c35abb571dabc0bbccdb5c1242324a47", size = 7532259, upload-time = "2026-05-18T16:13:50.614Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d7/3874c2308523209411367cf3b8b690e14e869f5f6bfb64cb1b1971e06a96/amplifier_core-1.6.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a8e0103242a2e2a975c880b1de0e5a02501e0421c1e5386dadae3f111e1d2b5", size = 8507642, upload-time = "2026-05-18T16:13:52.977Z" }, + { url = "https://files.pythonhosted.org/packages/86/59/3646a89537b4556274183519f6db9c354fb3d183f52ef4a2179af12dd386/amplifier_core-1.6.0-cp311-abi3-win_amd64.whl", hash = "sha256:5113aa2d88038776eb257af9e7d9de7af13b3cd9097d2ac67aef5730fa0678e3", size = 8910313, upload-time = "2026-05-18T16:13:55.249Z" }, + { url = "https://files.pythonhosted.org/packages/9f/9e/58b141115e5eea65703f0b01459eefed36b561e9642ba96d48542345cd8f/amplifier_core-1.6.0-cp311-abi3-win_arm64.whl", hash = "sha256:e1b2731dc09d1cbc668b411007e7f9a2c7edbd75b2525407cae1e6b4a4de0b83", size = 7661416, upload-time = "2026-05-18T16:13:57.513Z" }, +] [[package]] name = "amplifier-module-tool-blob-read" @@ -53,14 +48,14 @@ dev = [ [package.metadata] requires-dist = [ - { name = "amplifier-bundle-context-intelligence", editable = "../../" }, + { name = "amplifier-bundle-context-intelligence", git = "https://github.com/microsoft/amplifier-bundle-context-intelligence?rev=main" }, { name = "httpx", specifier = ">=0.28.1" }, { name = "idna", specifier = ">=3.15" }, ] [package.metadata.requires-dev] dev = [ - { name = "amplifier-core", git = "https://github.com/microsoft/amplifier-core?branch=main" }, + { name = "amplifier-core", specifier = ">=1.6.0" }, { name = "pyright", specifier = ">=1.1" }, { name = "pytest", specifier = ">=9.0.3" }, { name = "pytest-asyncio", specifier = ">=0.24" }, diff --git a/modules/tool-graph-query/amplifier_module_tool_graph_query/__init__.py b/modules/tool-graph-query/amplifier_module_tool_graph_query/__init__.py index baa50c3..1cca2c5 100644 --- a/modules/tool-graph-query/amplifier_module_tool_graph_query/__init__.py +++ b/modules/tool-graph-query/amplifier_module_tool_graph_query/__init__.py @@ -21,6 +21,6 @@ async def mount(coordinator: Any, config: dict[str, Any]) -> dict[str, Any]: # """ from .graph_query_tool import GraphQueryTool - tool = GraphQueryTool(coordinator=coordinator) + tool = GraphQueryTool(coordinator=coordinator, config=config) await coordinator.mount("tools", tool, name=tool.name) return {"tool": tool.name, "status": "mounted"} diff --git a/modules/tool-graph-query/amplifier_module_tool_graph_query/graph_query_tool.py b/modules/tool-graph-query/amplifier_module_tool_graph_query/graph_query_tool.py index 120f758..8eb1579 100644 --- a/modules/tool-graph-query/amplifier_module_tool_graph_query/graph_query_tool.py +++ b/modules/tool-graph-query/amplifier_module_tool_graph_query/graph_query_tool.py @@ -1,8 +1,15 @@ """GraphQueryTool โ€” agent-facing tool for executing Cypher queries. -Implements the Amplifier Tool protocol. Resolves configuration lazily -via the ``context_intelligence.config_resolver`` coordinator capability -registered by the hook-context-intelligence module. +Implements the Amplifier Tool protocol. Configuration is resolved via the +three-tier fallback chain in ``resolve_query_endpoint``: + + 1. Explicit read-config (``read_destinations:`` in mount config, if set). + 2. Upload destinations from ``context_intelligence.hook_config_resolver`` + capability (fixes the destinations-only config bug). + 3. ``AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL`` env var (canonical last-resort). + +The hook resolver is fetched lazily at first ``execute()`` call so that late +mount order is handled correctly (tools mount before hooks). """ from __future__ import annotations @@ -10,6 +17,7 @@ from typing import Any from context_intelligence.client import AsyncCIClient +from context_intelligence.tool_resolver import ToolConfigResolver, resolve_query_endpoint from amplifier_core.models import ToolResult @@ -18,13 +26,15 @@ class GraphQueryTool: """Execute Cypher queries against the context-intelligence server. Implements the Amplifier Tool protocol (name, description, input_schema, - execute). Configuration is resolved lazily at execute() time via the - coordinator's ``context_intelligence.config_resolver`` capability. + execute). Configuration is resolved via resolve_query_endpoint() at + execute() time, consulting the hook's upload destinations as a fallback. """ - def __init__(self, coordinator: Any) -> None: + def __init__(self, coordinator: Any, config: dict[str, Any] | None = None) -> None: self._coordinator = coordinator - self._resolver: Any | None = None + self._config = config or {} + self._hook_resolver: Any | None = None + self._tool_resolver = ToolConfigResolver(self._config, coordinator) @property def name(self) -> str: @@ -74,22 +84,27 @@ def input_schema(self) -> dict[str, Any]: "required": ["query"], } - async def execute(self, input: dict[str, Any]) -> ToolResult: # noqa: A002 - if self._resolver is None: - self._resolver = self._coordinator.get_capability( - "context_intelligence.config_resolver" - ) + def _resolve_server_config(self, coordinator: Any) -> tuple[str | None, str | None, str]: + """Resolve (server_url, api_key, workspace) using the three-tier fallback chain. - if self._resolver is None: - return ToolResult( - success=False, - error={ - "message": "context-intelligence hook not configured", - "type": "configuration_error", - }, + Late-mount upgrade: retries hook capability lookup on every call while + _hook_resolver is None (hook may mount after the tool). + """ + if self._hook_resolver is None: + self._hook_resolver = coordinator.get_capability( + "context_intelligence.hook_config_resolver" ) + url, api_key = resolve_query_endpoint(self._hook_resolver, self._tool_resolver) + workspace = ( + self._hook_resolver.workspace + if self._hook_resolver is not None + else self._tool_resolver.workspace + ) + return url, api_key, workspace + + async def execute(self, input: dict[str, Any]) -> ToolResult: # noqa: A002 + server_url, api_key, workspace = self._resolve_server_config(self._coordinator) - server_url = self._resolver.context_intelligence_server_url if not server_url: return ToolResult( success=False, @@ -99,7 +114,6 @@ async def execute(self, input: dict[str, Any]) -> ToolResult: # noqa: A002 }, ) - workspace = self._resolver.workspace query: str = input["query"] ws_override = input.get("workspace") effective_workspace = ws_override if ws_override is not None else workspace @@ -118,7 +132,6 @@ async def execute(self, input: dict[str, Any]) -> ToolResult: # noqa: A002 else: params = raw_params - api_key = self._resolver.context_intelligence_api_key async_client = AsyncCIClient(server_url=server_url, api_key=api_key or "") result = await async_client.cypher(query, effective_workspace, params=params) return ToolResult(success=True, output=result) diff --git a/modules/tool-graph-query/tests/test_graph_query_tool.py b/modules/tool-graph-query/tests/test_graph_query_tool.py index ad62614..c7908b2 100644 --- a/modules/tool-graph-query/tests/test_graph_query_tool.py +++ b/modules/tool-graph-query/tests/test_graph_query_tool.py @@ -2,6 +2,8 @@ from __future__ import annotations +import os +from types import SimpleNamespace from typing import Any from unittest.mock import AsyncMock, MagicMock, patch @@ -13,6 +15,7 @@ def _make_coordinator(resolver: Any = None) -> MagicMock: coordinator = MagicMock() + coordinator.config = {} coordinator.get_capability = MagicMock(return_value=resolver) return coordinator @@ -26,6 +29,13 @@ def _make_resolver( resolver.context_intelligence_server_url = server_url resolver.workspace = workspace resolver.context_intelligence_api_key = api_key + # destinations must be a real dict so _first_destination() can iterate it safely + if server_url: + resolver.destinations = { + "default": SimpleNamespace(name="default", url=server_url, api_key=api_key or ""), + } + else: + resolver.destinations = {} return resolver @@ -115,7 +125,10 @@ async def test_capability_not_found_returns_configuration_error(self) -> None: coordinator = _make_coordinator(resolver=None) tool = GraphQueryTool(coordinator=coordinator) - result = await tool.execute({"query": "MATCH (n) RETURN n"}) + # Clear all CI env vars so tier-3 fallback does not accidentally succeed + clean = {k: "" for k in os.environ if k.startswith("AMPLIFIER_CONTEXT_INTELLIGENCE_")} + with patch.dict(os.environ, clean): + result = await tool.execute({"query": "MATCH (n) RETURN n"}) assert result.success is False assert result.error is not None @@ -127,7 +140,10 @@ async def test_server_url_none_returns_configuration_error(self) -> None: resolver = _make_resolver(server_url=None) coordinator = _make_coordinator(resolver=resolver) tool = GraphQueryTool(coordinator=coordinator) - result = await tool.execute({"query": "MATCH (n) RETURN n"}) + # Clear all CI env vars so tier-3 fallback does not accidentally succeed + clean = {k: "" for k in os.environ if k.startswith("AMPLIFIER_CONTEXT_INTELLIGENCE_")} + with patch.dict(os.environ, clean): + result = await tool.execute({"query": "MATCH (n) RETURN n"}) assert result.success is False assert result.error is not None @@ -146,7 +162,9 @@ async def test_resolver_cached_after_first_lookup(self) -> None: await tool.execute({"query": "MATCH (n) RETURN n LIMIT 2"}) # get_capability should only be called once (on first execute) - coordinator.get_capability.assert_called_once_with("context_intelligence.config_resolver") + coordinator.get_capability.assert_called_once_with( + "context_intelligence.hook_config_resolver" + ) async def test_configured_resolver_succeeds(self) -> None: from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool @@ -376,3 +394,341 @@ async def test_non_dict_params_returns_validation_error(self) -> None: assert result.success is False assert result.error is not None assert result.error["type"] == "validation_error" + + +# --------------------------------------------------------------------------- +# Helpers for config-fallback tests (ยง7 matrix) +# --------------------------------------------------------------------------- + + +def _make_hook_resolver(destinations: dict) -> MagicMock: + """Hook resolver mock with specific destinations dict.""" + resolver = MagicMock() + resolver.workspace = "test-workspace" + resolver.destinations = destinations + return resolver + + +def _make_dest(url: str, api_key: str) -> SimpleNamespace: + """Quick Destination-like SimpleNamespace for test doubles.""" + name = "default" + return SimpleNamespace(name=name, url=url, api_key=api_key) + + +# --------------------------------------------------------------------------- +# TestConfigFallback โ€” ยง7 test matrix cases #1โ€“#7/#9โ€“#10 +# --------------------------------------------------------------------------- + + +class TestConfigFallback: + """Config-resolution three-tier fallback (spec ยง7). + + Tests the explicit-read-config-first, then upload-destination, then env + precedence order โ€” the core bug fix and its coherent read-config model. + """ + + # --- Case #1 / #4: read_destinations wins over hook destination --- + + async def test_case1_read_config_wins_over_destination(self) -> None: + """Case #1: explicit read_destinations wins over upload destination (tier 1 > tier 2).""" + from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + + dest_resolver = _make_hook_resolver( + destinations={"default": _make_dest("http://upload.example.com", "upload-key")} + ) + coordinator = _make_coordinator(resolver=dest_resolver) + config = { + "read_destinations": { + "default": {"url": "http://read.example.com", "api_key": "read-key"}, + } + } + tool = GraphQueryTool(coordinator=coordinator, config=config) + + _, mock_cls = _make_mock_async_ci_client() + with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + result = await tool.execute({"query": "MATCH (n) RETURN n"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + assert call_kwargs["server_url"] == "http://read.example.com" + assert call_kwargs["api_key"] == "read-key" + + # --- Case #2: CORE BUG FIX โ€” destinations-only config succeeds --- + + async def test_case2_destinations_only_falls_through_to_tier2(self) -> None: + """Case #2: no read_destinations + no legacy scalar โ†’ falls through to hook destinations.""" + from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + + dest_resolver = _make_hook_resolver( + destinations={"default": _make_dest("http://dest.example.com", "dest-key")} + ) + coordinator = _make_coordinator(resolver=dest_resolver) + # Tool config is empty โ€” no read_destinations, no legacy scalars + tool = GraphQueryTool(coordinator=coordinator, config={}) + + _, mock_cls = _make_mock_async_ci_client() + with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + result = await tool.execute({"query": "MATCH (n) RETURN n"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + assert call_kwargs["server_url"] == "http://dest.example.com" + assert call_kwargs["api_key"] == "dest-key" + + # --- Case #3: per-field independence --- + + async def test_case3_read_config_url_empty_falls_to_destination_for_url(self) -> None: + """Case #3: read_destinations url="" โ†’ url falls to destination; api_key stays at tier 1.""" + from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + + dest_resolver = _make_hook_resolver( + destinations={"default": _make_dest("http://dest.example.com", "dest-key")} + ) + coordinator = _make_coordinator(resolver=dest_resolver) + config = { + "read_destinations": { + "default": {"url": "", "api_key": "read-key"}, # url is empty + } + } + tool = GraphQueryTool(coordinator=coordinator, config=config) + + _, mock_cls = _make_mock_async_ci_client() + with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + result = await tool.execute({"query": "MATCH (n) RETURN n"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + # url falls through from tier 1 (empty) to tier 2 (destination) + assert call_kwargs["server_url"] == "http://dest.example.com" + # api_key stays at tier 1 + assert call_kwargs["api_key"] == "read-key" + + # --- Case #4: explicit-first precedence assertion --- + + async def test_case4_explicit_read_config_wins_both_fields(self) -> None: + """Case #4: BOTH url and api_key come from tier 1 when read_destinations is set.""" + from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + + dest_resolver = _make_hook_resolver( + destinations={"default": _make_dest("http://upload.example.com", "upload-key")} + ) + coordinator = _make_coordinator(resolver=dest_resolver) + config = { + "read_destinations": { + "default": {"url": "http://read.example.com", "api_key": "read-key"}, + } + } + tool = GraphQueryTool(coordinator=coordinator, config=config) + + _, mock_cls = _make_mock_async_ci_client() + with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + result = await tool.execute({"query": "MATCH (n) RETURN n"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + # Both fields must come from tier 1 (explicit read config) + assert call_kwargs["server_url"] == "http://read.example.com" + assert call_kwargs["api_key"] == "read-key" + + # --- Case #5: env hit --- + + async def test_case5_env_hit_when_no_config_or_destinations(self) -> None: + """Case #5: canonical env vars work as tier-3 fallback (below hook destination).""" + from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + + dest_resolver = _make_hook_resolver(destinations={}) # no destinations + coordinator = _make_coordinator(resolver=dest_resolver) + tool = GraphQueryTool(coordinator=coordinator, config={}) + + env_patch = { + "AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL": "http://env.example.com", + "AMPLIFIER_CONTEXT_INTELLIGENCE_API_KEY": "env-key", + } + _, mock_cls = _make_mock_async_ci_client() + with ( + patch.dict(os.environ, env_patch), + patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls), + ): + result = await tool.execute({"query": "MATCH (n) RETURN n"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + assert call_kwargs["server_url"] == "http://env.example.com" + assert call_kwargs["api_key"] == "env-key" + + # --- Regression: env is below hook destination (tier 2 beats tier 3) --- + + async def test_case5b_env_does_not_override_hook_destination(self) -> None: + """Regression: canonical env vars set + hook destination present โ†’ destination wins. + + Locks in that env (tier 3) never outranks the hook destination (tier 2). + """ + from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + + dest_resolver = _make_hook_resolver( + destinations={"default": _make_dest("http://dest.example.com", "dest-key")} + ) + coordinator = _make_coordinator(resolver=dest_resolver) + tool = GraphQueryTool(coordinator=coordinator, config={}) + + # Canonical env set โ€” must NOT override the hook destination + env_patch = { + "AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL": "http://env-override.example.com", + "AMPLIFIER_CONTEXT_INTELLIGENCE_API_KEY": "env-override-key", + } + _, mock_cls = _make_mock_async_ci_client() + with ( + patch.dict(os.environ, env_patch), + patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls), + ): + result = await tool.execute({"query": "MATCH (n) RETURN n"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + # Hook destination (tier 2) wins over env (tier 3) + assert call_kwargs["server_url"] == "http://dest.example.com" + assert call_kwargs["api_key"] == "dest-key" + + # --- Case #6: all miss โ†’ configuration_error --- + + async def test_case6_all_miss_returns_configuration_error(self) -> None: + """Case #6: no read_destinations, no destinations, no env โ†’ configuration_error.""" + from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + + dest_resolver = _make_hook_resolver(destinations={}) + coordinator = _make_coordinator(resolver=dest_resolver) + tool = GraphQueryTool(coordinator=coordinator, config={}) + + # Exclude ALL CI env vars (including canonical SERVER_URL / API_KEY) + clean_env = { + k: v + for k, v in os.environ.items() + if not k.startswith("AMPLIFIER_CONTEXT_INTELLIGENCE_") + } + _, mock_cls = _make_mock_async_ci_client() + with ( + patch.dict(os.environ, clean_env, clear=True), + patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls), + ): + result = await tool.execute({"query": "MATCH (n) RETURN n"}) + + assert result.success is False + assert result.error is not None + assert result.error["type"] == "configuration_error" + + # --- Case #7: multi-entry ordering determinism --- + + async def test_case7_multi_entry_ordering_first_read_entry_wins(self) -> None: + """Case #7: first entry in read_destinations (insertion order) wins.""" + from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + + dest_resolver = _make_hook_resolver( + destinations={ + "d1": SimpleNamespace(name="d1", url="http://d1.example.com", api_key="d1-key"), + "d2": SimpleNamespace(name="d2", url="http://d2.example.com", api_key="d2-key"), + } + ) + coordinator = _make_coordinator(resolver=dest_resolver) + config = { + "read_destinations": { + "alpha": {"url": "http://alpha.example.com", "api_key": "alpha-key"}, + "beta": {"url": "http://beta.example.com", "api_key": "beta-key"}, + } + } + tool = GraphQueryTool(coordinator=coordinator, config=config) + + _, mock_cls = _make_mock_async_ci_client() + with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + result = await tool.execute({"query": "MATCH (n) RETURN n"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + # First read_destinations entry ("alpha") wins + assert call_kwargs["server_url"] == "http://alpha.example.com" + assert call_kwargs["api_key"] == "alpha-key" + + async def test_case7_second_execute_same_result_deterministic(self) -> None: + """Case #7: repeated executes give the same endpoint (deterministic order).""" + from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + + dest_resolver = _make_hook_resolver( + destinations={ + "d1": SimpleNamespace(name="d1", url="http://d1.example.com", api_key="d1") + } + ) + coordinator = _make_coordinator(resolver=dest_resolver) + config = { + "read_destinations": { + "alpha": {"url": "http://alpha.example.com", "api_key": "alpha-key"}, + } + } + tool = GraphQueryTool(coordinator=coordinator, config=config) + + _, mock_cls = _make_mock_async_ci_client() + with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + r1 = await tool.execute({"query": "MATCH (n) RETURN n"}) + r2 = await tool.execute({"query": "MATCH (n) RETURN n"}) + + assert r1.success is True + assert r2.success is True + # Both executes used the same endpoint + calls = mock_cls.call_args_list + assert ( + calls[0].kwargs["server_url"] + == calls[1].kwargs["server_url"] + == "http://alpha.example.com" + ) + + # --- Case #9: legacy top-level scalar synthesizes default --- + + async def test_case9_legacy_scalars_synthesize_read_default_wins_tier1(self) -> None: + """Case #9: legacy context_intelligence_server_url+api_key synthesize read_destinations.""" + from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + + dest_resolver = _make_hook_resolver( + destinations={"default": _make_dest("http://upload.example.com", "upload-key")} + ) + coordinator = _make_coordinator(resolver=dest_resolver) + # Legacy scalars in tool config โ€” no read_destinations key + config = { + "context_intelligence_server_url": "http://legacy.example.com", + "context_intelligence_api_key": "legacy-key", + } + tool = GraphQueryTool(coordinator=coordinator, config=config) + + _, mock_cls = _make_mock_async_ci_client() + with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + result = await tool.execute({"query": "MATCH (n) RETURN n"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + # Synthesized default ("http://legacy.example.com") wins at tier 1 + assert call_kwargs["server_url"] == "http://legacy.example.com" + assert call_kwargs["api_key"] == "legacy-key" + + # --- Case #10: legacy url-only โ†’ no synthesis, falls through --- + + async def test_case10_legacy_url_only_no_synthesis_falls_through_to_destination(self) -> None: + """Case #10: legacy url-only (no api_key) โ†’ read_destinations={}, falls to tier 2.""" + from amplifier_module_tool_graph_query.graph_query_tool import GraphQueryTool + + dest_resolver = _make_hook_resolver( + destinations={"default": _make_dest("http://upload.example.com", "upload-key")} + ) + coordinator = _make_coordinator(resolver=dest_resolver) + # Only server_url, no api_key โ†’ both-fields-required not met โ†’ no synthesis + config = { + "context_intelligence_server_url": "http://legacy.example.com", + # no context_intelligence_api_key + } + tool = GraphQueryTool(coordinator=coordinator, config=config) + + _, mock_cls = _make_mock_async_ci_client() + with patch("amplifier_module_tool_graph_query.graph_query_tool.AsyncCIClient", mock_cls): + result = await tool.execute({"query": "MATCH (n) RETURN n"}) + + assert result.success is True + call_kwargs = mock_cls.call_args.kwargs + # No synthesis โ†’ read_destinations={} โ†’ falls through to tier 2 + assert call_kwargs["server_url"] == "http://upload.example.com" + assert call_kwargs["api_key"] == "upload-key" diff --git a/modules/tool-graph-query/uv.lock b/modules/tool-graph-query/uv.lock index 8d2a6e2..f459672 100644 --- a/modules/tool-graph-query/uv.lock +++ b/modules/tool-graph-query/uv.lock @@ -5,25 +5,12 @@ requires-python = ">=3.11" [[package]] name = "amplifier-bundle-context-intelligence" version = "0.1.1" -source = { editable = "../../" } - -[package.metadata] - -[package.metadata.requires-dev] -dev = [ - { name = "httpx", specifier = ">=0.25" }, - { name = "idna", specifier = ">=3.15" }, - { name = "pyright", specifier = ">=1.1" }, - { name = "pytest", specifier = ">=9.0.3" }, - { name = "pytest-asyncio", specifier = ">=0.24" }, - { name = "pyyaml", specifier = ">=6.0" }, - { name = "ruff", specifier = ">=0.4" }, -] +source = { git = "https://github.com/microsoft/amplifier-bundle-context-intelligence?rev=main#2e47dc7c331b60210814f711129a10fdffd76ee4" } [[package]] name = "amplifier-core" -version = "1.2.4" -source = { git = "https://github.com/microsoft/amplifier-core?branch=main#7a99cbbcb6b191872e9ffd5cf4beed18a59511c2" } +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "pydantic" }, @@ -31,6 +18,14 @@ dependencies = [ { name = "tomli" }, { name = "typing-extensions" }, ] +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/90/d520390cd91aae3d02db53653f828046089c79203dbb142e9bda346fa1d6/amplifier_core-1.6.0-cp311-abi3-macosx_10_12_x86_64.whl", hash = "sha256:d35130e4262cf0db2d6c5f7e65e244a9ef2c7397bfe2a9853bc9b0d9fd05be64", size = 8113151, upload-time = "2026-05-18T16:13:46.825Z" }, + { url = "https://files.pythonhosted.org/packages/94/75/3ab3126ba5a6f2fc6051a4d08e42364899e4c9ac4daa9d0a60947bf8acd1/amplifier_core-1.6.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:387a2c58fcf4caefdb45c52ec228307bc225e73606897f242154782bc3e123da", size = 7268223, upload-time = "2026-05-18T16:13:48.749Z" }, + { url = "https://files.pythonhosted.org/packages/21/22/5a36160b3487170bcba0cbc61535101ff624e8314ed38fd35e561cb711a1/amplifier_core-1.6.0-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8344fccdedd725a51c018de17867cdf1c35abb571dabc0bbccdb5c1242324a47", size = 7532259, upload-time = "2026-05-18T16:13:50.614Z" }, + { url = "https://files.pythonhosted.org/packages/bd/d7/3874c2308523209411367cf3b8b690e14e869f5f6bfb64cb1b1971e06a96/amplifier_core-1.6.0-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a8e0103242a2e2a975c880b1de0e5a02501e0421c1e5386dadae3f111e1d2b5", size = 8507642, upload-time = "2026-05-18T16:13:52.977Z" }, + { url = "https://files.pythonhosted.org/packages/86/59/3646a89537b4556274183519f6db9c354fb3d183f52ef4a2179af12dd386/amplifier_core-1.6.0-cp311-abi3-win_amd64.whl", hash = "sha256:5113aa2d88038776eb257af9e7d9de7af13b3cd9097d2ac67aef5730fa0678e3", size = 8910313, upload-time = "2026-05-18T16:13:55.249Z" }, + { url = "https://files.pythonhosted.org/packages/9f/9e/58b141115e5eea65703f0b01459eefed36b561e9642ba96d48542345cd8f/amplifier_core-1.6.0-cp311-abi3-win_arm64.whl", hash = "sha256:e1b2731dc09d1cbc668b411007e7f9a2c7edbd75b2525407cae1e6b4a4de0b83", size = 7661416, upload-time = "2026-05-18T16:13:57.513Z" }, +] [[package]] name = "amplifier-module-tool-graph-query" @@ -53,14 +48,14 @@ dev = [ [package.metadata] requires-dist = [ - { name = "amplifier-bundle-context-intelligence", editable = "../../" }, + { name = "amplifier-bundle-context-intelligence", git = "https://github.com/microsoft/amplifier-bundle-context-intelligence?rev=main" }, { name = "httpx", specifier = ">=0.28.1" }, { name = "idna", specifier = ">=3.15" }, ] [package.metadata.requires-dev] dev = [ - { name = "amplifier-core", git = "https://github.com/microsoft/amplifier-core?branch=main" }, + { name = "amplifier-core", specifier = ">=1.6.0" }, { name = "pyright", specifier = ">=1.1" }, { name = "pytest", specifier = ">=9.0.3" }, { name = "pytest-asyncio", specifier = ">=0.24" }, diff --git a/tests/test_tool_resolver.py b/tests/test_tool_resolver.py new file mode 100644 index 0000000..c8e7bce --- /dev/null +++ b/tests/test_tool_resolver.py @@ -0,0 +1,272 @@ +"""Unit tests for context_intelligence.tool_resolver. + +Tests the shared helpers (_first_entry, _first_destination, resolve_query_endpoint) +and ToolConfigResolver.read_destinations (including legacy synthesis โ€” spec ยง7 cases +#9 and #10 at the unit level). +""" + +from __future__ import annotations + +import os +from types import SimpleNamespace +from typing import Any +from unittest.mock import MagicMock, patch + + +# --------------------------------------------------------------------------- +# Helpers +# --------------------------------------------------------------------------- + + +def _make_coordinator(config: dict | None = None) -> MagicMock: + """MagicMock coordinator with a real .config dict (not a Mock auto-attr).""" + coordinator = MagicMock() + coordinator.config = config if config is not None else {} + return coordinator + + +def _make_dest(url: str, api_key: str, name: str = "default") -> SimpleNamespace: + """Destination-like SimpleNamespace.""" + return SimpleNamespace(name=name, url=url, api_key=api_key) + + +# --------------------------------------------------------------------------- +# TestFirstEntry +# --------------------------------------------------------------------------- + + +class TestFirstEntry: + """_first_entry() โ€” edge-case coverage.""" + + def test_none_returns_none(self) -> None: + from context_intelligence.tool_resolver import _first_entry + + assert _first_entry(None) is None + + def test_empty_dict_returns_none(self) -> None: + from context_intelligence.tool_resolver import _first_entry + + assert _first_entry({}) is None + + def test_non_dict_mock_returns_none(self) -> None: + """A MagicMock (auto-created attribute) is not a dict โ†’ None.""" + from context_intelligence.tool_resolver import _first_entry + + assert _first_entry(MagicMock()) is None + + def test_single_entry_returns_value(self) -> None: + from context_intelligence.tool_resolver import _first_entry + + result = _first_entry({"alpha": "hello"}) + assert result == "hello" + + def test_two_entry_dict_returns_first(self) -> None: + from context_intelligence.tool_resolver import _first_entry + + result = _first_entry({"alpha": 1, "beta": 2}) + assert result == 1 + + +# --------------------------------------------------------------------------- +# TestFirstDestination +# --------------------------------------------------------------------------- + + +class TestFirstDestination: + """_first_destination() โ€” delegating edge cases.""" + + def test_none_resolver_returns_none(self) -> None: + from context_intelligence.tool_resolver import _first_destination + + assert _first_destination(None) is None + + def test_resolver_with_empty_destinations_returns_none(self) -> None: + from context_intelligence.tool_resolver import _first_destination + + resolver = MagicMock() + resolver.destinations = {} + assert _first_destination(resolver) is None + + def test_resolver_with_no_destinations_attr_returns_none(self) -> None: + """getattr(resolver, 'destinations', None) returns None for a plain object.""" + from context_intelligence.tool_resolver import _first_destination + + class NoDestinations: + pass + + assert _first_destination(NoDestinations()) is None + + +# --------------------------------------------------------------------------- +# TestResolveQueryEndpointHelpers +# --------------------------------------------------------------------------- + + +class TestResolveQueryEndpoint: + """resolve_query_endpoint() โ€” the three-tier chain.""" + + def _make_empty_tool_resolver(self) -> Any: + from context_intelligence.tool_resolver import ToolConfigResolver + + return ToolConfigResolver({}, _make_coordinator()) + + async def test_none_hook_and_empty_tool_resolver_returns_none_tuple(self) -> None: + from context_intelligence.tool_resolver import resolve_query_endpoint + + tool_resolver = self._make_empty_tool_resolver() + # Clear all CI env vars so tier-3 fallback cannot supply a URL + clean = {k: "" for k in os.environ if k.startswith("AMPLIFIER_CONTEXT_INTELLIGENCE_")} + with patch.dict(os.environ, clean): + url, api_key = resolve_query_endpoint(None, tool_resolver) + assert url is None + assert api_key is None + + async def test_debug_log_emitted(self, caplog: Any) -> None: + import logging + + from context_intelligence.tool_resolver import resolve_query_endpoint + + tool_resolver = self._make_empty_tool_resolver() + with caplog.at_level(logging.DEBUG, logger="context_intelligence.tool_resolver"): + resolve_query_endpoint(None, tool_resolver) + + assert any("CI query endpoint resolved" in r.message for r in caplog.records) + + +# --------------------------------------------------------------------------- +# TestToolConfigResolverReadDestinations +# --------------------------------------------------------------------------- + + +class TestToolConfigResolverReadDestinations: + """ToolConfigResolver.read_destinations โ€” parsing and legacy synthesis.""" + + def test_explicit_mapping_parsed(self) -> None: + """Explicit read_destinations key โ†’ parsed into ReadEndpoint dict.""" + from context_intelligence.tool_resolver import ReadEndpoint, ToolConfigResolver + + config = { + "read_destinations": { + "default": {"url": "http://read.example.com", "api_key": "read-key"}, + } + } + resolver = ToolConfigResolver(config, _make_coordinator()) + rd = resolver.read_destinations + + assert "default" in rd + assert isinstance(rd["default"], ReadEndpoint) + assert rd["default"].url == "http://read.example.com" + assert rd["default"].api_key == "read-key" + assert rd["default"].name == "default" + + def test_explicit_empty_dict_returns_empty(self) -> None: + """Explicit read_destinations={} โ†’ {} (no legacy synthesis).""" + from context_intelligence.tool_resolver import ToolConfigResolver + + config = {"read_destinations": {}} + resolver = ToolConfigResolver(config, _make_coordinator()) + assert resolver.read_destinations == {} + + def test_non_dict_entry_skipped(self) -> None: + """Non-dict entries under read_destinations are silently skipped.""" + from context_intelligence.tool_resolver import ToolConfigResolver + + config = { + "read_destinations": { + "bad": "not-a-dict", + "good": {"url": "http://read.example.com", "api_key": "k"}, + } + } + resolver = ToolConfigResolver(config, _make_coordinator()) + rd = resolver.read_destinations + assert "bad" not in rd + assert "good" in rd + + def test_url_api_key_stripped(self) -> None: + """Whitespace in url/api_key is stripped.""" + from context_intelligence.tool_resolver import ToolConfigResolver + + config = { + "read_destinations": { + "default": {"url": " http://read.example.com ", "api_key": " key "}, + } + } + resolver = ToolConfigResolver(config, _make_coordinator()) + rd = resolver.read_destinations + assert rd["default"].url == "http://read.example.com" + assert rd["default"].api_key == "key" + + # --- Case #9: legacy synthesis when BOTH scalars present --- + + def test_absent_key_both_scalars_synthesizes_default(self) -> None: + """Case #9 unit: absent read_destinations + both scalars โ†’ synthesized default.""" + from context_intelligence.tool_resolver import ReadEndpoint, ToolConfigResolver + + config = { + "context_intelligence_server_url": "http://legacy.example.com", + "context_intelligence_api_key": "legacy-key", + } + resolver = ToolConfigResolver(config, _make_coordinator()) + rd = resolver.read_destinations + + assert "default" in rd + assert isinstance(rd["default"], ReadEndpoint) + assert rd["default"].url == "http://legacy.example.com" + assert rd["default"].api_key == "legacy-key" + + # --- Case #10: url-only โ†’ no synthesis --- + + def test_absent_key_url_only_no_synthesis(self) -> None: + """Case #10 unit: absent read_destinations + url only โ†’ {} (no synthesis).""" + from context_intelligence.tool_resolver import ToolConfigResolver + + config = { + "context_intelligence_server_url": "http://legacy.example.com", + # no context_intelligence_api_key + } + resolver = ToolConfigResolver(config, _make_coordinator()) + assert resolver.read_destinations == {} + + def test_absent_key_no_scalars_returns_empty(self) -> None: + """Absent key + no scalars โ†’ {} (neither synthesis nor parse).""" + from context_intelligence.tool_resolver import ToolConfigResolver + + resolver = ToolConfigResolver({}, _make_coordinator()) + assert resolver.read_destinations == {} + + def test_read_destinations_cached_after_first_access(self) -> None: + """read_destinations is cached โ€” same object returned on second access.""" + from context_intelligence.tool_resolver import ToolConfigResolver + + config = { + "read_destinations": { + "default": {"url": "http://read.example.com", "api_key": "k"}, + } + } + resolver = ToolConfigResolver(config, _make_coordinator()) + rd1 = resolver.read_destinations + rd2 = resolver.read_destinations + assert rd1 is rd2 + + # --- env is excluded from legacy synthesis (tier 3 only) --- + + def test_absent_key_env_does_not_synthesize_into_tier1(self) -> None: + """Env vars are excluded from legacy synthesis โ€” env can never enter tier 1. + + Setting canonical env vars alone does NOT cause legacy synthesis to fire. + Env is only consulted at tier 3 in resolve_query_endpoint(), which is + BELOW the hook destination (tier 2). This prevents env from outranking + an upload destination via the synthesis path. + """ + from context_intelligence.tool_resolver import ToolConfigResolver + + env_patch = { + "AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL": "http://env-scalar.example.com", + "AMPLIFIER_CONTEXT_INTELLIGENCE_API_KEY": "env-scalar-key", + } + with patch.dict(os.environ, env_patch): + resolver = ToolConfigResolver({}, _make_coordinator()) + rd = resolver.read_destinations + + # Env must NOT synthesize into read_destinations โ€” result is empty dict. + assert rd == {} From f944020a85b51122f629552440335f5bb58f1519 Mon Sep 17 00:00:00 2001 From: colombod Date: Tue, 23 Jun 2026 09:18:06 +0000 Subject: [PATCH 2/5] refactor(modules): merge graph-query + blob-read into tool-context-intelligence-query MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two context-intelligence read tools shipped as separate modules (tool-graph-query, tool-blob-read) that each built their own ToolConfigResolver and required sources to be configured twice (overrides.tool-graph-query.config AND overrides.tool-blob-read.config) -- two namespaces that could silently drift. Merge them into one module, tool-context-intelligence-query, that mounts BOTH tools. The single mount() builds ONE ToolConfigResolver and injects the same instance into both tools (constructor is now (coordinator, resolver=None); the unused config parameter is dropped from the tools). Result: one config namespace overrides.tool-context-intelligence-query.config.sources shared by both tools -- they can no longer diverge. Tool NAMES (graph_query, blob_read) and the explicit-first resolution semantics are unchanged; the lazy hook-resolver lookup stays at execute() time (tools mount before hooks -- a guaranteed kernel invariant). Idiomatic per the kernel/module contract (one module registering multiple tools, like tool-filesystem; mount() returns None -- non-callable returns are kernel-ignored; the shared resolver is plain injection, not a capability, since it is intra-module). Updated the sole composition site (agents/graph-analyst.md: two module entries -> one), the CI matrix (ci.yml: two lanes -> one, PYTHONPATH shadow kept), README (one sources block + repo tree), context/config-resolution.dot labels, the tool_resolver.py docstring, and regenerated bundle.dot/bundle.png. Tests: full per-tool matrix ported for both tools (85 passing) plus new module-level tests -- mount registers exactly two distinct tools; shared-resolver identity AND consistency; a late-mount timing test proving the hook lookup stays lazy at execute(); and malformed/empty destination inputs. CI shape (uv sync --frozen + PYTHONPATH shadow) green. Validation: end-to-end in a Digital Twin via the merged module's real installed code -- one mount() mounts BOTH tools, each resolves its endpoint from the first hook destination (tier 2), and both issue real READ requests (POST /cypher, GET /blobs) to a mock CI server carrying the destination's Bearer key; negative control (no hook resolver) reproduces the configuration_error. Bundle validator (full mode): packaging build passes, all bundles load "good", bundle.dot regenerated. No migration: sources is unreleased (introduced in this same PR), and the only composition site is in-repo, so the module-path change has no external consumers. ๐Ÿค– Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com> --- .github/workflows/ci.yml | 3 +- README.md | 24 +- agents/graph-analyst.md | 6 +- bundle.dot | 35 +- bundle.png | Bin 174175 -> 148656 bytes context/config-resolution.dot | 6 +- context_intelligence/tool_resolver.py | 55 +- .../__init__.py | 20 - modules/tool-blob-read/tests/test_mount.py | 73 --- modules/tool-blob-read/uv.lock | 515 ----------------- .../__init__.py | 41 ++ .../blob_read_tool.py | 11 +- .../graph_query_tool.py | 10 +- .../pyproject.toml | 9 +- .../tests/__init__.py | 0 .../tests/test_blob_read_tool.py | 172 +++--- .../tests/test_graph_query_tool.py | 422 ++++++++------ .../tests/test_module.py | 519 +++++++++++++++++ .../tests/test_tool_dependencies.py | 48 +- .../tool-context-intelligence-query/uv.lock | 520 ++++++++++++++++++ .../__init__.py | 26 - modules/tool-graph-query/pyproject.toml | 52 -- modules/tool-graph-query/tests/__init__.py | 0 modules/tool-graph-query/tests/test_mount.py | 73 --- .../tests/test_tool_dependencies.py | 96 ---- modules/tool-graph-query/uv.lock | 515 ----------------- tests/test_tool_resolver.py | 62 +-- 27 files changed, 1584 insertions(+), 1729 deletions(-) delete mode 100644 modules/tool-blob-read/amplifier_module_tool_blob_read/__init__.py delete mode 100644 modules/tool-blob-read/tests/test_mount.py delete mode 100644 modules/tool-blob-read/uv.lock create mode 100644 modules/tool-context-intelligence-query/amplifier_module_tool_context_intelligence_query/__init__.py rename modules/{tool-blob-read/amplifier_module_tool_blob_read => tool-context-intelligence-query/amplifier_module_tool_context_intelligence_query}/blob_read_tool.py (92%) rename modules/{tool-graph-query/amplifier_module_tool_graph_query => tool-context-intelligence-query/amplifier_module_tool_context_intelligence_query}/graph_query_tool.py (93%) rename modules/{tool-blob-read => tool-context-intelligence-query}/pyproject.toml (73%) rename modules/{tool-blob-read => tool-context-intelligence-query}/tests/__init__.py (100%) rename modules/{tool-blob-read => tool-context-intelligence-query}/tests/test_blob_read_tool.py (74%) rename modules/{tool-graph-query => tool-context-intelligence-query}/tests/test_graph_query_tool.py (61%) create mode 100644 modules/tool-context-intelligence-query/tests/test_module.py rename modules/{tool-blob-read => tool-context-intelligence-query}/tests/test_tool_dependencies.py (64%) create mode 100644 modules/tool-context-intelligence-query/uv.lock delete mode 100644 modules/tool-graph-query/amplifier_module_tool_graph_query/__init__.py delete mode 100644 modules/tool-graph-query/pyproject.toml delete mode 100644 modules/tool-graph-query/tests/__init__.py delete mode 100644 modules/tool-graph-query/tests/test_mount.py delete mode 100644 modules/tool-graph-query/tests/test_tool_dependencies.py delete mode 100644 modules/tool-graph-query/uv.lock diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cf192db..13317ef 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,9 +77,8 @@ jobs: matrix: module: - hook-context-intelligence - - tool-blob-read + - tool-context-intelligence-query - tool-context-intelligence-upload - - tool-graph-query steps: - uses: actions/checkout@v4 diff --git a/README.md b/README.md index 1c62621..7d35c8d 100644 --- a/README.md +++ b/README.md @@ -299,34 +299,29 @@ Legacy degradation (differs from `destinations`): if `context_intelligence_serve #### Query tools (`graph-query`, `blob-read`) โ€” read-side endpoint -The hook config above governs **where events are written** (the upload / fan-out side). The **query tools** `tool-graph-query` and `tool-blob-read` are the **read side** โ€” they call a Context Intelligence server to answer graph queries and fetch blobs. They resolve their `(server_url, api_key)` independently per field, **explicit-read-config first**, and the chain is designed so that **configuring `destinations` alone is enough** โ€” you do **not** have to repeat the endpoint for queries: +The hook config above governs **where events are written** (the upload / fan-out side). The **query tools** `graph_query` and `blob_read` (both mounted by the `tool-context-intelligence-query` module) are the **read side** โ€” they call a Context Intelligence server to answer graph queries and fetch blobs. They share a single `ToolConfigResolver` built once in `mount()`, so **a single config namespace** (`overrides.tool-context-intelligence-query.config`) serves both tools. They resolve their `(server_url, api_key)` independently per field, **explicit-read-config first**, and the chain is designed so that **configuring `destinations` alone is enough** โ€” you do **not** have to repeat the endpoint for queries: | Order | Source | Notes | |-------|--------|-------| -| **1** | First entry of `read_destinations` on the tool's own config (`overrides.tool-graph-query.config` / `overrides.tool-blob-read.config`) | The explicit read override. Wins when set. | +| **1** | First entry of `sources` on the tool's own config (`overrides.tool-context-intelligence-query.config`) | The explicit read override. Wins when set. Applies to both `graph_query` and `blob_read` โ€” configure once. | | **2** | First entry of the hook's `destinations` block | **The common case** โ€” queries follow the same server you upload to, with zero extra config. This is the bridge that makes a `destinations`-only setup "just work" for reads. | | **3** | Env `AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL` / `AMPLIFIER_CONTEXT_INTELLIGENCE_API_KEY` | Single canonical last-resort fallback (reached via `${VAR}` placeholders in the shipped YAML, same convention as everywhere else). | | โ€” | else | `configuration_error: "context-intelligence server URL not configured"`. | Each field walks the chain independently (a tier that supplies a `url` but no `api_key` lets `api_key` fall through). **Env is a true fallback โ€” it never outranks the hook destination** (tier 2). There are **no** `*_PRIVATE_*` environment variables; the only env names consulted are the canonical `AMPLIFIER_CONTEXT_INTELLIGENCE_SERVER_URL` / `_API_KEY`. -**`read_destinations`** is a dict keyed by name, mirroring the hook's `destinations` shape. The **first** entry (declaration / insertion order) is used. Reach for it only when the read endpoint must differ from the upload destination (e.g. a read replica or a debugging override) โ€” it overrides the **read path only** and does not change where the hook uploads: +**`sources`** is a dict keyed by name, mirroring the hook's `destinations` shape. The **first** entry (declaration / insertion order) is used. Reach for it only when the read endpoint must differ from the upload destination (e.g. a read replica or a debugging override) โ€” it overrides the **read path only** and does not change where the hook uploads: ```yaml # ~/.amplifier/settings.yaml โ€” only needed when queries must hit a DIFFERENT server than uploads +# One config namespace covers both graph_query and blob_read tools โ€” configure once. overrides: - tool-graph-query: + tool-context-intelligence-query: config: - read_destinations: + sources: default: url: "http://read-replica.example.com" api_key: "${CI_READ_KEY}" # secret lives in keys.env, referenced here - tool-blob-read: - config: - read_destinations: - default: - url: "http://read-replica.example.com" - api_key: "${CI_READ_KEY}" ``` | Sub-key | Required | Default | Description | @@ -334,9 +329,9 @@ overrides: | `url` | yes | โ€” | Base URL of the CI server the query tool reads from. | | `api_key` | yes | โ€” | Bearer token for read requests to that server. | -**Legacy back-compat (read side):** with no `read_destinations` key present, explicit top-level scalars on the tool config (`context_intelligence_server_url` + `context_intelligence_api_key`, **both** required) synthesize a single `default` read entry at tier 1 โ€” symmetric to the hook's legacy synthesis. With neither set, resolution falls through to the hook destination (tier 2) and then env (tier 3). +**Legacy back-compat (read side):** with no `sources` key present, explicit top-level scalars on the tool config (`context_intelligence_server_url` + `context_intelligence_api_key`, **both** required) synthesize a single `default` read entry at tier 1 โ€” symmetric to the hook's legacy synthesis. With neither set, resolution falls through to the hook destination (tier 2) and then env (tier 3). -> **Most users configure nothing here.** A single hook `destinations` entry already powers both upload and query. `read_destinations` exists only for the read-replica / split-endpoint case. +> **Most users configure nothing here.** A single hook `destinations` entry already powers both upload and query. `sources` exists only for the read-replica / split-endpoint case. --- @@ -498,8 +493,7 @@ amplifier-bundle-context-intelligence/ โ”‚ โ””โ”€โ”€ jsonl-event-schema.md โ† events.jsonl schema contract โ”œโ”€โ”€ modules/ โ”‚ โ”œโ”€โ”€ hook-context-intelligence/ โ† the Python hook module -โ”‚ โ”œโ”€โ”€ tool-graph-query/ โ† graph_query tool module -โ”‚ โ””โ”€โ”€ tool-blob-read/ โ† blob_read tool module +โ”‚ โ””โ”€โ”€ tool-context-intelligence-query/ โ† graph_query + blob_read tools โ”œโ”€โ”€ docs/ โ”‚ โ”œโ”€โ”€ context-intelligence-exploration-guide.md โ† what to explore and how to test โ”‚ โ”œโ”€โ”€ dispatch-circuit-breaker.dot โ† dispatch flow and circuit breaker state machine diff --git a/agents/graph-analyst.md b/agents/graph-analyst.md index 780cc05..0d3b55c 100644 --- a/agents/graph-analyst.md +++ b/agents/graph-analyst.md @@ -38,10 +38,8 @@ model_role: [reasoning, general] tools: - module: tool-delegate source: git+https://github.com/microsoft/amplifier-foundation@main#subdirectory=modules/tool-delegate - - module: tool-graph-query - source: git+https://github.com/microsoft/amplifier-bundle-context-intelligence@main#subdirectory=modules/tool-graph-query - - module: tool-blob-read - source: git+https://github.com/microsoft/amplifier-bundle-context-intelligence@main#subdirectory=modules/tool-blob-read + - module: tool-context-intelligence-query + source: git+https://github.com/microsoft/amplifier-bundle-context-intelligence@main#subdirectory=modules/tool-context-intelligence-query - module: tool-filesystem source: git+https://github.com/microsoft/amplifier-module-tool-filesystem@main config: diff --git a/bundle.dot b/bundle.dot index 4c741b0..f15e890 100644 --- a/bundle.dot +++ b/bundle.dot @@ -1,56 +1,55 @@ -// This repository packages "Context Intelligence" โ€” a toolkit that automatically records and lets you explore what happened during AI work sessions. +// This repository packages tools and AI assistants that record, search, and analyze Amplifier's own work-session history. digraph context_intelligence { rankdir=LR fontname="Helvetica" fontsize=12 - label="Context Intelligence โ€” Session Recording & Exploration Toolkit\nv0.1.0 ยท a bundle of AI helpers, tools, and skills" + label="Context Intelligence โ€” Session History Toolkit\nA bundle that records and analyzes Amplifier's past work sessions (v0.1.0)" labelloc=t labeljust=c nodesep=0.6 ranksep=0.7 bgcolor="white" - source_hash="7758e3d982ed1c85e71f0883ab4ac4596d336fd517ba1192e2580fbe98c220d2" + source_hash="4636e62f1ae10ff3f60e2b22dcb755c49a7851ad51669ebb1fcb900c54a33559" node [fontname="Helvetica", fontsize=11, style="filled,rounded"] edge [fontname="Helvetica", fontsize=9] - root_context_intelligence [label="Context Intelligence (Main Package)\nv0.1.0\n0 tools ยท 0 agents\n~98 tok aggregate", shape=box, fillcolor="#80cbc4", style="filled,rounded,bold", penwidth=2] + root_context_intelligence [label="Context Intelligence (Main Package)\n0 tools ยท 0 agents\n~98 tok aggregate", shape=box, fillcolor="#80cbc4", style="filled,rounded,bold", penwidth=2] subgraph cluster_behaviors { - label="Behaviors (Reusable Skill Bundles)" + label="Capability Bundles" style="filled" fillcolor="#f9f9f9" color="#999999" - beh_context_intelligence_behavior [label="Core Skill Bundle\ncontext-intelligence-behavior\n4 tools\n~2549 tok", shape=box, fillcolor="#e0f2f1", style="filled,rounded"] + beh_context_intelligence_behavior [label="Session Analysis Toolkit\n4 tools\n~2549 tok", shape=box, fillcolor="#e0f2f1", style="filled,rounded"] } subgraph cluster_agents { - label="Agents (Specialized AI Helpers)" + label="Specialist Assistants" style="filled" fillcolor="#f9f9f9" color="#999999" - agt_context_intelligence_design_facilitator [label="Guides Designing New Tools\ncontext-intelligence-design-facilitator\n~187 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] - agt_context_intelligence_tool_designer [label="Designs Tool Blueprints\ncontext-intelligence-tool-designer\n~198 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] - agt_graph_analyst [label="Analyzes Session Data\ngraph-analyst\n~543 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] - agt_session_navigator [label="Browses Past Sessions\nsession-navigator\n~366 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] + agt_context_intelligence_design_facilitator [label="Design Helper\n(guides new features)\n~187 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] + agt_context_intelligence_tool_designer [label="Tool Builder Helper\n~198 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] + agt_graph_analyst [label="Session Graph Analyst\n(answers questions about sessions)\n~543 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] + agt_session_navigator [label="Session File Navigator\n(reads raw session files)\n~366 tok desc", shape=box, fillcolor="#c8e6c9", style="filled,rounded"] } subgraph cluster_modules { - label="Modules (Building-Block Tools)" + label="Building Blocks (Code Components)" style="filled" fillcolor="#f9f9f9" color="#999999" - mod_hook_context_intelligence [label="Records Activity Automatically\nhook-context-intelligence", shape=box, fillcolor="#bbdefb", style="filled,rounded"] - mod_tool_blob_read [label="Reads Stored Data\ntool-blob-read", shape=box, fillcolor="#bbdefb", style="filled,rounded"] - mod_tool_context_intelligence_upload [label="Uploads Session Data\ntool-context-intelligence-upload", shape=box, fillcolor="#bbdefb", style="filled,rounded"] - mod_tool_graph_query [label="Searches the Data Graph\ntool-graph-query", shape=box, fillcolor="#bbdefb", style="filled,rounded"] + mod_hook_context_intelligence [label="Auto Session Recorder", shape=box, fillcolor="#bbdefb", style="filled,rounded"] + mod_tool_context_intelligence_query [label="Session Search Tool", shape=box, fillcolor="#bbdefb", style="filled,rounded"] + mod_tool_context_intelligence_upload [label="Session Upload Tool", shape=box, fillcolor="#bbdefb", style="filled,rounded"] } subgraph cluster_legend { - label="Legend" + label="Legend (Color Key)" style="filled" fillcolor="white" color="#cccccc" @@ -70,7 +69,7 @@ digraph context_intelligence { disclaimer [label="Token estimates: ~4 chars/token\nSolid border = local (counted)\nDashed + red = external, hidden cost (not counted)\nDashed + muted = external, no cost\nExcludes: sub-session costs, runtime-dynamic", shape=note, fillcolor="#eceff1", style="filled", fontsize=9] - ext_githttps___github_com_microsoft_amplifier_foundation_main [label="Shared Foundation (External)\namplifier-foundation\n(external, cost)", shape=box, fillcolor="#80cbc4", style="dashed", color="red", penwidth=2] + ext_githttps___github_com_microsoft_amplifier_foundation_main [label="amplifier-foundation\n(shared base, external)", shape=box, fillcolor="#80cbc4", style="dashed", color="red", penwidth=2] root_context_intelligence -> ext_githttps___github_com_microsoft_amplifier_foundation_main [style=dashed] root_context_intelligence -> beh_context_intelligence_behavior [label="composes"] diff --git a/bundle.png b/bundle.png index fde63e932b8a3d8aa5c49a173abe545bca99e372..ee8de522e9963cb41ace05e4c212f47b3858a0d1 100644 GIT binary patch literal 148656 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�gM#%+z{xrC_ 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 z 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 qPY&K_=$^*#9rR!SS{_CIskh=jHWqD$L%F7A> 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 z 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 LE_Rarf#?1P^GV|2 literal 174175 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