@flattype/models 1.6.0 → 1.7.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.
Files changed (2) hide show
  1. package/README.md +58 -1
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -20,6 +20,7 @@
20
20
  <a href="https://www.npmjs.com/package/@flattype/vue"><img src="https://img.shields.io/npm/v/@flattype/vue?label=%40flattype%2Fvue&color=8b6cff" alt="npm @flattype/vue"></a>
21
21
  <a href="https://www.npmjs.com/package/@flattype/angular"><img src="https://img.shields.io/npm/v/@flattype/angular?label=%40flattype%2Fangular&color=8b6cff" alt="npm @flattype/angular"></a>
22
22
  <a href="https://www.npmjs.com/package/@flattype/svelte"><img src="https://img.shields.io/npm/v/@flattype/svelte?label=%40flattype%2Fsvelte&color=8b6cff" alt="npm @flattype/svelte"></a>
23
+ <a href="https://www.npmjs.com/package/@flattype/ai"><img src="https://img.shields.io/npm/v/@flattype/ai?label=%40flattype%2Fai&color=8b6cff" alt="npm @flattype/ai"></a>
23
24
  <a href="https://github.com/karammm/flattype/actions/workflows/ci.yml"><img src="https://github.com/karammm/flattype/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
24
25
  <img src="https://img.shields.io/badge/core-3.7_KB_min%2Bgz-2fd4b2" alt="3.7 KB min+gz">
25
26
  <img src="https://img.shields.io/badge/dependencies-0-2fd4b2" alt="No third-party dependencies">
@@ -35,6 +36,7 @@
35
36
  <a href="#vue"><b>Vue</b></a> ·
36
37
  <a href="#angular"><b>Angular</b></a> ·
37
38
  <a href="#svelte-and-solid"><b>Svelte &amp; Solid</b></a> ·
39
+ <a href="#claude-and-llms"><b>Claude &amp; LLMs</b></a> ·
38
40
  <a href="#benchmarks"><b>Benchmarks</b></a> ·
39
41
  <a href="https://github.com/karammm/flattype/blob/main/CHANGELOG.md"><b>Changelog</b></a> ·
40
42
  <a href="https://github.com/karammm/flattype/blob/main/ROADMAP.md"><b>Roadmap</b></a>
