jev-recipes 0.0.1 → 0.0.4

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 (56) hide show
  1. package/CHANGELOG.md +7 -2
  2. package/README.md +95 -105
  3. package/dist/catalog/index.d.ts +211 -0
  4. package/dist/catalog/index.js +31 -0
  5. package/dist/catalog/recipes.d.ts +351 -0
  6. package/dist/catalog/recipes.js +50 -0
  7. package/dist/catalog/schema.d.ts +19 -0
  8. package/dist/catalog/schema.js +9 -0
  9. package/dist/cli/index.js +32 -16
  10. package/dist/cli/schema.d.ts +23 -8
  11. package/dist/cli/schema.js +10 -10
  12. package/dist/examples/support/index.d.ts +1 -0
  13. package/dist/examples/support/index.js +37 -0
  14. package/dist/examples/support/schema.d.ts +566 -0
  15. package/dist/examples/support/schema.js +76 -0
  16. package/dist/examples/support/workflow.d.ts +3 -0
  17. package/dist/examples/support/workflow.js +85 -0
  18. package/dist/recipes/answerability/index.d.ts +5 -0
  19. package/dist/recipes/answerability/index.js +32 -0
  20. package/dist/recipes/answerability/metadata.d.ts +8 -0
  21. package/dist/recipes/answerability/metadata.js +11 -0
  22. package/dist/recipes/answerability/schema.d.ts +47 -0
  23. package/dist/recipes/answerability/schema.js +25 -0
  24. package/dist/recipes/clarify/index.d.ts +5 -0
  25. package/dist/recipes/clarify/index.js +46 -0
  26. package/dist/recipes/clarify/metadata.d.ts +8 -0
  27. package/dist/recipes/clarify/metadata.js +11 -0
  28. package/dist/recipes/clarify/schema.d.ts +55 -0
  29. package/dist/recipes/clarify/schema.js +27 -0
  30. package/dist/recipes/handoff/index.d.ts +5 -0
  31. package/dist/recipes/handoff/index.js +50 -0
  32. package/dist/recipes/handoff/metadata.d.ts +8 -0
  33. package/dist/recipes/handoff/metadata.js +11 -0
  34. package/dist/recipes/handoff/schema.d.ts +59 -0
  35. package/dist/recipes/handoff/schema.js +27 -0
  36. package/dist/recipes/rerank/metadata.d.ts +8 -0
  37. package/dist/recipes/rerank/metadata.js +11 -0
  38. package/dist/recipes/route/metadata.d.ts +8 -0
  39. package/dist/recipes/route/metadata.js +11 -0
  40. package/dist/recipes/verify/metadata.d.ts +8 -0
  41. package/dist/recipes/verify/metadata.js +11 -0
  42. package/dist/src/index.d.ts +8 -0
  43. package/dist/src/index.js +4 -0
  44. package/dist/src/schema.d.ts +19 -0
  45. package/dist/src/schema.js +9 -0
  46. package/examples/support/README.md +60 -0
  47. package/examples/support/demo.json +156 -0
  48. package/package.json +26 -7
  49. package/recipes/answerability/README.md +29 -0
  50. package/recipes/answerability/demo.json +31 -0
  51. package/recipes/clarify/README.md +32 -0
  52. package/recipes/clarify/demo.json +45 -0
  53. package/recipes/handoff/README.md +35 -0
  54. package/recipes/handoff/demo.json +30 -0
  55. package/dist/cli/recipes.d.ts +0 -53
  56. package/dist/cli/recipes.js +0 -20
package/CHANGELOG.md CHANGED
@@ -2,9 +2,14 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
- ### Added
5
+ - Add independent `answerability`, `clarify`, and `handoff` recipes with Zod schemas, inferred types, documentation, and offline fixtures.
6
+ - Add recipe-owned metadata, a searchable catalog, and CLI `describe` with JSON schemas and example input.
7
+ - Add `demo all` and a support-assistant example that composes six recipes, accepts an application draft callback, and verifies claims against selected evidence.
8
+ - Extend package exports and release checks without adding dependencies.
6
9
 
7
- - Initial 0.0.1 foundation with route, rerank, and verify recipes.
10
+ ## 0.0.1
11
+
12
+ - Initial foundation with route, rerank, and verify recipes.
8
13
  - TypeScript library with Zod schemas and inferred types.
9
14
  - CLI with offline demos, editable example input, and live Jev calls.
10
15
  - Build, formatting, and package checks for manual npm releases.
package/README.md CHANGED
@@ -1,159 +1,149 @@
1
- # jev recipes
1
+ # jev-recipes
2
2
 
3
- Small, composable recipes for [Jev](https://docs.typesafe.ai/introduction/coding-agents): choose a handler, rank useful passages, and check claims against evidence.
3
+ [![npm version](https://img.shields.io/npm/v/jev-recipes?logo=npm)](https://www.npmjs.com/package/jev-recipes)
4
4
 
5
- **Version 0.0.1.** A TypeScript library and a small command-line runner. Each recipe owns its implementation, Zod schemas, example, and documentation. Public data types are inferred from those schemas.
5
+ Small TypeScript recipes for the decisions inside an AI application. Use [Jev](https://docs.typesafe.ai/introduction/coding-agents) to choose a handler, select useful evidence, check an answer, or decide when to ask for help.
6
6
 
7
- | Recipe | Input | Result |
8
- | ------------------------------------ | ------------------------------ | ------------------------------------------ |
9
- | [`route`](recipes/route/README.md) | A request and named handlers | A selected handler or a review decision |
10
- | [`rerank`](recipes/rerank/README.md) | A query and candidate passages | Relevant passages, ordered by relevance |
11
- | [`verify`](recipes/verify/README.md) | Claims paired with evidence | A verdict and review status for each claim |
7
+ Each recipe is a function you can use on its own. Your application supplies the context and acts on the result.
12
8
 
13
- ## Try it locally
9
+ ## Recipes
14
10
 
15
- Requires Node.js 22.9 or newer. From this repository:
11
+ | Recipe | What it does |
12
+ | -------------------------------------------------- | -------------------------------------------------- |
13
+ | [`route`](recipes/route/README.md) | Chooses a handler for a request. |
14
+ | [`rerank`](recipes/rerank/README.md) | Selects and orders relevant passages. |
15
+ | [`verify`](recipes/verify/README.md) | Checks claims against supplied evidence. |
16
+ | [`answerability`](recipes/answerability/README.md) | Checks whether the evidence can answer a question. |
17
+ | [`clarify`](recipes/clarify/README.md) | Finds missing or ambiguous information. |
18
+ | [`handoff`](recipes/handoff/README.md) | Checks your rules for involving a human. |
16
19
 
17
- ```sh
18
- npm ci
19
- npm run build
20
- npm run jev -- list
21
- npm run jev -- demo rerank
22
- ```
20
+ Each recipe has its own usage guide, input and result schemas, and runnable demo.
21
+
22
+ ## Use in an app
23
23
 
24
- All three demos work without a key. Each recipe's `README.md` explains its API and limits; `demo.json` supplies executable example input and a saved response for the CLI. The demos run the recipe's validation and decision handling without calling Jev or measuring model accuracy.
24
+ Requires Node.js 22.9 or newer.
25
25
 
26
26
  ```sh
27
- npm run jev -- demo route
28
- npm run jev -- demo verify
27
+ npm install jev-recipes
29
28
  ```
30
29
 
31
- ## Run your own input
30
+ Set `TYPESAFE_API_KEY` in your server's environment, then call a recipe:
32
31
 
33
- Copy `.env.example` to `.env`, then set `TYPESAFE_API_KEY` from your TypeSafe account. Keep the key out of source control.
32
+ ```ts
33
+ import { rerank } from 'jev-recipes/rerank';
34
34
 
35
- ```sh
36
- cp .env.example .env
37
- node dist/cli/index.js example rerank > input.json
35
+ const result = await rerank({
36
+ query: 'How do I reset my password?',
37
+ items: [
38
+ { id: 'billing', text: 'Invoices appear on the Billing page.' },
39
+ { id: 'reset', text: 'Select Forgot password to receive a reset link.' },
40
+ ],
41
+ topK: 1,
42
+ });
43
+
44
+ if (result.status === 'ready') {
45
+ console.log(result.items);
46
+ }
38
47
  ```
39
48
 
40
- Edit `input.json` with your query and passages, then run:
49
+ You can also import recipes from `jev-recipes`. Every recipe accepts an optional second argument with `client`, `model`, and `signal`. Use `createClient` to configure the official TypeSafe SDK's timeouts and retries.
41
50
 
42
- ```sh
43
- npm run jev -- run rerank input.json
44
- ```
51
+ Live calls send the supplied input to TypeSafe and use API quota. Keep your API key on the server.
52
+
53
+ ## Try the demos
45
54
 
46
- Use `-` in place of the filename to read JSON from stdin. The `npm run jev` script loads `.env`; direct `jev-recipes` or `node` invocations use the process environment unless you explicitly load an env file. Use the direct command when piping JSON so npm's script banner is not included:
55
+ From this repository:
47
56
 
48
57
  ```sh
49
- node --env-file-if-exists=.env dist/cli/index.js run rerank input.json
58
+ npm ci
59
+ npm run build
60
+ npm run jev -- demo all
50
61
  ```
51
62
 
52
- Live runs send the recipe's input to TypeSafe and consume API quota. Jev performs inference remotely; the recipe's filtering and review rules run in your process. This project does not store inputs or add telemetry.
63
+ Demos use saved responses and need no API key. They show how each recipe handles a decision; they do not measure model accuracy. To run one, replace `all` with its name.
53
64
 
54
- ## Use from an app
65
+ The repository may contain additions that are not yet in the [published npm package](https://www.npmjs.com/package/jev-recipes). Use this checkout to try all the recipes shown here.
55
66
 
56
- The package exposes the same functions used by the command-line runner. In this checkout, package self-references work after `npm run build`:
67
+ ## Find a recipe
57
68
 
58
- ```ts
59
- import { rerank } from 'jev-recipes';
69
+ Developers and coding agents can inspect the catalog without calling Jev:
60
70
 
61
- const result = await rerank({
62
- query: 'How do I reset my password?',
63
- items: [
64
- { id: 'billing', text: 'Invoices appear on the Billing page.' },
65
- { id: 'reset', text: 'Select Forgot password to receive a reset link.' },
66
- ],
67
- topK: 1,
68
- });
69
-
70
- console.log(result.status, result.items);
71
+ ```sh
72
+ npm run jev -- list
73
+ npm run jev -- list evidence --category retrieval
74
+ npm run jev -- describe answerability
71
75
  ```
72
76
 
73
- Individual recipe imports are also available:
77
+ `list` searches names, descriptions, categories, and tags. `describe` returns the recipe's limits, JSON input and result schemas, and example input.
78
+
79
+ The same catalog is available in TypeScript:
74
80
 
75
81
  ```ts
76
- import { route } from 'jev-recipes/route';
77
- import { verify } from 'jev-recipes/verify';
82
+ import { listRecipes, describeRecipe } from 'jev-recipes/catalog';
83
+
84
+ const recipes = listRecipes({ category: 'retrieval' });
85
+ const specification = describeRecipe('answerability');
78
86
  ```
79
87
 
80
- For another local project, run `npm pack` here and install the resulting `.tgz` file there. That exercises the same package contents npm will distribute. See [RELEASING.md](RELEASING.md) for the commands. This README does not assume the package is published on npm yet.
88
+ The library returns metadata and schemas. The command-line description also includes example input. Zod validates runtime inputs, including rules such as unique IDs that JSON Schema does not fully express.
81
89
 
82
- ### Client configuration
90
+ ## Run your own input
83
91
 
84
- The default client reads `TYPESAFE_API_KEY` and uses `jev-latest`. You can reuse a client and supply a model or cancellation signal per call:
92
+ Add `TYPESAFE_API_KEY` to a local `.env` file. See [.env.example](.env.example) for the format.
85
93
 
86
- ```ts
87
- import { createClient, route } from 'jev-recipes';
88
-
89
- const client = createClient({ timeout: 15_000, retry: { maxRetries: 1 } });
90
- const result = await route(
91
- {
92
- request: 'I was charged twice.',
93
- routes: {
94
- billing: 'Invoices, payments, subscriptions, and refunds',
95
- technical: 'Errors, outages, and broken integrations',
96
- },
97
- minConfidence: 0.8,
98
- },
99
- { client, signal: AbortSignal.timeout(20_000) },
100
- );
94
+ Create an input file, edit it, then run the recipe:
95
+
96
+ ```sh
97
+ node dist/cli/index.js example rerank > input.json
98
+ npm run jev -- run rerank input.json
101
99
  ```
102
100
 
103
- Transport, authentication, retries, and timeouts use the official `@typesafe-ai/sdk`. The shared client disables SDK logging by default. API keys belong on the server, never in browser code. The SDK timeout applies per attempt; a cancellation signal can bound the complete operation. Pass a supported model ID through `{ model: '...' }` to pin evaluations when comparing versions.
101
+ The `npm run jev` command loads `.env`. Use `-` instead of a filename to read from stdin. For scripts that need JSON without npm's command banner:
104
102
 
105
- ## Behavior to know
103
+ ```sh
104
+ node --env-file-if-exists=.env dist/cli/index.js run rerank input.json
105
+ ```
106
106
 
107
- - `ready` means a configured threshold passed. It does not mean the model is certainly correct or that an action was executed.
108
- - A review outcome is a successful evaluation, not a technical error. `verify` attaches a status to each check; a ready verdict can still be `contradicted` or `unsupported`.
109
- - Zod 4 validates inputs and model responses. Invalid input, missing credentials, provider failures, and malformed answers throw. The CLI writes an error to stderr and exits with code 1.
110
- - Confidence is distinct from a choice's probability. Reranking uses independent yes/no relevance values, which do not sum to 1.
111
- - Threshold defaults are illustrative. Evaluate on your own labeled examples before relying on them.
112
- - These functions return decisions only. They do not execute handlers, modify documents, search the web, or establish whether a source is true.
113
- - Inputs are not silently truncated. Batch limits are documented per recipe; provider context limits can require smaller batches.
107
+ ## Connect the recipes
114
108
 
115
- ## Project layout
109
+ The [support assistant example](examples/support/README.md) combines all six:
116
110
 
117
111
  ```text
118
- recipes/
119
- route/
120
- rerank/
121
- verify/
122
- index.ts Recipe implementation
123
- schema.ts Input/result schemas and z.infer types
124
- demo.json Example input and an offline response fixture
125
- README.md Usage and limits
126
- src/
127
- client.ts Thin adapter over the official SDK
128
- answers.ts Validate model responses
129
- schema.ts Shared Zod schemas and inferred types
130
- index.ts Public exports
131
- cli/
132
- index.ts Arguments, files, stdin, and output
133
- recipes.ts Explicit recipe registration
134
- schema.ts Command and demo validation
112
+ handoff → clarify → route → rerank → answerability → draft an answer → verify
135
113
  ```
136
114
 
137
- Recipes depend on `src/`, never on one another or on the CLI. The CLI calls the public recipe functions. There is no application server, database, or background process.
138
-
139
- ## Development
115
+ It stops when the request needs a person, clarification, better evidence, or review. The draft step is a callback you can connect to your existing generation code.
140
116
 
141
117
  ```sh
142
- npm run format
143
- npm run ci
144
- npm run pack:check
118
+ npm run example:support
145
119
  ```
146
120
 
147
- `npm run ci` checks formatting, type-checks the source, makes a clean build, and runs the offline demos. GitHub runs the same checks on Node 22 and 24. The demos show request and result shapes; live model accuracy has not been measured for this initial release.
121
+ This runs offline with a saved draft and saved decisions. Add `-- --live` to call Jev for the decisions using your `.env` key. The draft stays fixed in both modes.
122
+
123
+ ## Read the result before acting
124
+
125
+ - `ready` means a decision passed its threshold. Check the recipe's outcome too: a ready assessment can still find missing information or an unsupported claim.
126
+ - Use `canProceed`, `canAnswer`, `decision`, or `allSupported` as described in each recipe's guide.
127
+ - `review` is a valid outcome. Invalid inputs, malformed model responses, and provider errors throw; the command-line runner reports them on stderr and exits with code 1.
128
+ - Confidence does not guarantee correctness. Choose thresholds for your use case.
129
+ - Recipes assess the evidence and rules you supply. They return decisions; your application handles actions and permissions.
148
130
 
149
- See [CONTRIBUTING.md](CONTRIBUTING.md) for adding a recipe. Version 0.0.1 is the foundation: recipe installation into other projects, a user-data evaluation runner, and an MCP server are not included yet.
131
+ ## Contribute
150
132
 
151
- ## Distribution
133
+ Each recipe owns its implementation, Zod 4 schemas, inferred types, metadata, demo, and documentation. Recipes share a small client layer and stay independent of one another.
134
+
135
+ ```text
136
+ recipes/<name>/ Individual recipes
137
+ src/ Shared client, response validation, schemas, and exports
138
+ catalog/ Recipe registration and discovery
139
+ cli/ Command-line runner
140
+ examples/ Workflows that combine recipes
141
+ ```
152
142
 
153
- `npm run build` compiles the TypeScript into ESM JavaScript and `.d.ts` declarations under `dist/`. `npm pack` creates a `.tgz` containing that output, the recipe demos and documentation, the changelog, and the license. npm installs the TypeSafe SDK and Zod as runtime dependencies. Consumers do not run a build.
143
+ See [CONTRIBUTING.md](CONTRIBUTING.md) to add a recipe.
154
144
 
155
- Use [RELEASING.md](RELEASING.md) to inspect the archive, try it in a separate project, run live evaluations, and publish version 0.0.1. Publishing is manual.
145
+ `npm run build` compiles the TypeScript into JavaScript modules and type declarations. `npm pack` creates the installable archive. See [RELEASING.md](RELEASING.md) for packaging and publishing, and [CHANGELOG.md](CHANGELOG.md) for changes.
156
146
 
157
147
  ## License
158
148
 
159
- MIT. Independent community project; Jev and TypeSafe are products of TypeSafe AI.
149
+ [MIT](LICENSE). Independent community project. Jev and TypeSafe are products of TypeSafe AI.
@@ -0,0 +1,211 @@
1
+ import { z } from 'zod';
2
+ import type { RecipeFilters, RecipeName } from './schema.js';
3
+ export declare function listRecipes(filters?: RecipeFilters): {
4
+ id: "route" | "answerability" | "rerank" | "verify" | "clarify" | "handoff";
5
+ title: string;
6
+ description: string;
7
+ category: "retrieval" | "conversation" | "workflow";
8
+ tags: string[];
9
+ limitations: string[];
10
+ }[];
11
+ export declare function describeRecipe(name: RecipeName): {
12
+ inputSchema: z.core.ZodStandardJSONSchemaPayload<z.ZodObject<{
13
+ request: z.ZodString;
14
+ routes: z.ZodRecord<z.ZodString, z.ZodString>;
15
+ minConfidence: z.ZodOptional<z.ZodNumber>;
16
+ }, z.core.$strip> | z.ZodObject<{
17
+ query: z.ZodString;
18
+ items: z.ZodArray<z.ZodObject<{
19
+ id: z.ZodString;
20
+ text: z.ZodString;
21
+ }, z.core.$strip>>;
22
+ topK: z.ZodOptional<z.ZodNumber>;
23
+ minRelevance: z.ZodOptional<z.ZodNumber>;
24
+ }, z.core.$strip> | z.ZodObject<{
25
+ claims: z.ZodArray<z.ZodObject<{
26
+ id: z.ZodString;
27
+ claim: z.ZodString;
28
+ evidence: z.ZodString;
29
+ }, z.core.$strip>>;
30
+ minConfidence: z.ZodOptional<z.ZodNumber>;
31
+ }, z.core.$strip> | z.ZodObject<{
32
+ question: z.ZodString;
33
+ evidence: z.ZodArray<z.ZodObject<{
34
+ id: z.ZodString;
35
+ text: z.ZodString;
36
+ }, z.core.$strip>>;
37
+ minConfidence: z.ZodOptional<z.ZodNumber>;
38
+ }, z.core.$strip> | z.ZodObject<{
39
+ request: z.ZodString;
40
+ context: z.ZodOptional<z.ZodString>;
41
+ requirements: z.ZodArray<z.ZodObject<{
42
+ id: z.ZodString;
43
+ description: z.ZodString;
44
+ }, z.core.$strip>>;
45
+ minConfidence: z.ZodOptional<z.ZodNumber>;
46
+ }, z.core.$strip> | z.ZodObject<{
47
+ request: z.ZodString;
48
+ context: z.ZodOptional<z.ZodString>;
49
+ rules: z.ZodArray<z.ZodObject<{
50
+ id: z.ZodString;
51
+ description: z.ZodString;
52
+ }, z.core.$strip>>;
53
+ minConfidence: z.ZodOptional<z.ZodNumber>;
54
+ }, z.core.$strip>>;
55
+ resultSchema: z.core.ZodStandardJSONSchemaPayload<z.ZodObject<{
56
+ model: z.ZodString;
57
+ usage: z.ZodObject<{
58
+ input_tokens: z.ZodNumber;
59
+ output_tokens: z.ZodNumber;
60
+ }, z.core.$strip>;
61
+ status: z.ZodEnum<{
62
+ ready: "ready";
63
+ review: "review";
64
+ }>;
65
+ route: z.ZodNullable<z.ZodString>;
66
+ suggestedRoute: z.ZodNullable<z.ZodString>;
67
+ confidence: z.ZodNumber;
68
+ probabilities: z.ZodRecord<z.ZodString, z.ZodNumber>;
69
+ }, z.core.$strip> | z.ZodObject<{
70
+ model: z.ZodString;
71
+ usage: z.ZodObject<{
72
+ input_tokens: z.ZodNumber;
73
+ output_tokens: z.ZodNumber;
74
+ }, z.core.$strip>;
75
+ status: z.ZodEnum<{
76
+ ready: "ready";
77
+ review: "review";
78
+ }>;
79
+ items: z.ZodArray<z.ZodObject<{
80
+ id: z.ZodString;
81
+ text: z.ZodString;
82
+ relevance: z.ZodNumber;
83
+ }, z.core.$strip>>;
84
+ evaluated: z.ZodNumber;
85
+ }, z.core.$strip> | z.ZodObject<{
86
+ model: z.ZodString;
87
+ usage: z.ZodObject<{
88
+ input_tokens: z.ZodNumber;
89
+ output_tokens: z.ZodNumber;
90
+ }, z.core.$strip>;
91
+ checks: z.ZodArray<z.ZodObject<{
92
+ id: z.ZodString;
93
+ status: z.ZodEnum<{
94
+ ready: "ready";
95
+ review: "review";
96
+ }>;
97
+ verdict: z.ZodEnum<{
98
+ supported: "supported";
99
+ contradicted: "contradicted";
100
+ unsupported: "unsupported";
101
+ }>;
102
+ confidence: z.ZodNumber;
103
+ probabilities: z.ZodRecord<z.ZodEnum<{
104
+ supported: "supported";
105
+ contradicted: "contradicted";
106
+ unsupported: "unsupported";
107
+ }>, z.ZodNumber>;
108
+ }, z.core.$strip>>;
109
+ allSupported: z.ZodBoolean;
110
+ }, z.core.$strip> | z.ZodObject<{
111
+ model: z.ZodString;
112
+ usage: z.ZodObject<{
113
+ input_tokens: z.ZodNumber;
114
+ output_tokens: z.ZodNumber;
115
+ }, z.core.$strip>;
116
+ status: z.ZodEnum<{
117
+ ready: "ready";
118
+ review: "review";
119
+ }>;
120
+ verdict: z.ZodEnum<{
121
+ sufficient: "sufficient";
122
+ partial: "partial";
123
+ insufficient: "insufficient";
124
+ conflicting: "conflicting";
125
+ }>;
126
+ canAnswer: z.ZodBoolean;
127
+ confidence: z.ZodNumber;
128
+ probabilities: z.ZodRecord<z.ZodEnum<{
129
+ sufficient: "sufficient";
130
+ partial: "partial";
131
+ insufficient: "insufficient";
132
+ conflicting: "conflicting";
133
+ }>, z.ZodNumber>;
134
+ }, z.core.$strip> | z.ZodObject<{
135
+ model: z.ZodString;
136
+ usage: z.ZodObject<{
137
+ input_tokens: z.ZodNumber;
138
+ output_tokens: z.ZodNumber;
139
+ }, z.core.$strip>;
140
+ status: z.ZodEnum<{
141
+ ready: "ready";
142
+ review: "review";
143
+ }>;
144
+ canProceed: z.ZodBoolean;
145
+ missing: z.ZodArray<z.ZodString>;
146
+ ambiguous: z.ZodArray<z.ZodString>;
147
+ checks: z.ZodArray<z.ZodObject<{
148
+ id: z.ZodString;
149
+ status: z.ZodEnum<{
150
+ ready: "ready";
151
+ review: "review";
152
+ }>;
153
+ verdict: z.ZodEnum<{
154
+ present: "present";
155
+ missing: "missing";
156
+ ambiguous: "ambiguous";
157
+ }>;
158
+ confidence: z.ZodNumber;
159
+ probabilities: z.ZodRecord<z.ZodEnum<{
160
+ present: "present";
161
+ missing: "missing";
162
+ ambiguous: "ambiguous";
163
+ }>, z.ZodNumber>;
164
+ }, z.core.$strip>>;
165
+ }, z.core.$strip> | z.ZodObject<{
166
+ model: z.ZodString;
167
+ usage: z.ZodObject<{
168
+ input_tokens: z.ZodNumber;
169
+ output_tokens: z.ZodNumber;
170
+ }, z.core.$strip>;
171
+ status: z.ZodEnum<{
172
+ ready: "ready";
173
+ review: "review";
174
+ }>;
175
+ decision: z.ZodEnum<{
176
+ review: "review";
177
+ human: "human";
178
+ continue: "continue";
179
+ }>;
180
+ matchedRules: z.ZodArray<z.ZodString>;
181
+ uncertainRules: z.ZodArray<z.ZodString>;
182
+ checks: z.ZodArray<z.ZodObject<{
183
+ id: z.ZodString;
184
+ status: z.ZodEnum<{
185
+ ready: "ready";
186
+ review: "review";
187
+ }>;
188
+ verdict: z.ZodEnum<{
189
+ matches: "matches";
190
+ does_not_match: "does_not_match";
191
+ unclear: "unclear";
192
+ }>;
193
+ confidence: z.ZodNumber;
194
+ probabilities: z.ZodRecord<z.ZodEnum<{
195
+ matches: "matches";
196
+ does_not_match: "does_not_match";
197
+ unclear: "unclear";
198
+ }>, z.ZodNumber>;
199
+ }, z.core.$strip>>;
200
+ }, z.core.$strip>>;
201
+ id: string;
202
+ title: string;
203
+ description: string;
204
+ category: "retrieval" | "conversation" | "workflow";
205
+ tags: string[];
206
+ limitations: string[];
207
+ };
208
+ export { recipeFiltersSchema, recipeNameSchema } from './schema.js';
209
+ export { recipeCategorySchema, recipeMetadataSchema } from '../src/schema.js';
210
+ export type { RecipeFilters, RecipeName } from './schema.js';
211
+ export type { RecipeCategory, RecipeMetadata } from '../src/schema.js';
@@ -0,0 +1,31 @@
1
+ import { z } from 'zod';
2
+ import { recipeMetadataSchema } from '../src/schema.js';
3
+ import { recipes } from './recipes.js';
4
+ import { recipeFiltersSchema, recipeNameSchema } from './schema.js';
5
+ export function listRecipes(filters = {}) {
6
+ const { query, category } = recipeFiltersSchema.parse(filters);
7
+ const searchTerms = query?.toLowerCase().trim().split(/\s+/) ?? [];
8
+ return Object.entries(recipes)
9
+ .map(([id, recipe]) => ({
10
+ ...recipeMetadataSchema.parse(recipe.metadata),
11
+ id: recipeNameSchema.parse(id),
12
+ }))
13
+ .filter((recipe) => category === undefined || recipe.category === category)
14
+ .filter((recipe) => matchesSearch(recipe, searchTerms));
15
+ }
16
+ export function describeRecipe(name) {
17
+ const recipe = recipes[recipeNameSchema.parse(name)];
18
+ return {
19
+ ...recipeMetadataSchema.parse(recipe.metadata),
20
+ inputSchema: z.toJSONSchema(recipe.inputSchema, { io: 'input' }),
21
+ resultSchema: z.toJSONSchema(recipe.resultSchema),
22
+ };
23
+ }
24
+ function matchesSearch(recipe, terms) {
25
+ const text = [recipe.id, recipe.title, recipe.description, recipe.category, ...recipe.tags]
26
+ .join(' ')
27
+ .toLowerCase();
28
+ return terms.every((term) => text.includes(term));
29
+ }
30
+ export { recipeFiltersSchema, recipeNameSchema } from './schema.js';
31
+ export { recipeCategorySchema, recipeMetadataSchema } from '../src/schema.js';