Skip to content

Add Keenable as an opt-in keyless web provider - #450

Merged
chayapats merged 2 commits into
mainfrom
jit/449-keenable-provider
Nov 8, 2026
Merged

chayapats merged 2 commits into
mainfrom
jit/449-keenable-provider

Conversation

@chayapats

Copy link
Copy Markdown
Owner

Implements #449. Keenable becomes a selectable keyless search/fetch provider next to Parallel; Parallel stays the default and nothing changes unless the owner switches in Settings > Web research.

What changed

  • New src/s14/keenable-protocol.ts: KeenableSearch client returning the same ParallelResult, over POST /v1/search/public and GET /v1/fetch/public with a fixed X-Keenable-Title: Jit header. One request per read, no key, no session id, no model name. Reuses publicOutbound/publicWebUrl, ParallelFailure, the byte cap and Retry-After parsing.
  • src/s14/parallel.ts + parallel-types.ts: web.parallel.configure takes an optional provider (parallel | keenable), allowed only in anonymous mode so a saved Parallel key never reaches Keenable. read() picks the client; authority checks, outbound guard, deadline, output caps, evidence and citations are unchanged. Quota fencing is scoped per provider and a 429 never falls back to the other provider or a key. Absent provider means Parallel, so no migration.
  • Settings page: collapsed Search provider (optional) card below the account section; keyed mode shows a note that switching needs the free mode first.
  • Provider-neutral copy (1B): settings, evidence, setup note, lifecycle gains, model tool descriptions and the research system prompt render per the selected provider (new _keenable en/th strings; Parallel strings unchanged as defaults).
  • ADR 0047: short Keenable opt-in section. Keyed Keenable mode stays out of scope.

Test notes

  • New tests/s14-keenable.test.ts (7 tests, deterministic, no network): titled keyless search/fetch shape, excerpt vs full_content labels, fetch 404 to partial + not_found, 429 retry deadline + per-provider fencing, keyed-mode refusal + key isolation, oversize fails closed.
  • Regression: tests/s14-parallel.test.ts + tests/s14-web-memory.test.ts (105 pass), acceptance/evidence/web-ui (58 pass), web-tools/input-evidence/adoption-web (107 pass).
  • Typecheck clean (tsc --noEmit; needs GOMAXPROCS=1 GOGC=20 under a 2 GB container limit), git diff --check clean.
  • Live run from this machine through the real gateway: web_search returned 5 results in ~1.1 s, web_fetch returned the example page with excerpt coverage.

Closes #449

New KeenableSearch client returns the same normalized result over POST /v1/search/public and GET /v1/fetch/public with a fixed X-Keenable-Title header and no key, session or model. web.parallel.configure takes an optional provider allowed only in anonymous mode, quota fencing is scoped per provider, and settings/evidence/setup/lifecycle copy renders per the selected provider with Parallel as the default.
@greptile-apps

greptile-apps Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; all previous findings are fixed and no new blocking issues were found.

Summary

Adds Keenable as an owner-selected, keyless web provider while keeping Parallel as the default.

  • Keenable handles public web searches and page reads without a key.
  • Web research settings and evidence show the selected provider.

Reviews (2) · Last reviewed commit: "fix(s14): address Keenable review findin..." · Reviewed by Greptile

Comment thread src/s14/keenable-protocol.ts Resolved
Comment thread src/s14/keenable-protocol.ts Resolved
Comment thread src/s14/keenable-protocol.ts Resolved
Comment thread src/i18n/en.ts Resolved
Comment thread src/s14/web-research.ts Resolved
- Read Keenable bodies in chunks and cancel the stream once the byte cap
  is passed instead of buffering the whole response first.
- Keep description-only fetches labelled as excerpts and mark an unmet
  full-content request partial.
- Keep the requested URL in missing when Keenable returns a different page.
- Add the five Keenable settings strings to the Thai dictionary so both
  dictionaries define the same keys (fixes typecheck and i18n test).
- Share provider-aware outcome titles with the Progress notice; only quota
  names the provider, schema/service titles stay neutral.
- Regression tests for each finding; ADR 0047 notes the rules.
@chayapats

Copy link
Copy Markdown
Owner Author

@greptileai

@chayapats
chayapats merged commit fc2b599 into main Nov 8, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proposal: Keenable as an opt-in keyless web provider next to Parallel

1 participant