Skip to content

feat: add Clairic extraction beside keyed decisions - #32

Closed
TheGreatAxios wants to merge 3 commits into
cl-11530-match-the-typesafe-sdk-question-and-image-apifrom
cl-11531-add-clairic-extraction-beside-system-one-decisions
Closed

TheGreatAxios wants to merge 3 commits into
cl-11530-match-the-typesafe-sdk-question-and-image-apifrom
cl-11531-add-clairic-extraction-beside-system-one-decisions

Conversation

@TheGreatAxios

Copy link
Copy Markdown
Contributor

Summary

  • Add @corbits/system-one/extraction with extract() and field helpers text, date, number, list, and estimate.
  • extract calls Cloudflare Workers AI Clairic. It does not call the Jev endpoint. Missing credentials and bad responses are a fallback, not a throw.
  • A number field is a type error in a decision, and a choice is a type error in an extraction. The root package does not re-export the extraction helpers.

Verification

  • bun run check exited 0 (45 tests).
  • Review of 6cef41a found no defects. tsc --noEmit confirms the @ts-expect-error lines are real.

Stacked on #31.

Fixes CL-11531

@linear-code

linear-code Bot commented Oct 26, 2026

Copy link
Copy Markdown

CL-11531

@corbits-triage

corbits-triage Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Triage: Pass

No changes needed from you. A maintainer will review this pull request.

@TheGreatAxios TheGreatAxios left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review · Request changes

Adds Clairic extraction beside the keyed decisions API. The decisions generic bound does not change keyed runtime behavior.

Findings

  • src/extraction.ts:166 — textAnswer only reads start / end or offsets.start / offsets.end. A documented text answer { type: "text", value: "INV-2291", span: [8, 16], confidence: 1 } comes back as { value: "INV-2291" } with no offsets, including when wrapped in the Workers AI { result } envelope. src/extraction.test.ts locks the invented shape, so it cannot catch this. A temporary test failed on that sample.

  • src/extraction.ts:217 — estimateAnswer looks for a nested interval. The documented estimate is { type: "estimate", value: 30, median: 30, p10: 21, p90: 38 } with p10 / p90 as siblings. The same probe got median: 30 and interval: undefined, so the 80% interval is dropped.

  • src/extraction.ts:197 — list("number") is accepted (text | number | date), but AnswerOf types the value as string[] | null and the parser keeps only typeof item === "string". { type: "list", value: [250, 80] } becomes [].

  • src/extraction.ts:155 — a text answer whose value is not a string, { type: "text", value: 1080 }, is mapped to { value: null } and answersOf still returns success. That is indistinguishable from a real null. The response is also cast with as ExtractionAnswers instead of being checked.

decisions.ts only tightens the input generic. tsc --noEmit on choice, noul, score, and box narrowing exited 0. Omitted kinds (time, datetime, duration, forecast), images, reference_date, integer, and scale were treated as an intentional subset.

Commit 3ceb3b8 is Merge the keyed-decisions polish into the extraction branch. That subject has a trailing period and no type. A conventional subject under 72 characters would be easier for triage to accept.

@TheGreatAxios

Copy link
Copy Markdown
Contributor Author

Review · Follow-up

Commit 7adcdb6 is clean.

Text span: [8, 16] becomes start/end, including inside a { result } envelope. Sibling estimate p10/p90 fill interval. list("number") returns [250, 80], and a number list is number[] | null. { type: "text", value: 1080 } is fallback: true / parse-error, not a successful null. The as ExtractionAnswers cast is gone.

bun test src/extraction.test.ts exited 0 (5 pass). A deleted probe of the published Clairic body also passed.

This was referenced Oct 27, 2026
@TheGreatAxios

Copy link
Copy Markdown
Contributor Author

Stacked into the 0.4.0 release: #34

This pull is included in that release and must not also be merged. Landing #34 is the only merge into main. Do not close this pull yet.

@TheGreatAxios

Copy link
Copy Markdown
Contributor Author

Superseded by the 0.4.0 release, which is merged: #34

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant