Skip to content

feat(query): add @aeye/query — LLM-friendly query language, runtime &…#180

Open
ClickerMonkey wants to merge 7 commits into
mainfrom
feat/aeye-query
Open

feat(query): add @aeye/query — LLM-friendly query language, runtime &…#180
ClickerMonkey wants to merge 7 commits into
mainfrom
feat/aeye-query

Conversation

@ClickerMonkey

Copy link
Copy Markdown
Owner

… SQL converter

New standalone package (packages/query):

  • Types/fields meta-model + class-based Expr system (one file per kind, Registry dispatch)
  • Relation-based joins, params, per-FieldType filters, functions (scalar/tabular/aggregate/window), array field type
  • In-memory runtime + base & postgres SQL converter (RLS/FLS, computed-field backing, named joins/LATERAL, three-valued NULL logic)
  • Dev-side Type backing (Access/Computed) so the conceptual model stays simple while fields map to columns/SQL/runtime fns
  • Graduated per-axis LLM schema depth + capability gating; strict/typed-args schemas
  • Transforms (drill-down, auto-paginate), cost estimation, type-from-data util
  • Examples folder + interactive CLI; README

100% test coverage (932 tests, base+postgres SQL + runtime), 0 typecheck errors, no any/unknown/casts. Wires packages/query into the workspace (root package.json, tsconfig.base.json).

Claude-Session: https://claude.ai/code/session_012aWFXmP2zN1wnX43EwRjBS

ClickerMonkey and others added 7 commits July 1, 2026 20:17
… SQL converter

New standalone package (packages/query):
- Types/fields meta-model + class-based Expr system (one file per kind, Registry dispatch)
- Relation-based joins, params, per-FieldType filters, functions (scalar/tabular/aggregate/window), array field type
- In-memory runtime + base & postgres SQL converter (RLS/FLS, computed-field backing, named joins/LATERAL, three-valued NULL logic)
- Dev-side Type backing (Access/Computed) so the conceptual model stays simple while fields map to columns/SQL/runtime fns
- Graduated per-axis LLM schema depth + capability gating; strict/typed-args schemas
- Transforms (drill-down, auto-paginate), cost estimation, type-from-data util
- Examples folder + interactive CLI; README

100% test coverage (932 tests, base+postgres SQL + runtime), 0 typecheck errors, no any/unknown/casts.
Wires packages/query into the workspace (root package.json, tsconfig.base.json).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aWFXmP2zN1wnX43EwRjBS
…GROUP BY / ORDER BY / HAVING

`{ kind:'output', name }` delegates to the referenced select item's expression
(looked up by its `as` / natural name): expands to portable SQL (base+postgres)
and re-evaluates correctly at runtime (group keys over the source row; ORDER BY /
HAVING over the group, incl. aggregate targets). Offered by the LLM schema only
in groupBy/orderBy/having positions (gated out of the general Expr union), with
output.unknown / output.aggregate / output.not-available validation and drill-down
expansion. README "Output references" section. 100% coverage maintained (960 tests).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aWFXmP2zN1wnX43EwRjBS
…generic

Tool and Prompt gain an optional `parse` that fully REPLACES Zod validation
(JSON.parse → parse → validate), so a caller can decode raw args into a built
domain object and return rich compiler-style errors instead of Zod's. When
`parse` is supplied its RETURN TYPE drives a new appended-last `TDecoded`
generic (default = the wire type) that types call/validate/metadataFn and the
structured-output value — the handler receives the decoded value with no cast.
Backward-compatible: absent `parse` ⇒ identical Zod behavior. Docs + guides +
reference updated to the 7-param signatures.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aWFXmP2zN1wnX43EwRjBS
AIToolInput/AIPromptInput and the AI.tool()/AI.prompt() factories carry a
trailing TDecoded generic (appended-last-with-default) so a custom parse's
return type surfaces through the convenience layer; all existing callers
compile unchanged. Also fixes a pre-existing parse-ctx hydration/contravariance
mismatch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aWFXmP2zN1wnX43EwRjBS
…lf-describing, core Tool wiring

- Cross-type semantic pairing (bound-source query form) + numeric text-score
  (ts_rank); "top N by similarity/relevance" via ORDER BY score DESC LIMIT N.
- Function library expanded to 60+ (date/array/scalar/agg/window), renamed
  camelCase, per-dialect SQL (postgres native, base ANSI/degrade); an inline
  raw-literal arg mechanism for date-field selectors.
- e.* expression builder (returns real Expr instances; engine.evaluateExpr /
  exprToSQL; parseExpr passes an already-built Expr through).
- Search/semantic backing (hidden tsvector/pgvector vectorField) + backing
  alias-correctness (run factories receive the bound alias).
- `output` expr (reference a SELECT field in groupBy/orderBy/having); filters
  teardown of the op/clause machinery + query.filters() introspection.
- Self-describing: FunctionDef.instructions + static Expr INSTRUCTIONS +
  describeExprs/describeEngine + generated Type/Field descriptions; the CLI
  prompt is fully informed from the live engine.
- buildQueryTool returns a wired @aeye/core Tool (custom parse → built Query /
  QueryToolError, bypassing Zod).
- Cost-estimation accuracy (join fan-out + per-outer-row subquery multiplication).
- New aeye-query.md (LLM-facing) + README; 100% coverage gate (vitest+v8).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aWFXmP2zN1wnX43EwRjBS
A custom `parse` can decode raw args into ANY value (a number, Date, array,
boolean, class instance, …), not just object/string — so `TDecoded`'s
constraint on Tool/Prompt and the ai.tool()/ai.prompt() wrappers is now
`extends unknown` (defaults = the wire type, unchanged). Component's `TInput`
is widened to match, since a component's input IS the decoded value. No runtime
change and no new casts (the existing wire-fallback bridge stayed valid). Tests
prove a primitive `parse` return (e.g. `() => 42`) types the handler input as
`number` end-to-end through Tool.parse, Prompt structured output, and the ai
wrappers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aWFXmP2zN1wnX43EwRjBS
…te + field exprs/default)

Types declare insertable?/updatable?/deletable? (default true); fields declare
insertable?/updatable? and exprs?: {not|only} (narrow which expr kinds may
target them, bounded by the field type). FieldBacking.default (value or factory)
makes a field optional-on-insert and materializes it at runtime — no hasDefault;
a computed field defaults to non-insertable/updatable.

Enforced in BOTH layers: validation (insert/update/delete type+field readonly,
the insert-requiredness rule, field.expr-denied at direct-subject + operator
sites) AND schema-building (drop insert/update/delete kinds when no permitted
Type; filter into/type/from enums; paired-mode required-vs-optional insert
fields and updatable-only set; expr operand field enums honor not/only +
capability-gate a kind away when all fields exclude it). Runtime materializes
defaults (value/sync/async); describe surfaces the write-model tersely so the
self-describing prompt reflects it. aeye-query.md + README + 26 tests; 100%
coverage gate held.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aWFXmP2zN1wnX43EwRjBS
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.

1 participant