3tears-search
Provider-agnostic web and media search for the 3tears family.
The authority for everything in this package is
docs/search-spec.md (decisions D1-D28), with
requirement IDs (SR-*, G*, P*) defined in
docs/search-requirements.md.
Layout
threetears/search/
contracts/ # the leaf within the leaf -- types, protocols, errors, keys
adapters/
searxng.py # one provider's API, over the injected transport
call.py # a query → one candidate set, bounded and negotiated
bind.py # prose for a model + the metadata projection
standalone.py # bare-httpx transport [standalone] -- the sanctioned path (D19)
testing/ # the shared provider-conformance suite + declared doubles
Layer names (Adapter, Call, Bind, …) are module vocabulary and never type names, so a later re-cut of the layers stays cheap.
contracts/ is the lingua franca every layer and every consumer speaks:
SearchRequestand the open criteria vocabulary (typed constructors for well-known criteria, namespaced keys for everything else), with per-criterion dispositions (pushdown | local | unsatisfied | ignored-unknown).Candidate-- the carrier-neutral result core: identity, locators, provenance, named provenanced scores (never a singlescorefield, D1), fidelity available/achieved, an optional content slot, and additive facets keyed by themedia-contractsvocabulary.Spend-- every resource a call consumed: money (Decimal), wall-clock, call count, weighted provider units, bytes.- The typed error taxonomy (SR-J1), every error carrying
Spend(SR-E3). Zero results is a success value, not an error (SR-J2). SearchTransport-- the injected transport seam (SR-N1, P9). A thin host-side adapter overthreetears.core.http_client.TracedHttpClientsatisfies it structurally; this package never imports core.SEARCH_RESULTS_METADATA_KEYand the versioned metadata projection (D13, D22).ProviderCapabilities-- what a provider can express, declared and queryable so a consumer branches before sending rather than after failing (SR-B4), following the3tears-modelscapability-metadata pattern.SearchProvider-- the provider seam Call depends on and the conformance suite parametrizes over.- Canonical serialization of request/parameter types -- one canonical form consumed by both the D26 replay key and eval run identity (SR-F1).
Using it
import asyncio
from threetears.search.adapters.searxng import SearxngAdapter
from threetears.search.bind import bind_search
from threetears.search.contracts import Criterion, SearchRequest
from threetears.search.standalone import StandaloneTransport # or your own
async def main() -> None:
adapter = SearxngAdapter(
base_url="https://searx.internal.example", # deployment config, never env
transport=StandaloneTransport(allow_private_addresses=True),
provider_instance="searxng-main",
)
rendered = await bind_search(
SearchRequest(query="capybara habitat range", criteria=(Criterion.max_results(5),)),
provider=adapter,
)
print(rendered.content) # prose for a model
print(rendered.metadata["search_results"]["candidates"]) # structure for a program
asyncio.run(main())
bind_search never raises: a typed failure arrives as a failed
RenderedSearch carrying its spend under the same metadata key (D10). Callers
that want the exception go through threetears.search.call.search instead.
Budgets and pacing pass through the same entry point: hand bind_search (or
search) a budget= implementing BudgetPort, a limiter= such as
threetears.search.limiter.InProcessRateLimiter -- construct one per
process and share it, or pacing paces nothing -- and the egress= name your
transport actually exits by (D8, D20). A budget refusal or pacing denial
renders as a failed result like any other typed failure; omitting the ports
means no budget is consulted and no pacing applies.
Hosts that already have threetears.core should inject a thin adapter over
TracedHttpClient rather than take the [standalone] extra -- it brings
timeouts, retry, circuit-breaking and spans for free.
Provider conformance
threetears.search.testing ships the suite every adapter passes -- contract
shape, spend on failure, error taxonomy, disposition honesty,
zero-results-is-success (SR-O5). It imports no test framework, so a consumer
can run it against its own wiring:
from threetears.search.testing import ProviderConformanceCase, ProviderConformanceSuite
class TestMyProviderConformance(ProviderConformanceSuite):
case = ProviderConformanceCase(...)
Not here yet
aggregate.py, extract.py, select.py, limiter.py and replay.py are
later phases of docs/search-spec.md §7. Budget-port consultation and pacing
are marked seams inside call.py: the port types are Phase 1 PR 2, and a
placeholder protocol would only be a second vocabulary to migrate off.
Import-cleanliness
Importing threetears.search.contracts pulls nothing beyond stdlib, pydantic,
and 3tears-media-contracts. Nothing in this package imports
threetears.core, threetears.agent.*, langchain, or NATS. Nothing reads
environment variables -- the host passes base URLs, secret references, and
transport (SR-K1).
standalone.py is the only module that imports httpx, and nothing in the
package imports standalone at module level: the extra stays opt-in, and a
host that injects its own transport never installs it. Both facts are pinned
by tests/test_package_boundaries.py, and the module's path is the D19
widening of the no-bespoke-client norm in
tests/enforcement/test_no_bespoke_reuse.py -- a sanctioned transport, with no
exemption filed.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file 3tears_search-0.24.0.tar.gz.
File metadata
- Download URL: 3tears_search-0.24.0.tar.gz
- Upload date:
- Size: 167.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
338a371e9653cbcaefe6a0e6ac3cd6811b3af6bef3be3e4e270210eb87e25f79
|
|
| MD5 |
a23cf0952994877867e7a42ac75642e0
|
|
| BLAKE2b-256 |
8ca098931713fa79b5507a77f1cc7116c0f344d1257fbeb7eda7fdc4db9f0473
|
Provenance
The following attestation bundles were made for 3tears_search-0.24.0.tar.gz:
Publisher:
release.yml on pacepace/3tears
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
3tears_search-0.24.0.tar.gz -
Subject digest:
338a371e9653cbcaefe6a0e6ac3cd6811b3af6bef3be3e4e270210eb87e25f79 - Sigstore transparency entry: 2424603356
- Sigstore integration time:
-
Permalink:
pacepace/3tears@3f190986bf7e0b3dbc70fc1d2f7aab65daa966a5 -
Branch / Tag:
refs/tags/v0.24.0 - Owner: https://github.com/pacepace
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3f190986bf7e0b3dbc70fc1d2f7aab65daa966a5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file 3tears_search-0.24.0-py3-none-any.whl.
File metadata
- Download URL: 3tears_search-0.24.0-py3-none-any.whl
- Upload date:
- Size: 125.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f3f33406b03a6946884cdd85df79d4ce85a755d6636edf4d35f6af61e890a61f
|
|
| MD5 |
4b5d9e9b9ed03595375ec7569b373933
|
|
| BLAKE2b-256 |
a3595508ad7be9789d69e3f5ca45320ac4e6ce9bc761e59ea26980a5486ed8bc
|
Provenance
The following attestation bundles were made for 3tears_search-0.24.0-py3-none-any.whl:
Publisher:
release.yml on pacepace/3tears
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
3tears_search-0.24.0-py3-none-any.whl -
Subject digest:
f3f33406b03a6946884cdd85df79d4ce85a755d6636edf4d35f6af61e890a61f - Sigstore transparency entry: 2424628857
- Sigstore integration time:
-
Permalink:
pacepace/3tears@3f190986bf7e0b3dbc70fc1d2f7aab65daa966a5 -
Branch / Tag:
refs/tags/v0.24.0 - Owner: https://github.com/pacepace
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@3f190986bf7e0b3dbc70fc1d2f7aab65daa966a5 -
Trigger Event:
push
-
Statement type: