jev-recipes 0.4.1 → 0.5.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.
- package/CHANGELOG.md +2 -0
- package/README.md +16 -11
- package/dist/catalog/generated/details/checkers-move.json +128 -0
- package/dist/catalog/generated/loaders.js +1 -0
- package/dist/catalog/generated/metadata.js +27 -0
- package/dist/catalog/generated/names.d.ts +1 -1
- package/dist/catalog/generated/names.js +1 -0
- package/dist/catalog/schema.d.ts +1 -0
- package/dist/cli/schema.d.ts +3 -0
- package/dist/recipes/checkers-move/demo.json +58 -0
- package/dist/recipes/checkers-move/index.d.ts +5 -0
- package/dist/recipes/checkers-move/index.js +34 -0
- package/dist/recipes/checkers-move/schema.d.ts +48 -0
- package/dist/recipes/checkers-move/schema.js +73 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +1 -0
- package/package.json +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- Add `checkers-move`: supply a structured board, player, and legal moves to receive a move ID in one logical Jev request. Includes American/English checkers instructions, board translation, input checks, and offline tests, bringing the source catalog to 81 recipes. No new runtime dependencies; live speed and playing strength remain unmeasured.
|
|
6
|
+
|
|
5
7
|
- Add `take-turn` and `choose-action` for narrative turn eligibility and game action recommendations, with optional ordered player history, offline tests, and a gameplay composition guide. The source catalog now contains 80 recipes.
|
|
6
8
|
- Clarify that `.mjs` is a standalone Node quickstart option; existing JavaScript ES module and TypeScript projects can use their normal file types and start commands.
|
|
7
9
|
|
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
<!-- BEGIN GENERATED: summary -->
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
81 focused recipes for JavaScript and TypeScript. Route messages, check evidence, and label model responses with a function call.
|
|
15
15
|
|
|
16
16
|
<!-- END GENERATED: summary -->
|
|
17
17
|
|
|
@@ -19,6 +19,10 @@ Each recipe accepts your data, calls [Jev through TypeSafe's API](https://docs.t
|
|
|
19
19
|
|
|
20
20
|
For example, give `route` a support message and descriptions of your teams. It returns a team such as `billing`, or a review outcome when the choice is uncertain.
|
|
21
21
|
|
|
22
|
+
## Watch Jev play checkers against Jev using the checkers-move recipe
|
|
23
|
+
|
|
24
|
+
https://github.com/user-attachments/assets/4ac10e7b-b57c-4d73-a2fe-fee90cd1e58d
|
|
25
|
+
|
|
22
26
|
## Use a recipe
|
|
23
27
|
|
|
24
28
|
Requires **Node.js 22.9 or newer**, ES modules, and a **[TypeSafe API key](https://console.typesafe.ai/keys)**. Live calls send the supplied input to TypeSafe and use API quota.
|
|
@@ -113,15 +117,16 @@ The TypeSafe SDK handles API calls and typed answers. Recipes add the instructio
|
|
|
113
117
|
|
|
114
118
|
## Find your recipe
|
|
115
119
|
|
|
116
|
-
| Your task
|
|
117
|
-
|
|
|
118
|
-
| Send a request to the right team
|
|
119
|
-
| Find useful passages
|
|
120
|
-
| Check whether the evidence is enough to answer
|
|
121
|
-
| Check claims against supplied evidence
|
|
122
|
-
| Find missing or ambiguous requirements
|
|
123
|
-
| Label a response's stance toward a claim
|
|
124
|
-
| Choose a move from available game actions
|
|
120
|
+
| Your task | Start with |
|
|
121
|
+
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
|
|
122
|
+
| Send a request to the right team | [`route`](https://github.com/agencyenterprise/jev-recipes/blob/main/recipes/route/README.md) |
|
|
123
|
+
| Find useful passages | [`rerank`](https://github.com/agencyenterprise/jev-recipes/blob/main/recipes/rerank/README.md) |
|
|
124
|
+
| Check whether the evidence is enough to answer | [`answerability`](https://github.com/agencyenterprise/jev-recipes/blob/main/recipes/answerability/README.md) |
|
|
125
|
+
| Check claims against supplied evidence | [`verify`](https://github.com/agencyenterprise/jev-recipes/blob/main/recipes/verify/README.md) |
|
|
126
|
+
| Find missing or ambiguous requirements | [`clarify`](https://github.com/agencyenterprise/jev-recipes/blob/main/recipes/clarify/README.md) |
|
|
127
|
+
| Label a response's stance toward a claim | [`claim-stance`](https://github.com/agencyenterprise/jev-recipes/blob/main/recipes/claim-stance/README.md) |
|
|
128
|
+
| Choose a move from available game actions | [`choose-action`](https://github.com/agencyenterprise/jev-recipes/blob/main/recipes/choose-action/README.md) |
|
|
129
|
+
| Choose a checkers move from your board and legal moves | [`checkers-move`](https://github.com/agencyenterprise/jev-recipes/blob/main/recipes/checkers-move/README.md) |
|
|
125
130
|
|
|
126
131
|
Search, inspect inputs, and try saved results without a key:
|
|
127
132
|
|
|
@@ -133,7 +138,7 @@ npx jev-recipes demo answerability
|
|
|
133
138
|
|
|
134
139
|
[Browse the complete catalog](https://github.com/agencyenterprise/jev-recipes/blob/main/recipes/README.md). Each guide includes an import, input reference, result behavior, limitations, and related recipes.
|
|
135
140
|
|
|
136
|
-
For games, the [gameplay guide](https://github.com/agencyenterprise/jev-recipes/blob/main/docs/gameplay.md)
|
|
141
|
+
For games, the [gameplay guide](https://github.com/agencyenterprise/jev-recipes/blob/main/docs/gameplay.md) starts with a checkers decision using just the board, player, and legal moves. It also covers general action selection and narrative turn eligibility.
|
|
137
142
|
|
|
138
143
|
<a id="run-your-own-input-from-the-terminal"></a>
|
|
139
144
|
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
{
|
|
2
|
+
"inputSchema": {
|
|
3
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"board": {
|
|
7
|
+
"minItems": 1,
|
|
8
|
+
"maxItems": 24,
|
|
9
|
+
"type": "array",
|
|
10
|
+
"items": {
|
|
11
|
+
"type": "object",
|
|
12
|
+
"properties": {
|
|
13
|
+
"square": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"pattern": "^(?:[aceg][1357]|[bdfh][2468])$",
|
|
16
|
+
"description": "A playable square: a1 is bottom left; files a-h, ranks 1-8."
|
|
17
|
+
},
|
|
18
|
+
"player": { "type": "string", "enum": ["red", "black"] },
|
|
19
|
+
"king": {
|
|
20
|
+
"description": "True for a king; omitted or false for a man.",
|
|
21
|
+
"type": "boolean"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"required": ["square", "player"],
|
|
25
|
+
"additionalProperties": false
|
|
26
|
+
},
|
|
27
|
+
"description": "All remaining pieces. Unlisted squares are empty; red moves toward rank 8, black toward rank 1."
|
|
28
|
+
},
|
|
29
|
+
"player": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"enum": ["red", "black"],
|
|
32
|
+
"description": "The side whose turn it is and whose move should be chosen."
|
|
33
|
+
},
|
|
34
|
+
"legalMoves": {
|
|
35
|
+
"minItems": 1,
|
|
36
|
+
"maxItems": 50,
|
|
37
|
+
"type": "array",
|
|
38
|
+
"items": {
|
|
39
|
+
"type": "object",
|
|
40
|
+
"properties": {
|
|
41
|
+
"id": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"description": "Your move ID, returned unchanged when selected. __proto__ is reserved."
|
|
44
|
+
},
|
|
45
|
+
"from": {
|
|
46
|
+
"type": "string",
|
|
47
|
+
"pattern": "^(?:[aceg][1357]|[bdfh][2468])$",
|
|
48
|
+
"description": "A playable square: a1 is bottom left; files a-h, ranks 1-8."
|
|
49
|
+
},
|
|
50
|
+
"path": {
|
|
51
|
+
"minItems": 1,
|
|
52
|
+
"maxItems": 12,
|
|
53
|
+
"type": "array",
|
|
54
|
+
"items": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"pattern": "^(?:[aceg][1357]|[bdfh][2468])$",
|
|
57
|
+
"description": "A playable square: a1 is bottom left; files a-h, ranks 1-8."
|
|
58
|
+
},
|
|
59
|
+
"description": "Every landing square in order, excluding from. Include the full jump sequence."
|
|
60
|
+
},
|
|
61
|
+
"captures": {
|
|
62
|
+
"description": "Captured piece squares in jump order. Omit or use [] for an ordinary move.",
|
|
63
|
+
"maxItems": 12,
|
|
64
|
+
"type": "array",
|
|
65
|
+
"items": {
|
|
66
|
+
"type": "string",
|
|
67
|
+
"pattern": "^(?:[aceg][1357]|[bdfh][2468])$",
|
|
68
|
+
"description": "A playable square: a1 is bottom left; files a-h, ranks 1-8."
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"required": ["id", "from", "path"],
|
|
73
|
+
"additionalProperties": false
|
|
74
|
+
},
|
|
75
|
+
"description": "One to fifty complete legal moves from your game, with unique IDs."
|
|
76
|
+
},
|
|
77
|
+
"minConfidence": { "type": "number", "minimum": 0, "maximum": 1 }
|
|
78
|
+
},
|
|
79
|
+
"required": ["board", "player", "legalMoves"],
|
|
80
|
+
"additionalProperties": false
|
|
81
|
+
},
|
|
82
|
+
"resultSchema": {
|
|
83
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
84
|
+
"type": "object",
|
|
85
|
+
"properties": {
|
|
86
|
+
"model": { "type": "string" },
|
|
87
|
+
"usage": {
|
|
88
|
+
"type": "object",
|
|
89
|
+
"properties": {
|
|
90
|
+
"input_tokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
|
|
91
|
+
"output_tokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 }
|
|
92
|
+
},
|
|
93
|
+
"required": ["input_tokens", "output_tokens"],
|
|
94
|
+
"additionalProperties": false
|
|
95
|
+
},
|
|
96
|
+
"status": { "type": "string", "enum": ["ready", "review"] },
|
|
97
|
+
"verdict": { "type": "string", "enum": ["matched", "none", "ambiguous"] },
|
|
98
|
+
"selection": { "type": ["string", "null"] },
|
|
99
|
+
"suggestedSelection": { "type": ["string", "null"] },
|
|
100
|
+
"confidence": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
101
|
+
"probabilities": {
|
|
102
|
+
"type": "object",
|
|
103
|
+
"properties": {
|
|
104
|
+
"candidates": {
|
|
105
|
+
"type": "object",
|
|
106
|
+
"propertyNames": { "type": "string" },
|
|
107
|
+
"additionalProperties": { "type": "number", "minimum": 0, "maximum": 1 }
|
|
108
|
+
},
|
|
109
|
+
"none": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
110
|
+
"ambiguous": { "type": "number", "minimum": 0, "maximum": 1 }
|
|
111
|
+
},
|
|
112
|
+
"required": ["candidates", "none", "ambiguous"],
|
|
113
|
+
"additionalProperties": false
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
"required": [
|
|
117
|
+
"model",
|
|
118
|
+
"usage",
|
|
119
|
+
"status",
|
|
120
|
+
"verdict",
|
|
121
|
+
"selection",
|
|
122
|
+
"suggestedSelection",
|
|
123
|
+
"confidence",
|
|
124
|
+
"probabilities"
|
|
125
|
+
],
|
|
126
|
+
"additionalProperties": false
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -13,6 +13,7 @@ export const recipeLoaders = {
|
|
|
13
13
|
'cancellation-check': () => import('../../recipes/cancellation-check/index.js').then((recipe) => (input, options) => recipe.cancellationCheck(recipe.cancellationCheckInputSchema.parse(input), options)),
|
|
14
14
|
'certainty-match': () => import('../../recipes/certainty-match/index.js').then((recipe) => (input, options) => recipe.certaintyMatch(recipe.certaintyMatchInputSchema.parse(input), options)),
|
|
15
15
|
'change-meaning': () => import('../../recipes/change-meaning/index.js').then((recipe) => (input, options) => recipe.changeMeaning(recipe.changeMeaningInputSchema.parse(input), options)),
|
|
16
|
+
'checkers-move': () => import('../../recipes/checkers-move/index.js').then((recipe) => (input, options) => recipe.checkersMove(recipe.checkersMoveInputSchema.parse(input), options)),
|
|
16
17
|
'choose-action': () => import('../../recipes/choose-action/index.js').then((recipe) => (input, options) => recipe.chooseAction(recipe.chooseActionInputSchema.parse(input), options)),
|
|
17
18
|
'citation-match': () => import('../../recipes/citation-match/index.js').then((recipe) => (input, options) => recipe.citationMatch(recipe.citationMatchInputSchema.parse(input), options)),
|
|
18
19
|
'citation-needed': () => import('../../recipes/citation-needed/index.js').then((recipe) => (input, options) => recipe.citationNeeded(recipe.citationNeededInputSchema.parse(input), options)),
|
|
@@ -251,6 +251,29 @@ export const recipeMetadata = [
|
|
|
251
251
|
},
|
|
252
252
|
],
|
|
253
253
|
},
|
|
254
|
+
{
|
|
255
|
+
id: 'checkers-move',
|
|
256
|
+
title: 'Choose a checkers move',
|
|
257
|
+
description: 'Recommend a supplied legal checkers move from a structured board and player, with built-in American/English checkers instructions.',
|
|
258
|
+
category: 'workflow',
|
|
259
|
+
tags: ['checkers', 'draughts', 'gameplay', 'board game', 'legal moves', 'kings', 'captures'],
|
|
260
|
+
limitations: [
|
|
261
|
+
'Supports the documented 8x8 American/English variant and orientation. Your game supplies complete legal moves and owns turn, draw, and execution rules.',
|
|
262
|
+
'Validates format, ownership, and capture references; does not generate moves, prove legality, search future positions, or guarantee optimal play.',
|
|
263
|
+
'Makes one logical Jev request. Tests and demos are offline; live latency and playing strength have not been measured.',
|
|
264
|
+
],
|
|
265
|
+
useWhen: 'Your checkers game already provides its board, acting player, and legal moves, and you want a move ID without writing decision prompts.',
|
|
266
|
+
related: [
|
|
267
|
+
{
|
|
268
|
+
id: 'choose-action',
|
|
269
|
+
reason: 'Use choose-action for other games, checkers variants, or custom objectives. It accepts your rules and action descriptions instead of translating a checkers board.',
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
id: 'take-turn',
|
|
273
|
+
reason: 'Use take-turn for narrative turn eligibility. Checkers games should supply the known acting player directly without another model call.',
|
|
274
|
+
},
|
|
275
|
+
],
|
|
276
|
+
},
|
|
254
277
|
{
|
|
255
278
|
id: 'choose-action',
|
|
256
279
|
title: 'Choose a game action from supplied candidates',
|
|
@@ -273,6 +296,10 @@ export const recipeMetadata = [
|
|
|
273
296
|
],
|
|
274
297
|
useWhen: 'You need to choose the next game action from a list using the current environment, game rules, and previous player actions.',
|
|
275
298
|
related: [
|
|
299
|
+
{
|
|
300
|
+
id: 'checkers-move',
|
|
301
|
+
reason: 'Use checkers-move for a structured American/English checkers board and legal moves, with built-in rules and move descriptions.',
|
|
302
|
+
},
|
|
276
303
|
{
|
|
277
304
|
id: 'take-turn',
|
|
278
305
|
reason: 'Use take-turn to assess whether the player has an opportunity to act now before selecting an action.',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const recipeNames: readonly ["action-scope", "answer-consistency", "answer-coverage", "answer-invalidation", "answer-relevance", "answerability", "argument-fit", "attempted-step", "attribution-match", "audience-fit", "cache-match", "cancellation-check", "certainty-match", "change-meaning", "choose-action", "citation-match", "citation-needed", "claim-stance", "clarify", "confirmation-match", "constraint-strength", "context-role", "correction-target", "document-role", "draft-compare", "evaluation-mention", "evidence-conflict", "evidence-independence", "evidence-novelty", "fact-stability", "failure-kind", "feedback-kind", "field-select", "followup-link", "freshness-needed", "frustration-signal", "handoff", "incident-match", "instruction-conflict", "instruction-fit", "intent-change", "issue-impact", "memory-relation", "memory-scope", "memory-value", "passage-duplicate", "preference-kind", "promise-check", "query-equivalence", "query-specificity", "question-leading", "reference-resolve", "repeated-attempt", "reply-template-match", "requirement-testability", "rerank", "resolution-check", "response-needed", "response-refusal", "result-outcome", "result-usefulness", "retrieval-needed", "route", "source-applicability", "step-complete", "step-progress", "summary-coverage", "take-turn", "task-dependency", "task-duplicate", "ticket-match", "tone-check", "tool-fit", "topic-shift", "troubleshooting-fit", "turn-intent", "uncertainty-expression", "urgency-signal", "verify", "workaround-fit"];
|
|
1
|
+
export declare const recipeNames: readonly ["action-scope", "answer-consistency", "answer-coverage", "answer-invalidation", "answer-relevance", "answerability", "argument-fit", "attempted-step", "attribution-match", "audience-fit", "cache-match", "cancellation-check", "certainty-match", "change-meaning", "checkers-move", "choose-action", "citation-match", "citation-needed", "claim-stance", "clarify", "confirmation-match", "constraint-strength", "context-role", "correction-target", "document-role", "draft-compare", "evaluation-mention", "evidence-conflict", "evidence-independence", "evidence-novelty", "fact-stability", "failure-kind", "feedback-kind", "field-select", "followup-link", "freshness-needed", "frustration-signal", "handoff", "incident-match", "instruction-conflict", "instruction-fit", "intent-change", "issue-impact", "memory-relation", "memory-scope", "memory-value", "passage-duplicate", "preference-kind", "promise-check", "query-equivalence", "query-specificity", "question-leading", "reference-resolve", "repeated-attempt", "reply-template-match", "requirement-testability", "rerank", "resolution-check", "response-needed", "response-refusal", "result-outcome", "result-usefulness", "retrieval-needed", "route", "source-applicability", "step-complete", "step-progress", "summary-coverage", "take-turn", "task-dependency", "task-duplicate", "ticket-match", "tone-check", "tool-fit", "topic-shift", "troubleshooting-fit", "turn-intent", "uncertainty-expression", "urgency-signal", "verify", "workaround-fit"];
|
package/dist/catalog/schema.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare const recipeNameSchema: z.ZodEnum<{
|
|
|
14
14
|
"cancellation-check": "cancellation-check";
|
|
15
15
|
"certainty-match": "certainty-match";
|
|
16
16
|
"change-meaning": "change-meaning";
|
|
17
|
+
"checkers-move": "checkers-move";
|
|
17
18
|
"choose-action": "choose-action";
|
|
18
19
|
"citation-match": "citation-match";
|
|
19
20
|
"citation-needed": "citation-needed";
|
package/dist/cli/schema.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ export declare const commandArgumentsSchema: z.ZodUnion<readonly [z.ZodTuple<[z.
|
|
|
17
17
|
"cancellation-check": "cancellation-check";
|
|
18
18
|
"certainty-match": "certainty-match";
|
|
19
19
|
"change-meaning": "change-meaning";
|
|
20
|
+
"checkers-move": "checkers-move";
|
|
20
21
|
"choose-action": "choose-action";
|
|
21
22
|
"citation-match": "citation-match";
|
|
22
23
|
"citation-needed": "citation-needed";
|
|
@@ -101,6 +102,7 @@ export declare const commandArgumentsSchema: z.ZodUnion<readonly [z.ZodTuple<[z.
|
|
|
101
102
|
"cancellation-check": "cancellation-check";
|
|
102
103
|
"certainty-match": "certainty-match";
|
|
103
104
|
"change-meaning": "change-meaning";
|
|
105
|
+
"checkers-move": "checkers-move";
|
|
104
106
|
"choose-action": "choose-action";
|
|
105
107
|
"citation-match": "citation-match";
|
|
106
108
|
"citation-needed": "citation-needed";
|
|
@@ -182,6 +184,7 @@ export declare const commandArgumentsSchema: z.ZodUnion<readonly [z.ZodTuple<[z.
|
|
|
182
184
|
"cancellation-check": "cancellation-check";
|
|
183
185
|
"certainty-match": "certainty-match";
|
|
184
186
|
"change-meaning": "change-meaning";
|
|
187
|
+
"checkers-move": "checkers-move";
|
|
185
188
|
"choose-action": "choose-action";
|
|
186
189
|
"citation-match": "citation-match";
|
|
187
190
|
"citation-needed": "citation-needed";
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"input": {
|
|
3
|
+
"board": [
|
|
4
|
+
{
|
|
5
|
+
"square": "c3",
|
|
6
|
+
"player": "red"
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
"square": "b4",
|
|
10
|
+
"player": "black"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"square": "d4",
|
|
14
|
+
"player": "black"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"square": "f6",
|
|
18
|
+
"player": "black",
|
|
19
|
+
"king": true
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"player": "red",
|
|
23
|
+
"legalMoves": [
|
|
24
|
+
{
|
|
25
|
+
"id": "capture-left",
|
|
26
|
+
"from": "c3",
|
|
27
|
+
"path": ["a5"],
|
|
28
|
+
"captures": ["b4"]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": "capture-right",
|
|
32
|
+
"from": "c3",
|
|
33
|
+
"path": ["e5", "g7"],
|
|
34
|
+
"captures": ["d4", "f6"]
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
"response": {
|
|
39
|
+
"model": "demo-fixture",
|
|
40
|
+
"usage": {
|
|
41
|
+
"input_tokens": 0,
|
|
42
|
+
"output_tokens": 0
|
|
43
|
+
},
|
|
44
|
+
"answers": {
|
|
45
|
+
"decision": {
|
|
46
|
+
"type": "choice",
|
|
47
|
+
"choice": "candidate_1",
|
|
48
|
+
"confidence": 0.94,
|
|
49
|
+
"probabilities": {
|
|
50
|
+
"candidate_0": 0.02,
|
|
51
|
+
"candidate_1": 0.94,
|
|
52
|
+
"none": 0.02,
|
|
53
|
+
"ambiguous": 0.02
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { RecipeOptions } from '../../src/schema.js';
|
|
2
|
+
import type { CheckersMoveInput, CheckersMoveResult } from './schema.js';
|
|
3
|
+
export declare function checkersMove(input: CheckersMoveInput, options?: RecipeOptions): Promise<CheckersMoveResult>;
|
|
4
|
+
export { checkersMoveInputSchema, checkersMoveResultSchema } from './schema.js';
|
|
5
|
+
export type { CheckersMoveInput, CheckersMoveResult } from './schema.js';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { selectCandidate } from '../../src/selection.js';
|
|
2
|
+
import { checkersMoveInputSchema, checkersMoveResultSchema } from './schema.js';
|
|
3
|
+
export async function checkersMove(input, options = {}) {
|
|
4
|
+
const { board, player, legalMoves, minConfidence = 0.8 } = checkersMoveInputSchema.parse(input);
|
|
5
|
+
const pieces = new Map(board.map((piece) => [piece.square, piece]));
|
|
6
|
+
const material = { you: { men: 0, kings: 0 }, opponent: { men: 0, kings: 0 } };
|
|
7
|
+
const position = board.map((piece) => {
|
|
8
|
+
const owner = piece.player === player ? 'you' : 'opponent';
|
|
9
|
+
material[owner][piece.king ? 'kings' : 'men'] += 1;
|
|
10
|
+
return `${piece.square}: ${owner === 'you' ? 'your' : 'opponent'} ${piece.king ? 'king' : 'man'}`;
|
|
11
|
+
});
|
|
12
|
+
const candidates = legalMoves.map((move) => {
|
|
13
|
+
// References and nonempty paths are checked by the input schema.
|
|
14
|
+
const piece = pieces.get(move.from);
|
|
15
|
+
const captures = (move.captures ?? []).map((square) => `opponent ${pieces.get(square).king ? 'king' : 'man'} at ${square}`);
|
|
16
|
+
const promotes = !piece.king && move.path.at(-1).endsWith(player === 'red' ? '8' : '1');
|
|
17
|
+
return {
|
|
18
|
+
id: move.id,
|
|
19
|
+
text: `Move your ${piece.king ? 'king' : 'man'} from ${move.from} to ${move.path.join(' then ')}. ` +
|
|
20
|
+
`Captures: ${captures.length ? captures.join(', ') : 'none'}.` +
|
|
21
|
+
(promotes ? ' Promotes to king and ends the turn.' : ''),
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
const decision = await selectCandidate({ player, board: position.join('\n'), material }, candidates, 'Choose the supplied move that best advances winning for player in American/English checkers on an 8x8 board. ' +
|
|
25
|
+
'Coordinates are fixed: a1 is bottom left, a-h run left to right, ranks 1-8 run bottom to top. Only dark squares are playable. ' +
|
|
26
|
+
'Red men move and capture toward rank 8; black men toward rank 1. Kings move one diagonal square or jump an adjacent opponent in either direction, not flying kings. ' +
|
|
27
|
+
"Captures are compulsory; each candidate includes its complete jump sequence. Among capture alternatives, taking the most pieces is not compulsory. Reaching the promotion rank ends a man's turn. " +
|
|
28
|
+
'The caller supplies the full current board and legal moves for the acting player. Unlisted squares are empty. Compare those candidates without inventing moves or reconstructing game history. ' +
|
|
29
|
+
'Win by leaving the opponent without pieces or legal moves. Consider immediate wins, material including kings, vulnerability to replies, promotion, and mobility. More captures alone do not establish a better move. ' +
|
|
30
|
+
'Use the supplied material counts; do not assume a draw history or hidden search results. Future uncertainty alone is not ambiguity, but an unresolved tie or insufficient facts to prefer one move requires ambiguous. ' +
|
|
31
|
+
'Choose none only if no supplied candidate can be used because the supplied position and candidates conflict. Recommend a move without executing it or claiming optimal play.', minConfidence, options);
|
|
32
|
+
return checkersMoveResultSchema.parse(decision);
|
|
33
|
+
}
|
|
34
|
+
export { checkersMoveInputSchema, checkersMoveResultSchema } from './schema.js';
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const checkersMoveInputSchema: z.ZodObject<{
|
|
3
|
+
board: z.ZodArray<z.ZodObject<{
|
|
4
|
+
square: z.ZodString;
|
|
5
|
+
player: z.ZodEnum<{
|
|
6
|
+
red: "red";
|
|
7
|
+
black: "black";
|
|
8
|
+
}>;
|
|
9
|
+
king: z.ZodOptional<z.ZodBoolean>;
|
|
10
|
+
}, z.core.$strict>>;
|
|
11
|
+
player: z.ZodEnum<{
|
|
12
|
+
red: "red";
|
|
13
|
+
black: "black";
|
|
14
|
+
}>;
|
|
15
|
+
legalMoves: z.ZodArray<z.ZodObject<{
|
|
16
|
+
id: z.ZodString;
|
|
17
|
+
from: z.ZodString;
|
|
18
|
+
path: z.ZodArray<z.ZodString>;
|
|
19
|
+
captures: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
20
|
+
}, z.core.$strict>>;
|
|
21
|
+
minConfidence: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
}, z.core.$strict>;
|
|
23
|
+
export declare const checkersMoveResultSchema: z.ZodObject<{
|
|
24
|
+
model: z.ZodString;
|
|
25
|
+
usage: z.ZodObject<{
|
|
26
|
+
input_tokens: z.ZodNumber;
|
|
27
|
+
output_tokens: z.ZodNumber;
|
|
28
|
+
}, z.core.$strip>;
|
|
29
|
+
status: z.ZodEnum<{
|
|
30
|
+
ready: "ready";
|
|
31
|
+
review: "review";
|
|
32
|
+
}>;
|
|
33
|
+
verdict: z.ZodEnum<{
|
|
34
|
+
matched: "matched";
|
|
35
|
+
none: "none";
|
|
36
|
+
ambiguous: "ambiguous";
|
|
37
|
+
}>;
|
|
38
|
+
selection: z.ZodNullable<z.ZodString>;
|
|
39
|
+
suggestedSelection: z.ZodNullable<z.ZodString>;
|
|
40
|
+
confidence: z.ZodNumber;
|
|
41
|
+
probabilities: z.ZodObject<{
|
|
42
|
+
candidates: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
43
|
+
none: z.ZodNumber;
|
|
44
|
+
ambiguous: z.ZodNumber;
|
|
45
|
+
}, z.core.$strip>;
|
|
46
|
+
}, z.core.$strip>;
|
|
47
|
+
export type CheckersMoveInput = z.infer<typeof checkersMoveInputSchema>;
|
|
48
|
+
export type CheckersMoveResult = z.infer<typeof checkersMoveResultSchema>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { nonEmptyText, probability, selectionResultSchema } from '../../src/schema.js';
|
|
3
|
+
const player = z.enum(['red', 'black']);
|
|
4
|
+
const square = z
|
|
5
|
+
.string()
|
|
6
|
+
.regex(/^(?:[aceg][1357]|[bdfh][2468])$/)
|
|
7
|
+
.describe('A playable square: a1 is bottom left; files a-h, ranks 1-8.');
|
|
8
|
+
const piece = z.strictObject({
|
|
9
|
+
square,
|
|
10
|
+
player,
|
|
11
|
+
king: z.boolean().optional().describe('True for a king; omitted or false for a man.'),
|
|
12
|
+
});
|
|
13
|
+
const move = z
|
|
14
|
+
.strictObject({
|
|
15
|
+
id: nonEmptyText
|
|
16
|
+
.refine((value) => value !== '__proto__', 'This ID is reserved by result serialization.')
|
|
17
|
+
.describe('Your move ID, returned unchanged when selected. __proto__ is reserved.'),
|
|
18
|
+
from: square,
|
|
19
|
+
path: z
|
|
20
|
+
.array(square)
|
|
21
|
+
.min(1)
|
|
22
|
+
.max(12)
|
|
23
|
+
.describe('Every landing square in order, excluding from. Include the full jump sequence.'),
|
|
24
|
+
captures: z
|
|
25
|
+
.array(square)
|
|
26
|
+
.max(12)
|
|
27
|
+
.optional()
|
|
28
|
+
.describe('Captured piece squares in jump order. Omit or use [] for an ordinary move.'),
|
|
29
|
+
})
|
|
30
|
+
.refine((value) => new Set(value.captures).size === (value.captures?.length ?? 0), 'A piece cannot be captured twice in one move.')
|
|
31
|
+
.refine((value) => value.path.length === Math.max(1, value.captures?.length ?? 0), 'Use one landing for an ordinary move, or one landing per captured piece.');
|
|
32
|
+
export const checkersMoveInputSchema = z
|
|
33
|
+
.strictObject({
|
|
34
|
+
board: z
|
|
35
|
+
.array(piece)
|
|
36
|
+
.min(1)
|
|
37
|
+
.max(24)
|
|
38
|
+
.refine((pieces) => new Set(pieces.map((value) => value.square)).size === pieces.length, 'Each board square can hold only one piece.')
|
|
39
|
+
.refine((pieces) => pieces.filter((value) => value.player === 'red').length <= 12 &&
|
|
40
|
+
pieces.filter((value) => value.player === 'black').length <= 12, 'Each player can have at most twelve pieces.')
|
|
41
|
+
.describe('All remaining pieces. Unlisted squares are empty; red moves toward rank 8, black toward rank 1.'),
|
|
42
|
+
player: player.describe('The side whose turn it is and whose move should be chosen.'),
|
|
43
|
+
legalMoves: z
|
|
44
|
+
.array(move)
|
|
45
|
+
.min(1)
|
|
46
|
+
.max(50)
|
|
47
|
+
.refine((moves) => new Set(moves.map((value) => value.id)).size === moves.length, 'Move IDs must be unique.')
|
|
48
|
+
.describe('One to fifty complete legal moves from your game, with unique IDs.'),
|
|
49
|
+
minConfidence: probability.optional(),
|
|
50
|
+
})
|
|
51
|
+
.superRefine((input, context) => {
|
|
52
|
+
const pieces = new Map(input.board.map((value) => [value.square, value]));
|
|
53
|
+
input.legalMoves.forEach((value, index) => {
|
|
54
|
+
if (pieces.get(value.from)?.player !== input.player) {
|
|
55
|
+
context.addIssue({
|
|
56
|
+
code: 'custom',
|
|
57
|
+
path: ['legalMoves', index, 'from'],
|
|
58
|
+
message: 'The starting square must contain a piece owned by player.',
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
value.captures?.forEach((captured, captureIndex) => {
|
|
62
|
+
const target = pieces.get(captured);
|
|
63
|
+
if (target === undefined || target.player === input.player) {
|
|
64
|
+
context.addIssue({
|
|
65
|
+
code: 'custom',
|
|
66
|
+
path: ['legalMoves', index, 'captures', captureIndex],
|
|
67
|
+
message: 'Each captured square must contain an opponent piece.',
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
export const checkersMoveResultSchema = selectionResultSchema;
|
package/dist/src/index.d.ts
CHANGED
|
@@ -30,6 +30,8 @@ export { certaintyMatch, certaintyMatchInputSchema, certaintyMatchResultSchema,
|
|
|
30
30
|
export type { CertaintyMatchInput, CertaintyMatchResult, CertaintyMatchVerdict, } from '../recipes/certainty-match/index.js';
|
|
31
31
|
export { changeMeaning, changeMeaningInputSchema, changeMeaningResultSchema, changeMeaningVerdictSchema, } from '../recipes/change-meaning/index.js';
|
|
32
32
|
export type { ChangeMeaningInput, ChangeMeaningResult, ChangeMeaningVerdict, } from '../recipes/change-meaning/index.js';
|
|
33
|
+
export { checkersMove, checkersMoveInputSchema, checkersMoveResultSchema, } from '../recipes/checkers-move/index.js';
|
|
34
|
+
export type { CheckersMoveInput, CheckersMoveResult } from '../recipes/checkers-move/index.js';
|
|
33
35
|
export { chooseAction, chooseActionInputSchema, chooseActionResultSchema, } from '../recipes/choose-action/index.js';
|
|
34
36
|
export type { ChooseActionInput, ChooseActionResult } from '../recipes/choose-action/index.js';
|
|
35
37
|
export { citationMatch, citationMatchInputSchema, citationMatchResultSchema, } from '../recipes/citation-match/index.js';
|
package/dist/src/index.js
CHANGED
|
@@ -15,6 +15,7 @@ export { cacheMatch, cacheMatchInputSchema, cacheMatchResultSchema, cacheMatchVe
|
|
|
15
15
|
export { cancellationCheck, cancellationCheckInputSchema, cancellationCheckResultSchema, cancellationCheckVerdictSchema, } from '../recipes/cancellation-check/index.js';
|
|
16
16
|
export { certaintyMatch, certaintyMatchInputSchema, certaintyMatchResultSchema, certaintyMatchVerdictSchema, } from '../recipes/certainty-match/index.js';
|
|
17
17
|
export { changeMeaning, changeMeaningInputSchema, changeMeaningResultSchema, changeMeaningVerdictSchema, } from '../recipes/change-meaning/index.js';
|
|
18
|
+
export { checkersMove, checkersMoveInputSchema, checkersMoveResultSchema, } from '../recipes/checkers-move/index.js';
|
|
18
19
|
export { chooseAction, chooseActionInputSchema, chooseActionResultSchema, } from '../recipes/choose-action/index.js';
|
|
19
20
|
export { citationMatch, citationMatchInputSchema, citationMatchResultSchema, } from '../recipes/citation-match/index.js';
|
|
20
21
|
export { citationNeeded, citationNeededInputSchema, citationNeededResultSchema, citationNeededVerdictSchema, } from '../recipes/citation-needed/index.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jev-recipes",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Small, composable Jev decisions for retrieval, conversations, and agent workflows.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -80,6 +80,10 @@
|
|
|
80
80
|
"types": "./dist/recipes/change-meaning/index.d.ts",
|
|
81
81
|
"import": "./dist/recipes/change-meaning/index.js"
|
|
82
82
|
},
|
|
83
|
+
"./checkers-move": {
|
|
84
|
+
"types": "./dist/recipes/checkers-move/index.d.ts",
|
|
85
|
+
"import": "./dist/recipes/checkers-move/index.js"
|
|
86
|
+
},
|
|
83
87
|
"./choose-action": {
|
|
84
88
|
"types": "./dist/recipes/choose-action/index.d.ts",
|
|
85
89
|
"import": "./dist/recipes/choose-action/index.js"
|