Skip to content

Commit dcafea1

Browse files
authored
separate import json and extend in both seeder and jumble (#1093)
1 parent d3f98bf commit dcafea1

File tree

5 files changed

+102
-105
lines changed

5 files changed

+102
-105
lines changed

charm/src/commands.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { extractUserCode, injectUserCode } from "./iframe/static.ts";
66
import { compileAndRunRecipe, generateNewRecipeVersion } from "./iterate.ts";
77
import { NAME } from "@commontools/builder";
88
import { WorkflowForm } from "./index.ts";
9+
import { createJsonSchema, type JSONSchema } from "@commontools/builder";
910
import { processWorkflow, ProcessWorkflowOptions } from "./workflow.ts";
1011

1112
export const castSpellAsCharm = async (
@@ -32,6 +33,42 @@ export const castSpellAsCharm = async (
3233
return null;
3334
};
3435

36+
export const createDataCharm = (
37+
charmManager: CharmManager,
38+
data: Record<string, any>,
39+
schema?: JSONSchema,
40+
name?: string,
41+
) => {
42+
const argumentSchema = schema ?? createJsonSchema(data);
43+
44+
const schemaString = JSON.stringify(argumentSchema, null, 2);
45+
const result = Object.keys(argumentSchema.properties ?? {}).map((key) =>
46+
` ${key}: data.${key},\n`
47+
).join("\n");
48+
49+
const dataRecipeSrc = `import { h } from "@commontools/html";
50+
import { recipe, UI, NAME, derive, type JSONSchema } from "@commontools/builder";
51+
52+
const schema = ${schemaString};
53+
54+
export default recipe(schema, schema, (data) => ({
55+
[NAME]: "${name ?? "data import"}",
56+
[UI]: <div><h2>Your data has this schema</h2><pre>${
57+
schemaString.replaceAll("{", "&#123;")
58+
.replaceAll("}", "&#125;")
59+
.replaceAll("\n", "<br/>")
60+
}</pre></div>,
61+
${result}
62+
}));`;
63+
64+
return compileAndRunRecipe(
65+
charmManager,
66+
dataRecipeSrc,
67+
name ?? "data import",
68+
data,
69+
);
70+
};
71+
3572
export async function fixItCharm(
3673
charmManager: CharmManager,
3774
charm: Cell<Charm>,

charm/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export {
2222
export {
2323
addGithubRecipe,
2424
castSpellAsCharm,
25+
createDataCharm,
2526
fixItCharm,
2627
modifyCharm,
2728
renameCharm,

jumble/src/components/commands.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
Charm,
66
CharmManager,
77
compileAndRunRecipe,
8+
createDataCharm,
89
processWorkflow,
910
renameCharm,
1011
WorkflowForm,
@@ -354,17 +355,13 @@ async function handleImportJSON(ctx: CommandContext) {
354355
if (!title) return;
355356

356357
ctx.setOpen(false);
357-
const jsonPrompt = formatJsonImportPrompt(title, data);
358-
const form = await processWorkflow(
359-
jsonPrompt,
358+
359+
const newCharm = await createDataCharm(
360360
ctx.charmManager,
361-
{
362-
cache: true,
363-
dryRun: false,
364-
},
361+
data,
362+
undefined,
363+
title,
365364
);
366-
367-
const newCharm = form.generation?.charm;
368365
if (!newCharm) throw new Error("Failed to create new charm");
369366

370367
navigateToCharm(ctx, newCharm);

seeder/cli.ts

Lines changed: 7 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,11 @@ import {
77
import { getEntityId, setBobbyServerUrl, storage } from "@commontools/runner";
88
import { createSession, Identity } from "@commontools/identity";
99
import { LLMClient, setLLMUrl } from "@commontools/llm";
10-
import { processWorkflow } from "@commontools/charm";
10+
import { createDataCharm, processWorkflow } from "@commontools/charm";
1111
import { type CharmResult, CommandType, type Step } from "./interfaces.ts";
1212
import { scenarios } from "./scenarios.ts";
1313
import { toolshedUrl } from "./env.ts";
1414
import { llmVerifyCharm } from "./judge.ts";
15-
import {
16-
createJsonSchema,
17-
derive,
18-
NAME,
19-
recipe,
20-
UI,
21-
} from "@commontools/builder";
22-
import { h } from "@commontools/html";
2315
import { ensureReportDir, generateReport } from "./report.ts";
2416
import {
2517
addErrorListeners,
@@ -140,53 +132,18 @@ async function processCommand(
140132
throw new Error("Missing data for JSON import.");
141133
}
142134

143-
// FIXME(ja): we should move this to a common charm method so that
144-
// jumble and seeder can share
145-
const schema = step.dataSchema ?? createJsonSchema(step.data);
146-
const schemaString = JSON.stringify(schema, null, 2);
147-
const result = Object.keys(schema.properties ?? {}).map((key) =>
148-
` ${key}: data.${key},\n`
149-
).join("\n");
150-
151-
const dataRecipeSrc = `import { h } from "@commontools/html";
152-
import { recipe, UI, NAME, derive, type JSONSchema } from "@commontools/builder";
153-
154-
const schema = ${schemaString};
155-
156-
export default recipe(schema, schema, (data) => ({
157-
[NAME]: "Data Import",
158-
[UI]: <div><h2>schema</h2><pre>${
159-
schemaString.replaceAll("{", "&#123;")
160-
.replaceAll("}", "&#125;")
161-
.replaceAll("\n", "<br/>")
162-
}</pre></div>,
163-
${result}
164-
}));`;
165-
166-
const dataCharm = await compileAndRunRecipe(
135+
const charm = await createDataCharm(
167136
charmManager,
168-
dataRecipeSrc,
169-
"data import",
170137
step.data,
138+
step.dataSchema,
139+
prompt,
171140
);
172141

173-
const form = await processWorkflow(prompt, charmManager, {
174-
existingCharm: dataCharm,
175-
cache,
176-
prefill: {
177-
classification: {
178-
workflowType: "imagine",
179-
confidence: 1.0,
180-
reasoning: "hard coded",
181-
},
182-
},
183-
});
184-
185-
const newCharm = form.generation?.charm;
186-
const id = getEntityId(newCharm);
142+
const id = getEntityId(charm);
143+
console.log(`Charm added from JSON import`, { id });
187144
if (id) {
188145
console.log(`Charm added from JSON import: ${id["/"]}`);
189-
await verifyCharm(id["/"], prompt);
146+
await verifyCharm(id["/"], "shows a jsonschema for " + prompt);
190147
return id["/"];
191148
}
192149
break;

seeder/scenarios.ts

Lines changed: 51 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -218,58 +218,63 @@ Hierarchical integrity is maintained as subitems with their Parent items.
218218
{
219219
name: "Recipe Collection Manager",
220220
tags: ["import"],
221-
steps: [{
222-
type: CommandType.ImportJSON,
223-
prompt:
224-
"Recipe collection manager, the lets the user dream up new recipes using the LLM",
225-
dataSchema: {
226-
type: "object",
227-
properties: {
228-
"recipes": {
229-
type: "array",
230-
items: {
231-
"type": "object",
232-
"properties": {
233-
"name": { "type": "string" },
234-
"ingredients": {
235-
"type": "array",
236-
"items": { "type": "string" },
221+
steps: [
222+
{
223+
type: CommandType.ImportJSON,
224+
prompt: "Family Cookbook",
225+
dataSchema: {
226+
type: "object",
227+
properties: {
228+
"recipes": {
229+
type: "array",
230+
items: {
231+
"type": "object",
232+
"properties": {
233+
"name": { "type": "string" },
234+
"ingredients": {
235+
"type": "array",
236+
"items": { "type": "string" },
237+
},
238+
"instructions": { "type": "string" },
237239
},
238-
"instructions": { "type": "string" },
239240
},
240241
},
241242
},
242243
},
244+
data: {
245+
"recipes": [
246+
{
247+
"name": "Pasta Carbonara",
248+
"ingredients": [
249+
"200g spaghetti",
250+
"100g pancetta",
251+
"2 eggs",
252+
"50g pecorino cheese",
253+
"50g parmesan",
254+
"black pepper",
255+
],
256+
"instructions":
257+
"Cook pasta. Fry pancetta. Mix eggs and cheese. Combine all ingredients while pasta is hot.",
258+
},
259+
{
260+
"name": "Classic Margherita Pizza",
261+
"ingredients": [
262+
"pizza dough",
263+
"tomato sauce",
264+
"fresh mozzarella",
265+
"fresh basil",
266+
"olive oil",
267+
],
268+
"instructions":
269+
"Stretch dough. Add sauce, cheese. Bake at high heat. Add basil after cooking.",
270+
},
271+
],
272+
},
243273
},
244-
data: {
245-
"recipes": [
246-
{
247-
"name": "Pasta Carbonara",
248-
"ingredients": [
249-
"200g spaghetti",
250-
"100g pancetta",
251-
"2 eggs",
252-
"50g pecorino cheese",
253-
"50g parmesan",
254-
"black pepper",
255-
],
256-
"instructions":
257-
"Cook pasta. Fry pancetta. Mix eggs and cheese. Combine all ingredients while pasta is hot.",
258-
},
259-
{
260-
"name": "Classic Margherita Pizza",
261-
"ingredients": [
262-
"pizza dough",
263-
"tomato sauce",
264-
"fresh mozzarella",
265-
"fresh basil",
266-
"olive oil",
267-
],
268-
"instructions":
269-
"Stretch dough. Add sauce, cheese. Bake at high heat. Add basil after cooking.",
270-
},
271-
],
274+
{
275+
type: CommandType.Extend,
276+
prompt: "Allow user to find recipes by common ingredients",
272277
},
273-
}],
278+
],
274279
},
275280
];

0 commit comments

Comments
 (0)