@@ -140,9 +142,10 @@ const [users] = createFlatResource(() => "/api/users", { model: User, list: true
140
142
  | [`@flattype/vue`](https://github.com/karammm/flattype/blob/main/packages/vue) | The same composables for Vue 3, with reactive URLs, plus the `createFlat()` plugin | +1.2 KB |
141
143
  | [`@flattype/angular`](https://github.com/karammm/flattype/blob/main/packages/angular) | `flatInterceptor` for HttpClient, the signal-based `flatResource` / `flatStream`, the `flatModel` pipe | +1.8 KB |
142
144
  | [`@flattype/svelte`](https://github.com/karammm/flattype/blob/main/packages/svelte) | Svelte stores (`flatStore`, `flatStreamStore`, `modelStore`), and `/solid` with `createFlatResource` / `createFlatStream` | +1.1 KB / +0.9 KB |
145
+ | [`@flattype/ai`](https://github.com/karammm/flattype/blob/main/packages/ai) | `toPrompt`, `fromModelOutput`, `countTokens`, and MCP / Claude tool results | +1.3 KB |
143
146
  | [`@flattype/shared`](https://github.com/karammm/flattype/blob/main/packages/shared) | Shared TypeScript types | types only |
144
147
 
145
- Claude helpers and a CLI are planned. See the [roadmap](https://github.com/karammm/flattype/blob/main/ROADMAP.md).
148
+ A CLI with code generation is planned. See the [roadmap](https://github.com/karammm/flattype/blob/main/ROADMAP.md).
146
149
 
147
150
  ## The format
148
151
 
@@ -436,6 +439,60 @@ const events = createFlatStream(() => "/api/export", { model: Row, table: "rows"
436
439
 
437
440
  The stores also work in Solid, or anywhere else, through the store contract: `from(flatStore(...))`. Runnable apps with Playwright tests in three browsers are in [`examples/svelte-app`](https://github.com/karammm/flattype/blob/main/examples/svelte-app) and [`examples/solid-app`](https://github.com/karammm/flattype/blob/main/examples/solid-app).
438
441
 
442
+ ## Claude and LLMs
443
+
444
+ ```bash
445
+ npm install @flattype/ai
446
+ ```
447
+
448
+ ```ts
449
+ import Anthropic from "@anthropic-ai/sdk";
450
+ import { countTokens, fromModelOutput, outputInstructions, toPrompt } from "@flattype/ai";
451
+
452
+ const client = new Anthropic();
453
+
454
+ // 1. Data in: Flat Notation inside <data> tags, with a one-line legend the model reads once.
455
+ const response = await client.beta.messages.create({
456
+ model: "claude-opus-5-5",
457
+ max_tokens: 16000,
458
+ betas: ["server-side-fallback-2026-07-01"],
459
+ fallbacks: "default", // if a safety classifier declines, retry on the recommended fallback model
460
+ messages: [{
461
+ role: "user",
462
+ content: `${toPrompt(orders, { name: "orders" })}\n\nTotal spent per customer?\n\n${outputInstructions([{ customer: "Alice", spent: 120 }])}`,
463
+ }],
464
+ });
465
+
466
+ // 2. Data out: tolerant of tags, fences, prose and JSON, then validated into typed models.
467
+ const reply = response.content.filter((b) => b.type === "text").map((b) => b.text).join("\n");
468
+ const totals = fromModelOutput(reply, { model: Total, list: true }); // Total[]
469
+
470
+ // 3. Measure it with Claude's own tokenizer (count_tokens is free).
471
+ const { json, flat, saved } = await countTokens(client, orders);
472
+ ```
473
+
474
+ **Tool results** shrink too, which matters most for agents that call tools over and over:
475
+
476
+ ```ts
477
+ import { claudeToolResult, toolResult } from "@flattype/ai";
478
+
479
+ // MCP server (@modelcontextprotocol/sdk): returns a CallToolResult with Flat Notation text
480
+ server.registerTool("list_orders", { description: "…" }, async () => toolResult(await db.orders()));
481
+
482
+ // Claude API tool loop: a tool_result block for the next user message
483
+ messages.push({ role: "user", content: [claudeToolResult(toolUse.id, await runTool(toolUse))] });
484
+ ```
485
+
486
+ | API | What it does |
487
+ | --- | --- |
488
+ | `toPrompt(data, { name, legend })` | `<data format="flat-notation">` plus a one-line legend. The block is still valid Flat Notation; put the legend in your system prompt once with `legend: false` |
489
+ | `outputInstructions(example)` | Asks the model to answer in Flat Notation and shows the exact shape you expect |
490
+ | `fromModelOutput(reply, { model, list })` | Finds the data (last `<data>` block, code fence, or the text itself), skips prose lines, and accepts JSON too |
491
+ | `countTokens(client, data, { model })` | `{ json, flat, saved }` in real Claude tokens, minus per-message overhead. Takes any client with `messages.countTokens` |
492
+ | `toolResult(data, { structured })` / `claudeToolResult(id, data)` | MCP `CallToolResult` and Claude API `tool_result` blocks |
493
+
494
+ See [`examples/ai-claude`](https://github.com/karammm/flattype/blob/main/examples/ai-claude) for a token report, a full Claude round trip, and a runnable MCP server (`claude mcp add flattype-orders -- node mcp-server.mjs`).
495
+
439
496
  ## Benchmarks
440
497
 
441
498
  `pnpm compare` on the fixtures in [`fixtures/`](https://github.com/karammm/flattype/blob/main/fixtures/index.mjs) (Node 24, Apple Silicon):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flattype/models",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "Typed models for API data: key mapping, coercion and defaults, from JSON or Flat Notation.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -33,8 +33,8 @@
33
33
  "flattype"
34
34
  ],
35
35
  "dependencies": {
36
- "@flattype/core": "1.6.0",
37
- "@flattype/shared": "1.6.0"
36
+ "@flattype/core": "1.7.0",
37
+ "@flattype/shared": "1.7.0"
38
38
  },
39
39
  "publishConfig": {
40
40
  "access": "public"