lean-browser-use 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/CREDITS.md +18 -0
- package/LICENSE +21 -0
- package/README.md +159 -2
- package/agents/aun-browser-runner.md +48 -0
- package/bin/lean-browser-use.mjs +3 -0
- package/briefs/browser-read.md +63 -0
- package/briefs/helper-read.md +63 -0
- package/docs/PROVENANCE.md +32 -0
- package/docs/benchmark.md +91 -0
- package/docs/guards.md +54 -0
- package/docs/how-it-works.md +27 -0
- package/docs/install.md +78 -0
- package/docs/measure.md +53 -0
- package/docs/reader.md +39 -0
- package/docs/search.md +16 -0
- package/hooks/batch-nudge.mjs +14 -0
- package/hooks/batch-nudge.sh +8 -0
- package/hooks/common.mjs +71 -0
- package/hooks/hooks.settings.json +58 -0
- package/hooks/pick-guard.mjs +27 -0
- package/hooks/pick-guard.sh +8 -0
- package/hooks/retry-guard.mjs +69 -0
- package/hooks/retry-guard.sh +8 -0
- package/llms.txt +40 -0
- package/package.json +61 -4
- package/proof/benchmark.json +166 -0
- package/proof/results.json +241 -0
- package/reader/README.md +48 -0
- package/reader/crawl_helper.py +256 -0
- package/reader/reader +14 -0
- package/reader/reader_base.py +106 -0
- package/reader/reader_compile.py +106 -0
- package/reader/reader_crawl.py +67 -0
- package/reader/reader_extract.py +261 -0
- package/reader/reader_fetch.py +148 -0
- package/reader/reader_runtime.py +199 -0
- package/reader/reader_test_harness.py +173 -0
- package/reader/reader_test_support.py +214 -0
- package/reader/specs/claude-pricing.json +223 -0
- package/reader/specs/npm-package.json +67 -0
- package/reader/test_reader.py +345 -0
- package/reader/test_reader_1.py +309 -0
- package/reader/test_reader_2.py +348 -0
- package/reader/test_reader_3.py +254 -0
- package/reader/test_reader_contract.py +57 -0
- package/reader/testdata/claude-pricing.html +4 -0
- package/reader/testdata/compile_stub.py +24 -0
- package/reader/testdata/npm-react.html +4 -0
- package/reader/testdata/npm-schema.json +14 -0
- package/reader/testdata/npm-zod.html +4 -0
- package/reader/testdata/pricing-schema.json +24 -0
- package/searxng/README.md +29 -0
- package/searxng/compose.yml +21 -0
- package/searxng/core-config/settings.yml +26 -0
- package/searxng/deploy.sh +36 -0
- package/searxng/searx +73 -0
- package/searxng/test_searx.py +107 -0
- package/searxng/test_searx_offline.py +67 -0
- package/skills/lean-browser-use/SKILL.md +35 -0
- package/skills/lean-browser-use/references/cleanup.md +17 -0
- package/skills/lean-browser-use/references/cost-model.md +11 -0
- package/skills/lean-browser-use/references/draft-offline.md +9 -0
- package/skills/lean-browser-use/references/failure-modes.md +16 -0
- package/skills/lean-browser-use/references/logged-in-run.md +23 -0
- package/skills/lean-browser-use/references/packet-principle.md +15 -0
- package/skills/lean-browser-use/references/route-by-job.md +18 -0
- package/skills/lean-browser-use/references/runner-rules.md +27 -0
- package/skills/lean-browser-use/references/verify.md +9 -0
- package/src/cli.mjs +42 -0
- package/src/doctor.mjs +60 -0
- package/src/install.mjs +116 -0
- package/src/measure.mjs +64 -0
- package/src/paths.mjs +51 -0
- package/src/uninstall.mjs +68 -0
- package/src/util.mjs +35 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<!doctype html><html><body><article id="content-container">
|
|
2
|
+
<!-- Pricing table captured from official public page on 2026-10-23. -->
|
|
3
|
+
<table><colgroup></colgroup><colgroup span="2"></colgroup><colgroup span="3"></colgroup><thead><tr><th class="whitespace-nowrap" scope="colgroup">Model</th><th class="border-s whitespace-nowrap" colspan="2" scope="colgroup">Base tokens</th><th class="border-s whitespace-nowrap" colspan="3" scope="colgroup">Prompt caching</th></tr><tr><th class="py-xs text-secondary text-footnote font-medium whitespace-nowrap" scope="col" style="background-color:color-mix(in srgb, var(--cds-alpha-1) 50%, transparent)">Name</th><th class="py-xs text-secondary text-footnote font-medium whitespace-nowrap border-s" scope="col" style="background-color:color-mix(in srgb, var(--cds-alpha-1) 50%, transparent);padding-inline-end:calc(0.75em + var(--cds-pad-sm))">Input</th><th class="py-xs text-secondary text-footnote font-medium whitespace-nowrap" scope="col" style="background-color:color-mix(in srgb, var(--cds-alpha-1) 50%, transparent);padding-inline-end:calc(0.75em + var(--cds-pad-sm))">Output</th><th class="py-xs text-secondary text-footnote font-medium whitespace-nowrap border-s" scope="col" style="background-color:color-mix(in srgb, var(--cds-alpha-1) 50%, transparent);padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><button aria-expanded="false" aria-haspopup="dialog" class="inline cursor-help rounded-sm text-left underline decoration-dotted decoration-1 underline-offset-4 [text-decoration-color:color-mix(in_srgb,currentColor,transparent_55%)] focus-visible:shadow-focus focus-visible:outline-none print:contents" data-base-ui-click-trigger="" id="base-ui-_R_ut6g9li9av5ul5u9fmbtdpl4plb_" tabindex="0" type="button">5m writes</button></th><th class="py-xs text-secondary text-footnote font-medium whitespace-nowrap" scope="col" style="background-color:color-mix(in srgb, var(--cds-alpha-1) 50%, transparent);padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><button aria-expanded="false" aria-haspopup="dialog" class="inline cursor-help rounded-sm text-left underline decoration-dotted decoration-1 underline-offset-4 [text-decoration-color:color-mix(in_srgb,currentColor,transparent_55%)] focus-visible:shadow-focus focus-visible:outline-none print:contents" data-base-ui-click-trigger="" id="base-ui-_R_v56g9li9av5ul5u9fmbtdpl4plb_" tabindex="0" type="button">1h writes</button></th><th class="py-xs text-secondary text-footnote font-medium whitespace-nowrap" scope="col" style="background-color:color-mix(in srgb, var(--cds-alpha-1) 50%, transparent);padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><button aria-expanded="false" aria-haspopup="dialog" class="inline cursor-help rounded-sm text-left underline decoration-dotted decoration-1 underline-offset-4 [text-decoration-color:color-mix(in_srgb,currentColor,transparent_55%)] focus-visible:shadow-focus focus-visible:outline-none print:contents" data-base-ui-click-trigger="" id="base-ui-_R_vd6g9li9av5ul5u9fmbtdpl4plb_" tabindex="0" type="button">Hits and refreshes</button></th></tr></thead><tbody><tr><td class="align-middle h-18 not-print:group-data-collapsed/rows:h-auto not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><div class="flex items-start gap-sm"><div aria-hidden="true" class="flex shrink-0 items-center justify-center size-7 rounded mt-1" style="background-color:var(--cds-blue-300)"><img alt="" class="h-4 w-auto" data-nimg="1" decoding="async" height="59" loading="lazy" src="/images/dashboard-discovery/head.svg?dpl=f317f7548df059f9a9d82e81295c1e733df69ca3-5d6fc624" style="color:transparent" width="51"/></div><div class="flex min-w-0 flex-col"><a class="cds-reset cds-text-link cds-text-link-underline inline [transition-property:text-decoration-color,box-shadow] [&:not(:hover,:focus-visible)]:[--_text-link-line:color-mix(in_srgb,currentColor,transparent_35%)] cursor-pointer font-medium whitespace-nowrap text-primary" data-cds="TextLink" data-inherit-color="" href="/docs/en/models/fable-5-1/overview">Claude Fable 5.1</a><span class="text-caption text-secondary">For demanding reasoning and long-horizon agentic work</span></div></div></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$10<!-- --> <span class="text-footnote text-muted">/ <button aria-expanded="false" aria-haspopup="dialog" class="inline cursor-help rounded-sm text-left underline decoration-dotted decoration-1 underline-offset-4 [text-decoration-color:color-mix(in_srgb,currentColor,transparent_55%)] focus-visible:shadow-focus focus-visible:outline-none print:contents" data-base-ui-click-trigger="" id="base-ui-_R_v932og9li9av5ul5u9fmbtdpl4plb_" tabindex="0" type="button">MTok</button></span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$12.50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$20<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap"><button aria-expanded="false" aria-haspopup="dialog" class="inline cursor-help rounded-sm text-left underline decoration-dotted decoration-1 underline-offset-4 [text-decoration-color:color-mix(in_srgb,currentColor,transparent_55%)] focus-visible:shadow-focus focus-visible:outline-none print:contents" data-base-ui-click-trigger="" id="base-ui-_R_1sr2og9li9av5ul5u9fmbtdpl4plb_" tabindex="0" type="button">$0.25</button> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle h-18 not-print:group-data-collapsed/rows:h-auto not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><div class="flex items-start gap-sm"><div aria-hidden="true" class="flex shrink-0 items-center justify-center size-7 rounded mt-1" style="background-color:var(--cds-orange-250)"><img alt="" class="h-4 w-auto" data-nimg="1" decoding="async" height="65" loading="lazy" src="/images/dashboard-discovery/cursor.svg?dpl=f317f7548df059f9a9d82e81295c1e733df69ca3-5d6fc624" style="color:transparent" width="64"/></div><div class="flex min-w-0 flex-col"><a class="cds-reset cds-text-link cds-text-link-underline inline [transition-property:text-decoration-color,box-shadow] [&:not(:hover,:focus-visible)]:[--_text-link-line:color-mix(in_srgb,currentColor,transparent_35%)] cursor-pointer font-medium whitespace-nowrap text-primary" data-cds="TextLink" data-inherit-color="" href="/docs/en/models/opus-5-5/overview">Claude Opus 5.5</a><span class="text-caption text-secondary">For long-running agentic coding and knowledge work</span></div></div></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$4<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$20<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$5<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$8<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap"><button aria-expanded="false" aria-haspopup="dialog" class="inline cursor-help rounded-sm text-left underline decoration-dotted decoration-1 underline-offset-4 [text-decoration-color:color-mix(in_srgb,currentColor,transparent_55%)] focus-visible:shadow-focus focus-visible:outline-none print:contents" data-base-ui-click-trigger="" id="base-ui-_R_1sr4og9li9av5ul5u9fmbtdpl4plb_" tabindex="0" type="button">$0.20</button> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle h-18 not-print:group-data-collapsed/rows:h-auto not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><div class="flex items-start gap-sm"><div aria-hidden="true" class="flex shrink-0 items-center justify-center size-7 rounded mt-1" style="background-color:#F0EEE6"><img alt="" class="h-4 w-auto" data-nimg="1" decoding="async" height="58" loading="lazy" src="/images/dashboard-discovery/bubble.svg?dpl=f317f7548df059f9a9d82e81295c1e733df69ca3-5d6fc624" style="color:transparent" width="57"/></div><div class="flex min-w-0 flex-col"><a class="cds-reset cds-text-link cds-text-link-underline inline [transition-property:text-decoration-color,box-shadow] [&:not(:hover,:focus-visible)]:[--_text-link-line:color-mix(in_srgb,currentColor,transparent_35%)] cursor-pointer font-medium whitespace-nowrap text-primary" data-cds="TextLink" data-inherit-color="" href="/docs/en/models/sonnet-5-5/overview">Claude Sonnet 5.5</a><span class="text-caption text-secondary">The best combination of speed and intelligence</span></div></div></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$2<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$10<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$2.50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$4<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap"><button aria-expanded="false" aria-haspopup="dialog" class="inline cursor-help rounded-sm text-left underline decoration-dotted decoration-1 underline-offset-4 [text-decoration-color:color-mix(in_srgb,currentColor,transparent_55%)] focus-visible:shadow-focus focus-visible:outline-none print:contents" data-base-ui-click-trigger="" id="base-ui-_R_1sr6og9li9av5ul5u9fmbtdpl4plb_" tabindex="0" type="button">$0.10</button> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle h-18 not-print:group-data-collapsed/rows:h-auto not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0" rowspan="2"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><div class="flex items-start gap-sm"><div aria-hidden="true" class="flex shrink-0 items-center justify-center size-7 rounded mt-1" style="background-color:var(--cds-cactus)"><img alt="" class="h-4 w-auto" data-nimg="1" decoding="async" height="54" loading="lazy" src="/images/dashboard-discovery/bird.svg?dpl=f317f7548df059f9a9d82e81295c1e733df69ca3-5d6fc624" style="color:transparent" width="65"/></div><div class="flex min-w-0 flex-col"><a class="cds-reset cds-text-link cds-text-link-underline inline [transition-property:text-decoration-color,box-shadow] [&:not(:hover,:focus-visible)]:[--_text-link-line:color-mix(in_srgb,currentColor,transparent_35%)] cursor-pointer font-medium whitespace-nowrap text-primary" data-cds="TextLink" data-inherit-color="" href="/docs/en/models/haiku-5-5/overview">Claude Haiku 5.5</a><span class="text-caption text-secondary">For high-volume, latency-sensitive tasks such as classification, extraction, and routing</span></div></div></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.10<!-- --> <span class="text-footnote text-muted">/ MTok</span><span class="block text-footnote text-muted print:whitespace-normal">for prompts up to 100,000 tokens</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.125<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.20<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.01<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.50<!-- --> <span class="text-footnote text-muted">/ MTok</span><span class="block text-footnote text-muted print:whitespace-normal">for prompts over 100,000 tokens</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$2.50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.625<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$1<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.05<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td></tr></tbody><tbody><tr><th aria-label="Additional models" class="bg-transparent py-sm" colspan="6" scope="rowgroup"><div class="flex" data-cds="Collapsible" data-open=""><button aria-controls="_R_18g9li9av5ul5u9fmbtdpl4plb_" aria-disabled="false" aria-expanded="true" class="cds-reset group/clp inline-flex w-fit items-center gap-1.5 border-0 select-none outline-none focus-visible:outline-hidden font-sans text-secondary hover:text-primary transition-shadow duration-fast focus-visible:shadow-focus rounded data-[disabled]:opacity-disabled data-[disabled]:pointer-events-none text-footnote font-medium" data-panel-open="" tabindex="0" type="button"><span aria-hidden="true" class="shrink-0 transition-transform group-data-[panel-open]/clp:rotate-90 group-data-[panel-open]/clp:page-rtl:-rotate-90" data-cds="Icon" data-cds-mirror="" style="font-size:calc(1rem * var(--cds-rem-scale, 1));font-weight:533.3"></span>Additional models</button></div></th></tr></tbody><tbody class="group/rows" id="_R_18g9li9av5ul5u9fmbtdpl4plb_"><tr><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><span class="inline-flex items-center gap-xs"><a class="cds-reset cds-text-link cds-text-link-underline inline text-inherit [transition-property:text-decoration-color,box-shadow] [&:not(:hover,:focus-visible)]:[--_text-link-line:color-mix(in_srgb,currentColor,transparent_35%)] cursor-pointer" data-cds="TextLink" data-inherit-color="" href="/docs/en/models/mythos-5-1/overview">Claude Mythos 5.1</a><button aria-expanded="false" aria-haspopup="dialog" aria-label="Claude Mythos 5.1 (Verification required)" class="-m-1 inline-flex shrink-0 cursor-help items-center justify-center rounded p-1 text-muted transition-colors duration-fast outline-none hover:text-secondary focus-visible:text-secondary focus-visible:shadow-focus data-[popup-open]:text-secondary" data-base-ui-click-trigger="" id="base-ui-_R_3sgr8g9li9av5ul5u9fmbtdpl4plb_" tabindex="0" type="button"><span aria-hidden="true" data-cds="Icon" style="font-size:calc(1rem * var(--cds-rem-scale, 1));font-weight:533.3"></span></button></span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$10<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$12.50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$20<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap"><button aria-expanded="false" aria-haspopup="dialog" class="inline cursor-help rounded-sm text-left underline decoration-dotted decoration-1 underline-offset-4 [text-decoration-color:color-mix(in_srgb,currentColor,transparent_55%)] focus-visible:shadow-focus focus-visible:outline-none print:contents" data-base-ui-click-trigger="" id="base-ui-_R_1srr8g9li9av5ul5u9fmbtdpl4plb_" tabindex="0" type="button">$0.25</button> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><a class="cds-reset cds-text-link cds-text-link-underline inline text-inherit [transition-property:text-decoration-color,box-shadow] [&:not(:hover,:focus-visible)]:[--_text-link-line:color-mix(in_srgb,currentColor,transparent_35%)] cursor-pointer" data-cds="TextLink" data-inherit-color="" href="/docs/en/models/fable-5/overview">Claude Fable 5</a></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$10<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$12.50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$20<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$1<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><span class="inline-flex items-center gap-xs"><a class="cds-reset cds-text-link cds-text-link-underline inline text-inherit [transition-property:text-decoration-color,box-shadow] [&:not(:hover,:focus-visible)]:[--_text-link-line:color-mix(in_srgb,currentColor,transparent_35%)] cursor-pointer" data-cds="TextLink" data-inherit-color="" href="/docs/en/models/mythos-5/overview">Claude Mythos 5</a><button aria-expanded="false" aria-haspopup="dialog" aria-label="Claude Mythos 5 (Verification required)" class="-m-1 inline-flex shrink-0 cursor-help items-center justify-center rounded p-1 text-muted transition-colors duration-fast outline-none hover:text-secondary focus-visible:text-secondary focus-visible:shadow-focus data-[popup-open]:text-secondary" data-base-ui-click-trigger="" id="base-ui-_R_3shr8g9li9av5ul5u9fmbtdpl4plb_" tabindex="0" type="button"><span aria-hidden="true" data-cds="Icon" style="font-size:calc(1rem * var(--cds-rem-scale, 1));font-weight:533.3"></span></button></span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$10<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$12.50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$20<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$1<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><a class="cds-reset cds-text-link cds-text-link-underline inline text-inherit [transition-property:text-decoration-color,box-shadow] [&:not(:hover,:focus-visible)]:[--_text-link-line:color-mix(in_srgb,currentColor,transparent_35%)] cursor-pointer" data-cds="TextLink" data-inherit-color="" href="/docs/en/models/opus-5/overview">Claude Opus 5</a></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$5<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$25<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$6.25<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$10<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><a class="cds-reset cds-text-link cds-text-link-underline inline text-inherit [transition-property:text-decoration-color,box-shadow] [&:not(:hover,:focus-visible)]:[--_text-link-line:color-mix(in_srgb,currentColor,transparent_35%)] cursor-pointer" data-cds="TextLink" data-inherit-color="" href="/docs/en/models/opus-4-8/overview">Claude Opus 4.8</a></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$5<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$25<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$6.25<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$10<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><a class="cds-reset cds-text-link cds-text-link-underline inline text-inherit [transition-property:text-decoration-color,box-shadow] [&:not(:hover,:focus-visible)]:[--_text-link-line:color-mix(in_srgb,currentColor,transparent_35%)] cursor-pointer" data-cds="TextLink" data-inherit-color="" href="/docs/en/models/opus-4-7/overview">Claude Opus 4.7</a></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$5<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$25<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$6.25<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$10<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><a class="cds-reset cds-text-link cds-text-link-underline inline text-inherit [transition-property:text-decoration-color,box-shadow] [&:not(:hover,:focus-visible)]:[--_text-link-line:color-mix(in_srgb,currentColor,transparent_35%)] cursor-pointer" data-cds="TextLink" data-inherit-color="" href="/docs/en/models/opus-4-6/overview">Claude Opus 4.6</a></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$5<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$25<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$6.25<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$10<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><a class="cds-reset cds-text-link cds-text-link-underline inline text-inherit [transition-property:text-decoration-color,box-shadow] [&:not(:hover,:focus-visible)]:[--_text-link-line:color-mix(in_srgb,currentColor,transparent_35%)] cursor-pointer" data-cds="TextLink" data-inherit-color="" href="/docs/en/models/opus-4-5/overview">Claude Opus 4.5</a></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$5<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$25<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$6.25<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$10<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><span class="inline-flex items-center gap-xs">Claude Opus 4.1<button aria-expanded="false" aria-haspopup="dialog" aria-label="Claude Opus 4.1 (Retired)" class="-m-1 inline-flex shrink-0 cursor-help items-center justify-center rounded p-1 text-muted transition-colors duration-fast outline-none hover:text-secondary focus-visible:text-secondary focus-visible:shadow-focus data-[popup-open]:text-secondary" data-base-ui-click-trigger="" id="base-ui-_R_3skr8g9li9av5ul5u9fmbtdpl4plb_" tabindex="0" type="button"><span aria-hidden="true" data-cds="Icon" style="font-size:calc(1rem * var(--cds-rem-scale, 1));font-weight:533.3"></span></button></span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$15<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$75<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$18.75<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$30<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$1.50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><span class="inline-flex items-center gap-xs">Claude Opus 4<button aria-expanded="false" aria-haspopup="dialog" aria-label="Claude Opus 4 (Retired)" class="-m-1 inline-flex shrink-0 cursor-help items-center justify-center rounded p-1 text-muted transition-colors duration-fast outline-none hover:text-secondary focus-visible:text-secondary focus-visible:shadow-focus data-[popup-open]:text-secondary" data-base-ui-click-trigger="" id="base-ui-_R_3slb8g9li9av5ul5u9fmbtdpl4plb_" tabindex="0" type="button"><span aria-hidden="true" data-cds="Icon" style="font-size:calc(1rem * var(--cds-rem-scale, 1));font-weight:533.3"></span></button></span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$15<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$75<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$18.75<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$30<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$1.50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><a class="cds-reset cds-text-link cds-text-link-underline inline text-inherit [transition-property:text-decoration-color,box-shadow] [&:not(:hover,:focus-visible)]:[--_text-link-line:color-mix(in_srgb,currentColor,transparent_35%)] cursor-pointer" data-cds="TextLink" data-inherit-color="" href="/docs/en/models/sonnet-5/overview">Claude Sonnet 5</a></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap"><span class="scroll-mt-24" id="claude-sonnet-5-introductory-pricing"><button aria-expanded="false" aria-haspopup="dialog" class="inline cursor-help rounded-sm text-left underline decoration-dotted decoration-1 underline-offset-4 [text-decoration-color:color-mix(in_srgb,currentColor,transparent_55%)] focus-visible:shadow-focus focus-visible:outline-none print:contents" data-base-ui-click-trigger="" id="base-ui-_R_1sj5r8g9li9av5ul5u9fmbtdpl4plb_" tabindex="0" type="button">$2</button></span> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap"><button aria-expanded="false" aria-haspopup="dialog" class="inline cursor-help rounded-sm text-left underline decoration-dotted decoration-1 underline-offset-4 [text-decoration-color:color-mix(in_srgb,currentColor,transparent_55%)] focus-visible:shadow-focus focus-visible:outline-none print:contents" data-base-ui-click-trigger="" id="base-ui-_R_1sl5r8g9li9av5ul5u9fmbtdpl4plb_" tabindex="0" type="button">$10</button> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$2.50<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$4<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.20<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><a class="cds-reset cds-text-link cds-text-link-underline inline text-inherit [transition-property:text-decoration-color,box-shadow] [&:not(:hover,:focus-visible)]:[--_text-link-line:color-mix(in_srgb,currentColor,transparent_35%)] cursor-pointer" data-cds="TextLink" data-inherit-color="" href="/docs/en/models/sonnet-4-6/overview">Claude Sonnet 4.6</a></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$3<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$15<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$3.75<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$6<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.30<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><a class="cds-reset cds-text-link cds-text-link-underline inline text-inherit [transition-property:text-decoration-color,box-shadow] [&:not(:hover,:focus-visible)]:[--_text-link-line:color-mix(in_srgb,currentColor,transparent_35%)] cursor-pointer" data-cds="TextLink" data-inherit-color="" href="/docs/en/models/sonnet-4-5/overview">Claude Sonnet 4.5</a></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$3<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$15<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$3.75<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$6<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.30<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><span class="inline-flex items-center gap-xs">Claude Sonnet 4<button aria-expanded="false" aria-haspopup="dialog" aria-label="Claude Sonnet 4 (Retired)" class="-m-1 inline-flex shrink-0 cursor-help items-center justify-center rounded p-1 text-muted transition-colors duration-fast outline-none hover:text-secondary focus-visible:text-secondary focus-visible:shadow-focus data-[popup-open]:text-secondary" data-base-ui-click-trigger="" id="base-ui-_R_3snb8g9li9av5ul5u9fmbtdpl4plb_" tabindex="0" type="button"><span aria-hidden="true" data-cds="Icon" style="font-size:calc(1rem * var(--cds-rem-scale, 1));font-weight:533.3"></span></button></span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$3<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$15<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$3.75<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$6<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.30<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><a class="cds-reset cds-text-link cds-text-link-underline inline text-inherit [transition-property:text-decoration-color,box-shadow] [&:not(:hover,:focus-visible)]:[--_text-link-line:color-mix(in_srgb,currentColor,transparent_35%)] cursor-pointer" data-cds="TextLink" data-inherit-color="" href="/docs/en/models/haiku-4-5/overview">Claude Haiku 4.5</a></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$1<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$5<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$1.25<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$2<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.10<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td></tr><tr><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" rowspan="1"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden"><span class="inline-flex items-center gap-xs">Claude Haiku 3.5<button aria-expanded="false" aria-haspopup="dialog" aria-label="Claude Haiku 3.5 (Retired)" class="-m-1 inline-flex shrink-0 cursor-help items-center justify-center rounded p-1 text-muted transition-colors duration-fast outline-none hover:text-secondary focus-visible:text-secondary focus-visible:shadow-focus data-[popup-open]:text-secondary" data-base-ui-click-trigger="" id="base-ui-_R_3sob8g9li9av5ul5u9fmbtdpl4plb_" tabindex="0" type="button"><span aria-hidden="true" data-cds="Icon" style="font-size:calc(1rem * var(--cds-rem-scale, 1));font-weight:533.3"></span></button></span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.80<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$4<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle border-s not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$1<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$1.60<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td><td class="align-middle not-print:group-data-collapsed/rows:border-t-0 not-print:group-data-collapsed/rows:py-0 whitespace-nowrap [&_code]:whitespace-nowrap print:whitespace-normal print:[&_code]:whitespace-normal" style="padding-inline-end:calc(0.75em + var(--cds-pad-sm))"><div class="not-print:group-data-collapsed/rows:h-0 not-print:group-data-collapsed/rows:overflow-hidden print:whitespace-nowrap">$0.08<!-- --> <span class="text-footnote text-muted">/ MTok</span></div></td></tr></tbody></table>
|
|
4
|
+
</article></body></html>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Offline compile-command fixture: stdin prompt, stdout extraction JSON."""
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
prompt = sys.stdin.read()
|
|
9
|
+
payload = json.loads(prompt.split("INPUT JSON:\n", 1)[1])
|
|
10
|
+
counter = os.environ.get("STUB_CALL_LOG")
|
|
11
|
+
if counter:
|
|
12
|
+
with open(counter, "a") as stream:
|
|
13
|
+
stream.write(json.dumps(payload) + "\n")
|
|
14
|
+
mode = os.environ.get("STUB_MODE", "npm")
|
|
15
|
+
if mode == "fail":
|
|
16
|
+
print("not valid JSON")
|
|
17
|
+
elif mode == "pricing" and "embedded_json" in payload:
|
|
18
|
+
print('{"need_html":true}')
|
|
19
|
+
else:
|
|
20
|
+
filename = "pricing-schema.json" if mode == "pricing" else "npm-schema.json"
|
|
21
|
+
schema = json.loads((Path(__file__).parent / filename).read_text())
|
|
22
|
+
if mode == "broken" or mode == "refine" and not payload.get("validation_failures"):
|
|
23
|
+
schema["paths"]["license"] = "nonexistent.license"
|
|
24
|
+
print(json.dumps(schema))
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<!doctype html><html><head><title>react fixture</title></head><body>
|
|
2
|
+
<!-- Synthetic public-package shape, not a captured npm response. -->
|
|
3
|
+
<script>window.__context__ = {"context":{"packument":{"name":"react","dist-tags":{"latest":"19.2.0"}},"downloads":{"weeklyDownloads":42000000},"packageVersion":{"license":"MIT","repository":{"url":"git+https://github.com/facebook/react.git"}}}};</script>
|
|
4
|
+
<h1>react</h1></body></html>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "embedded_json",
|
|
3
|
+
"source": "__context__",
|
|
4
|
+
"rows": "context",
|
|
5
|
+
"paths": {
|
|
6
|
+
"name": "packument.name",
|
|
7
|
+
"latest_version": "packument.dist-tags.latest",
|
|
8
|
+
"weekly_downloads": "downloads.weeklyDownloads",
|
|
9
|
+
"license": "packageVersion.license",
|
|
10
|
+
"repository_url": "packageVersion.repository.url"
|
|
11
|
+
},
|
|
12
|
+
"required": ["name", "latest_version", "weekly_downloads", "license", "repository_url"],
|
|
13
|
+
"transforms": {"weekly_downloads": "number"}
|
|
14
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<!doctype html><html><head><title>zod fixture</title></head><body>
|
|
2
|
+
<!-- Synthetic public-package shape, not a captured npm response. -->
|
|
3
|
+
<script>window.__context__ = {"context":{"packument":{"name":"zod","dist-tags":{"latest":"4.1.12"}},"downloads":{"weeklyDownloads":33000000},"packageVersion":{"license":"MIT","repository":{"url":"git+https://github.com/colinhacks/zod.git"}}}};</script>
|
|
4
|
+
<h1>zod</h1></body></html>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "css",
|
|
3
|
+
"schema": {
|
|
4
|
+
"name": "claude_pricing",
|
|
5
|
+
"baseSelector": "#content-container table:has(colgroup[span=\"3\"]) > tbody > tr:has(td[rowspan]):not(:has(button[aria-label*=\"Retired\"]))",
|
|
6
|
+
"fields": [
|
|
7
|
+
{"name": "model", "selector": "td:nth-child(1)", "type": "text"},
|
|
8
|
+
{"name": "input", "selector": "td:nth-child(2)", "type": "text"},
|
|
9
|
+
{"name": "output", "selector": "td:nth-child(3)", "type": "text"},
|
|
10
|
+
{"name": "cache_write_5m", "selector": "td:nth-child(4)", "type": "text"},
|
|
11
|
+
{"name": "cache_write_1h", "selector": "td:nth-child(5)", "type": "text"},
|
|
12
|
+
{"name": "cache_read", "selector": "td:nth-child(6)", "type": "text"}
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
"required": ["model", "input", "output"],
|
|
16
|
+
"transforms": {
|
|
17
|
+
"model": {"regex": "(Claude\\s+\\w+\\s+\\d+(?:\\.\\d+)?)"},
|
|
18
|
+
"input": {"regex": "\\$([\\d.]+)", "number": true},
|
|
19
|
+
"output": {"regex": "\\$([\\d.]+)", "number": true},
|
|
20
|
+
"cache_write_5m": {"regex": "\\$([\\d.]+)", "number": true},
|
|
21
|
+
"cache_write_1h": {"regex": "\\$([\\d.]+)", "number": true},
|
|
22
|
+
"cache_read": {"regex": "\\$([\\d.]+)", "number": true}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Links-only search
|
|
2
|
+
|
|
3
|
+
SearXNG finds public URLs when the reading job starts without known links. The `searx` command prints titles, URLs and source engines. Pass those URLs to the reader or a batched reading job. Running your own instance avoids a paid search API.
|
|
4
|
+
|
|
5
|
+
## Run the instance
|
|
6
|
+
|
|
7
|
+
Install Docker yourself, then run:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
bash searxng/deploy.sh
|
|
11
|
+
searxng/searx 'public documentation'
|
|
12
|
+
searxng/searx 'public documentation' --json
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The container binds to `127.0.0.1:8888`. `SEARXNG_URL` selects another instance. The deployment script creates a private signing-secret file at `${XDG_CONFIG_HOME:-$HOME/.config}/lean-browser-use/searxng-secret.env`, pulls the pinned container, starts it and checks its health. It requires Docker Compose, OpenSSL and curl. The secret is never printed.
|
|
16
|
+
|
|
17
|
+
`--engines`, `--categories`, `--time`, `--lang`, `--page`, `--max-results` and `--timeout` narrow a query. The Python command uses the standard library. The container configuration keeps the limiter off for a private instance; add access controls before exposing it on a private network.
|
|
18
|
+
|
|
19
|
+
## Check the command
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
python3 -m unittest discover -s searxng -p 'test_*.py'
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Mocked responses work offline. Loopback server checks skip when the sandbox blocks local sockets.
|
|
26
|
+
|
|
27
|
+
## Licence
|
|
28
|
+
|
|
29
|
+
[SearXNG](https://github.com/searxng/searxng) is AGPL-3.0. This repository ships configuration and a container reference only; it does not bundle SearXNG code. The command and configuration in this repository use the repository's MIT licence.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Loopback binding keeps this private. To expose it deliberately, bind a private
|
|
2
|
+
# interface and add access controls for that network before starting the container.
|
|
3
|
+
name: searxng
|
|
4
|
+
|
|
5
|
+
services:
|
|
6
|
+
core:
|
|
7
|
+
container_name: searxng-core
|
|
8
|
+
image: docker.io/searxng/searxng:2026.10.19-81371861f
|
|
9
|
+
restart: unless-stopped
|
|
10
|
+
ports:
|
|
11
|
+
- "127.0.0.1:8888:8080"
|
|
12
|
+
environment:
|
|
13
|
+
SEARXNG_SECRET: ${SEARXNG_SECRET:?run through deploy.sh}
|
|
14
|
+
FORCE_OWNERSHIP: "false"
|
|
15
|
+
volumes:
|
|
16
|
+
- ./core-config/:/etc/searxng/:ro
|
|
17
|
+
- core-data:/var/cache/searxng/
|
|
18
|
+
mem_limit: 320m
|
|
19
|
+
|
|
20
|
+
volumes:
|
|
21
|
+
core-data:
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Private instance; the limiter is off. deploy.sh supplies the signing secret.
|
|
2
|
+
use_default_settings: true
|
|
3
|
+
|
|
4
|
+
general:
|
|
5
|
+
instance_name: "lean-searxng"
|
|
6
|
+
|
|
7
|
+
search:
|
|
8
|
+
safe_search: 0
|
|
9
|
+
formats:
|
|
10
|
+
- html
|
|
11
|
+
- json
|
|
12
|
+
|
|
13
|
+
server:
|
|
14
|
+
secret_key: "ultrasecretkey"
|
|
15
|
+
limiter: false
|
|
16
|
+
public_instance: false
|
|
17
|
+
image_proxy: false
|
|
18
|
+
|
|
19
|
+
outgoing:
|
|
20
|
+
request_timeout: 4.0
|
|
21
|
+
|
|
22
|
+
engines:
|
|
23
|
+
- name: bing
|
|
24
|
+
disabled: false
|
|
25
|
+
- name: yahoo
|
|
26
|
+
disabled: false
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Usage: bash searxng/deploy.sh
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
cd "$(dirname "$0")"
|
|
5
|
+
|
|
6
|
+
SECRET_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/lean-browser-use/searxng-secret.env"
|
|
7
|
+
mkdir -p "$(dirname "$SECRET_FILE")"
|
|
8
|
+
chmod 700 "$(dirname "$SECRET_FILE")"
|
|
9
|
+
if [ ! -f "$SECRET_FILE" ]; then
|
|
10
|
+
# A cookie-signing key only this container reads; generated here, never printed.
|
|
11
|
+
(umask 077; set -C; printf 'SEARXNG_SECRET=%s\n' "$(openssl rand -hex 32)" > "$SECRET_FILE") || [ -f "$SECRET_FILE" ]
|
|
12
|
+
fi
|
|
13
|
+
chmod 600 "$SECRET_FILE"
|
|
14
|
+
|
|
15
|
+
for _ in $(seq 1 30); do
|
|
16
|
+
[ -s "$SECRET_FILE" ] && break
|
|
17
|
+
sleep 0.1
|
|
18
|
+
done
|
|
19
|
+
if [ ! -s "$SECRET_FILE" ]; then
|
|
20
|
+
echo "searxng: secret file is empty" >&2
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
set -a; . "$SECRET_FILE"; set +a
|
|
25
|
+
docker compose pull --quiet
|
|
26
|
+
docker compose up -d
|
|
27
|
+
|
|
28
|
+
for _ in $(seq 1 30); do
|
|
29
|
+
if curl -fsS -o /dev/null "http://127.0.0.1:8888/healthz"; then
|
|
30
|
+
echo "searxng: healthy"
|
|
31
|
+
exit 0
|
|
32
|
+
fi
|
|
33
|
+
sleep 2
|
|
34
|
+
done
|
|
35
|
+
echo "searxng: not healthy after 60s; see: docker compose -f $PWD/compose.yml logs core" >&2
|
|
36
|
+
exit 1
|
package/searxng/searx
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Search a SearXNG instance for links.
|
|
3
|
+
|
|
4
|
+
Exit codes: 0 results, 1 empty results, 2 usage, 3 unreachable instance.
|
|
5
|
+
Set SEARXNG_URL to choose an instance; the default uses loopback.
|
|
6
|
+
"""
|
|
7
|
+
import argparse
|
|
8
|
+
import json
|
|
9
|
+
import os
|
|
10
|
+
import re
|
|
11
|
+
import sys
|
|
12
|
+
import urllib.error
|
|
13
|
+
import urllib.parse
|
|
14
|
+
import urllib.request
|
|
15
|
+
|
|
16
|
+
DEFAULT_URL = "http://127.0.0.1:8888"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def clean_text(value) -> str:
|
|
20
|
+
return re.sub(r"[\x00-\x1f\x7f-\x9f]", "", str(value))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def main() -> int:
|
|
24
|
+
p = argparse.ArgumentParser(prog="searx", description=__doc__.splitlines()[0])
|
|
25
|
+
p.add_argument("query")
|
|
26
|
+
p.add_argument("-n", "--max-results", type=int, default=10)
|
|
27
|
+
p.add_argument("--engines", help="comma-separated engine names")
|
|
28
|
+
p.add_argument("--categories", help="comma-separated, e.g. general,news,it")
|
|
29
|
+
p.add_argument("--time", choices=["day", "week", "month", "year"])
|
|
30
|
+
p.add_argument("--lang", default="auto")
|
|
31
|
+
p.add_argument("--page", type=int, default=1)
|
|
32
|
+
p.add_argument("--json", action="store_true", help="print the raw response")
|
|
33
|
+
p.add_argument("--timeout", type=float, default=20.0)
|
|
34
|
+
a = p.parse_args()
|
|
35
|
+
|
|
36
|
+
params = {"q": a.query, "format": "json", "language": a.lang, "pageno": a.page}
|
|
37
|
+
if a.engines:
|
|
38
|
+
params["engines"] = a.engines
|
|
39
|
+
if a.categories:
|
|
40
|
+
params["categories"] = a.categories
|
|
41
|
+
if a.time:
|
|
42
|
+
params["time_range"] = a.time
|
|
43
|
+
|
|
44
|
+
base = os.environ.get("SEARXNG_URL", DEFAULT_URL).rstrip("/")
|
|
45
|
+
url = f"{base}/search?{urllib.parse.urlencode(params)}"
|
|
46
|
+
req = urllib.request.Request(url, headers={"User-Agent": "searx-cli/1"})
|
|
47
|
+
try:
|
|
48
|
+
with urllib.request.urlopen(req, timeout=a.timeout) as r:
|
|
49
|
+
data = json.load(r)
|
|
50
|
+
if (not isinstance(data, dict)
|
|
51
|
+
or not isinstance(data.get("results"), list)
|
|
52
|
+
or not all(isinstance(result, dict) for result in data["results"])):
|
|
53
|
+
raise ValueError("expected an object with a list of object results")
|
|
54
|
+
except (urllib.error.URLError, TimeoutError, ValueError) as e:
|
|
55
|
+
print(f"searx: {base} unreachable or bad response: {e}", file=sys.stderr)
|
|
56
|
+
return 3
|
|
57
|
+
|
|
58
|
+
results = data.get("results", [])[: a.max_results]
|
|
59
|
+
if a.json:
|
|
60
|
+
data["results"] = results
|
|
61
|
+
json.dump(data, sys.stdout, indent=2)
|
|
62
|
+
print()
|
|
63
|
+
else:
|
|
64
|
+
for i, r in enumerate(results, 1):
|
|
65
|
+
engines = ",".join(clean_text(eng) for eng in r.get("engines", []))
|
|
66
|
+
print(f"{i}. {clean_text(r.get('title', '')).strip()}\n {clean_text(r.get('url'))}\n [{engines}] {clean_text(r.get('publishedDate') or '')}".rstrip())
|
|
67
|
+
for eng, why in data.get("unresponsive_engines", []):
|
|
68
|
+
print(f"unresponsive: {clean_text(eng)} ({clean_text(why)})", file=sys.stderr)
|
|
69
|
+
return 0 if results else 1
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
if __name__ == "__main__":
|
|
73
|
+
sys.exit(main())
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Loopback-only regression tests for the searx CLI."""
|
|
3
|
+
import http.server
|
|
4
|
+
import json
|
|
5
|
+
import os
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
import subprocess
|
|
8
|
+
import sys
|
|
9
|
+
import threading
|
|
10
|
+
import unittest
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Handler(http.server.BaseHTTPRequestHandler):
|
|
14
|
+
def do_GET(self):
|
|
15
|
+
body = json.dumps(self.server.response).encode()
|
|
16
|
+
self.send_response(200)
|
|
17
|
+
self.send_header("Content-Type", "application/json")
|
|
18
|
+
self.send_header("Content-Length", str(len(body)))
|
|
19
|
+
self.end_headers()
|
|
20
|
+
self.wfile.write(body)
|
|
21
|
+
|
|
22
|
+
def log_message(self, *args):
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class SearxTests(unittest.TestCase):
|
|
27
|
+
@classmethod
|
|
28
|
+
def setUpClass(cls):
|
|
29
|
+
try:
|
|
30
|
+
cls.server = http.server.HTTPServer(("127.0.0.1", 0), Handler)
|
|
31
|
+
except PermissionError:
|
|
32
|
+
raise unittest.SkipTest("sandbox blocks local sockets; mocked search tests still run")
|
|
33
|
+
cls.thread = threading.Thread(target=cls.server.serve_forever)
|
|
34
|
+
cls.thread.start()
|
|
35
|
+
|
|
36
|
+
@classmethod
|
|
37
|
+
def tearDownClass(cls):
|
|
38
|
+
cls.server.shutdown()
|
|
39
|
+
cls.thread.join()
|
|
40
|
+
cls.server.server_close()
|
|
41
|
+
|
|
42
|
+
def run_searx(self, body, *args):
|
|
43
|
+
self.server.response = body
|
|
44
|
+
env = {**os.environ,
|
|
45
|
+
"SEARXNG_URL": f"http://127.0.0.1:{self.server.server_port}",
|
|
46
|
+
"NO_PROXY": "127.0.0.1", "no_proxy": "127.0.0.1",
|
|
47
|
+
"PYTHONIOENCODING": "utf-8"}
|
|
48
|
+
return subprocess.run(
|
|
49
|
+
[sys.executable, str(Path(__file__).with_name("searx")), "test", *args],
|
|
50
|
+
env=env, capture_output=True, timeout=5)
|
|
51
|
+
|
|
52
|
+
def test_control_characters_in_all_text_fields(self):
|
|
53
|
+
controls = "".join(chr(i) for i in (*range(32), *range(127, 160)))
|
|
54
|
+
result = self.run_searx({
|
|
55
|
+
"results": [{"title": "Title\x1b[2J" + controls,
|
|
56
|
+
"url": "https://example.test/" + controls,
|
|
57
|
+
"engines": ["engine" + controls],
|
|
58
|
+
"publishedDate": "today" + controls}],
|
|
59
|
+
"unresponsive_engines": [["failed" + controls, "reason" + controls]],
|
|
60
|
+
})
|
|
61
|
+
self.assertEqual(result.returncode, 0, result.stderr)
|
|
62
|
+
self.assertNotIn(b"\x1b", result.stdout + result.stderr)
|
|
63
|
+
self.assertEqual(result.stdout.decode(),
|
|
64
|
+
"1. Title[2J\n https://example.test/\n [engine] today\n")
|
|
65
|
+
self.assertEqual(result.stderr, b"unresponsive: failed (reason)\n")
|
|
66
|
+
|
|
67
|
+
def test_bad_response_shapes(self):
|
|
68
|
+
for body in ([], "x", None, 1, {}, {"results": None},
|
|
69
|
+
{"results": {}}, {"results": "x"},
|
|
70
|
+
{"results": [None]}, {"results": [{}] * 10 + ["x"]}):
|
|
71
|
+
for args in ((), ("--json",)):
|
|
72
|
+
with self.subTest(body=body, args=args):
|
|
73
|
+
result = self.run_searx(body, *args)
|
|
74
|
+
self.assertEqual(result.returncode, 3, result.stderr)
|
|
75
|
+
self.assertIn(b"unreachable or bad response", result.stderr)
|
|
76
|
+
self.assertNotIn(b"Traceback", result.stderr)
|
|
77
|
+
self.assertEqual(result.stdout, b"")
|
|
78
|
+
|
|
79
|
+
def test_single_result(self):
|
|
80
|
+
result = self.run_searx({"results": [{"title": "Title",
|
|
81
|
+
"url": "https://example.test/",
|
|
82
|
+
"engines": ["engine"]}]})
|
|
83
|
+
self.assertEqual(result.returncode, 0, result.stderr)
|
|
84
|
+
self.assertEqual(result.stdout,
|
|
85
|
+
b"1. Title\n https://example.test/\n [engine]\n")
|
|
86
|
+
self.assertEqual(result.stderr, b"")
|
|
87
|
+
|
|
88
|
+
def test_json_preserves_data_and_result_limit(self):
|
|
89
|
+
controls = "\x00\x1b\x7f\x85\x9f"
|
|
90
|
+
item = {"title": controls, "url": controls, "engines": [controls],
|
|
91
|
+
"publishedDate": controls}
|
|
92
|
+
body = {"results": [item, item], "unresponsive_engines": [[controls, controls]]}
|
|
93
|
+
result = self.run_searx(body, "--json", "-n", "1")
|
|
94
|
+
self.assertEqual(result.returncode, 0, result.stderr)
|
|
95
|
+
expected = {**body, "results": [item]}
|
|
96
|
+
self.assertEqual(result.stdout.decode(), json.dumps(expected, indent=2) + "\n")
|
|
97
|
+
self.assertEqual(result.stderr, b"")
|
|
98
|
+
|
|
99
|
+
def test_empty_results(self):
|
|
100
|
+
result = self.run_searx({"results": []})
|
|
101
|
+
self.assertEqual(result.returncode, 1, result.stderr)
|
|
102
|
+
self.assertEqual(result.stdout, b"")
|
|
103
|
+
self.assertEqual(result.stderr, b"")
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
if __name__ == "__main__":
|
|
107
|
+
unittest.main()
|