@jiggai/recipes 0.4.52 → 0.4.53
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.
|
@@ -56,7 +56,7 @@ When a node's `text` field contains JSON, ClawRecipes automatically extracts nes
|
|
|
56
56
|
### Available Template Variables
|
|
57
57
|
- `{{nodeId.text}}` — Raw JSON string
|
|
58
58
|
- `{{nodeId.title}}` — Extracted: "Product Launch"
|
|
59
|
-
- `{{nodeId.
|
|
59
|
+
- `{{nodeId.approved}}` — For non-string values: "true"
|
|
60
60
|
|
|
61
61
|
### Deeply Nested Extraction
|
|
62
62
|
If the JSON contains nested objects, fields are flattened:
|
|
@@ -68,7 +68,7 @@ If the JSON contains nested objects, fields are flattened:
|
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
Available as:
|
|
71
|
-
- `{{nodeId.
|
|
71
|
+
- `{{nodeId.meta}}` — Full meta object as JSON string
|
|
72
72
|
- `{{nodeId.author}}` — "John" (if meta.author is a string)
|
|
73
73
|
|
|
74
74
|
## LLM Node Structured Output
|
|
@@ -92,7 +92,7 @@ LLM nodes with `outputFields` configuration produce predictable JSON structures:
|
|
|
92
92
|
```
|
|
93
93
|
Title: {{nodeId.title}}
|
|
94
94
|
Tags: {{nodeId.tags}}
|
|
95
|
-
Metadata: {{nodeId.
|
|
95
|
+
Metadata: {{nodeId.metadata}}
|
|
96
96
|
```
|
|
97
97
|
|
|
98
98
|
## Usage Examples
|
|
@@ -144,7 +144,7 @@ Template substitution happens in the workflow worker during node execution. The
|
|
|
144
144
|
1. **Global vars** are built from run metadata and timestamps
|
|
145
145
|
2. **Node outputs** are loaded from each completed node's output file
|
|
146
146
|
3. **JSON parsing** attempts to extract fields from the `text` field
|
|
147
|
-
4. **Nested extraction** flattens nested objects
|
|
147
|
+
4. **Nested extraction** flattens nested objects, stringifying non-string values under their declared field name
|
|
148
148
|
5. **Template replacement** applies all variables using simple string substitution
|
|
149
149
|
|
|
150
150
|
### Performance Notes
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -161,26 +161,42 @@ export async function generateKitchenManifest(opts: GenerateManifestOptions): Pr
|
|
|
161
161
|
};
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
//
|
|
164
|
+
// Read agents directly from config (avoids subprocess which can silently fail)
|
|
165
165
|
let agents: AgentManifestEntry[] = [];
|
|
166
166
|
try {
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
167
|
+
const list = (api.config as { agents?: { list?: Array<Record<string, unknown>> } }).agents?.list;
|
|
168
|
+
if (Array.isArray(list)) {
|
|
169
|
+
agents = list.map((a) => ({
|
|
170
|
+
id: String(a.id ?? ''),
|
|
171
|
+
identityName: typeof (a.identity as Record<string, unknown> | undefined)?.name === 'string'
|
|
172
|
+
? (a.identity as { name: string }).name
|
|
173
|
+
: undefined,
|
|
174
|
+
workspace: typeof a.workspace === 'string' ? a.workspace : undefined,
|
|
175
|
+
model: typeof a.model === 'string' ? a.model : undefined,
|
|
176
|
+
isDefault: a.default === true,
|
|
177
|
+
})).filter((a) => a.id);
|
|
173
178
|
}
|
|
174
179
|
} catch { /* best-effort */ }
|
|
175
180
|
|
|
176
|
-
|
|
181
|
+
// Read recipes from filesystem (avoids subprocess which can silently fail)
|
|
182
|
+
const recipes: RecipeManifestEntry[] = [];
|
|
177
183
|
try {
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
);
|
|
182
|
-
|
|
183
|
-
|
|
184
|
+
const { listRecipeFiles } = await import('./recipes');
|
|
185
|
+
const { getRecipesConfig } = await import('./config');
|
|
186
|
+
const { parseFrontmatter } = await import('./recipe-frontmatter');
|
|
187
|
+
const cfg = getRecipesConfig(api.config);
|
|
188
|
+
const files = await listRecipeFiles(api, cfg);
|
|
189
|
+
for (const f of files) {
|
|
190
|
+
const md = await fs.readFile(f.path, 'utf8');
|
|
191
|
+
const { frontmatter } = parseFrontmatter(md);
|
|
192
|
+
if (frontmatter.id && frontmatter.name) {
|
|
193
|
+
recipes.push({
|
|
194
|
+
id: frontmatter.id,
|
|
195
|
+
name: frontmatter.name,
|
|
196
|
+
kind: frontmatter.kind === 'team' ? 'team' : 'agent',
|
|
197
|
+
source: f.source,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
184
200
|
}
|
|
185
201
|
} catch { /* best-effort */ }
|
|
186
202
|
|
|
@@ -167,14 +167,14 @@ async function buildTemplateVars(
|
|
|
167
167
|
if (typeof nestedValue === 'string') {
|
|
168
168
|
vars[`${nid}.${nestedKey}`] = nestedValue;
|
|
169
169
|
} else if (nestedValue !== null && nestedValue !== undefined) {
|
|
170
|
-
vars[`${nid}.${nestedKey}
|
|
170
|
+
vars[`${nid}.${nestedKey}`] = JSON.stringify(nestedValue);
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
}
|
|
174
174
|
} catch { /* nested parse fail is fine */ }
|
|
175
175
|
}
|
|
176
176
|
} else if (value !== null && value !== undefined) {
|
|
177
|
-
vars[`${nid}.${key}
|
|
177
|
+
vars[`${nid}.${key}`] = JSON.stringify(value);
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
}
|