Skip to content

Commit 47162ef

Browse files
committed
update dataDesigner
1 parent 43ef2fc commit 47162ef

File tree

2 files changed

+50
-31
lines changed

2 files changed

+50
-31
lines changed

typescript/packages/lookslike-high-level/src/recipes/dataDesigner.ts

Lines changed: 50 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import {
44
UI,
55
NAME,
66
lift,
7-
generateData,
7+
llm,
88
handler,
99
str,
1010
createJsonSchema,
11+
cell,
1112
} from "@commontools/common-builder";
1213

1314

@@ -25,12 +26,37 @@ const updateTitle = handler<{ detail: { value: string } }, { title: string }>(
2526
({ detail }, state) => detail?.value && (state.title = detail.value),
2627
);
2728

28-
const systemPrompt = `generate/modify a document based on input, respond within a json block , e.g.
29-
\`\`\`json
30-
...
31-
\`\`\`
29+
const buildPrompt = lift(({ prompt, data }) => {
30+
let fullPrompt = prompt;
31+
if (data) {
32+
fullPrompt += `\n\nHere's the previous JSON for reference:\n\`\`\`json\n${JSON.stringify(data, null, 2)}\n\`\`\``;
33+
}
3234

33-
No field can be set to null or undefined.`;
35+
return {
36+
messages: [fullPrompt, '```json\n'],
37+
system: `generate/modify a document based on input, respond within a json block , e.g.
38+
\`\`\`json
39+
...
40+
\`\`\`
41+
42+
No field can be set to null or undefined.`,
43+
stop: '```'
44+
}
45+
});
46+
47+
const grabJSON = lift<{ result?: string }, any>(({ result }) => {
48+
if (!result) {
49+
return {};
50+
}
51+
const jsonMatch = result.match(/```json\n([\s\S]+?)```/);
52+
if (!jsonMatch) {
53+
console.error("No JSON found in text:", result);
54+
return {};
55+
}
56+
let d = JSON.parse(jsonMatch[1]);
57+
console.log("grabJSON", d);
58+
return d;
59+
});
3460

3561
const deriveJsonSchema = lift(({ data }) => {
3662
const schema = createJsonSchema({}, data)?.["properties"];
@@ -49,27 +75,25 @@ const addToPrompt = handler<
4975
{ prompt: string },
5076
{ prompt: string; query: string }
5177
>((e, state) => {
52-
state.prompt += "\n" + e.prompt;
78+
state.prompt = (state.prompt ? state.prompt + "\n" : "") + e.prompt;
5379
state.query = state.prompt;
5480
});
5581

56-
const buildJSONGenMessages = lift(({ prompt, data }) => {
57-
console.log("prompt", prompt, data);
58-
let fullPrompt = prompt;
59-
if (data) {
60-
fullPrompt += `\n\nHere's the previous JSON for reference:\n\`\`\`json\n${JSON.stringify(data, null, 2)}\n\`\`\``;
61-
}
62-
return [fullPrompt, '```json\n']
63-
});
64-
65-
const onAcceptData = handler<void, { data: any; lastData: any; result: any }>(
82+
const onAcceptData = handler<void, { data: any; lastData: any; generatedData: any }>(
6683
(_, state) => {
67-
console.log("accept data", state.data, state.result);
6884
state.lastData = JSON.parse(JSON.stringify(state.data));
69-
state.data = JSON.parse(JSON.stringify(state.result))
85+
state.data = JSON.parse(JSON.stringify(state.generatedData))
7086
}
7187
);
7288

89+
const tail = lift<{ pending: boolean, partial?: string, lines: number }, string>(({ pending, partial, lines }) => {
90+
if (!partial || !pending) {
91+
return "";
92+
}
93+
return partial.split('\n').slice(-lines).join('\n');
94+
});
95+
96+
7397
export const dataDesigner = recipe<{
7498
title: string;
7599
prompt: string;
@@ -81,16 +105,12 @@ export const dataDesigner = recipe<{
81105

82106
const schema = deriveJsonSchema({ data });
83107
const query = copy({ value: prompt });
84-
const lastData = copy({ value: data });
85-
lastData.setDefault({});
108+
// using copy for lastData was causing re-running llm whenever data changed in iframes
109+
const lastData = cell({ key: 'value' })
86110
tap({ lastData });
87111

88-
const { result } = generateData<any>({
89-
messages: buildJSONGenMessages({ prompt, data: lastData }),
90-
system: systemPrompt,
91-
mode: "json",
92-
});
93-
tap({ result })
112+
const {result, pending, partial} = llm(buildPrompt({ prompt, data: lastData }));
113+
const generatedData = grabJSON({ result });
94114

95115
return {
96116
[NAME]: str`${title}`,
@@ -109,10 +129,10 @@ export const dataDesigner = recipe<{
109129
onkeyup=${onInput({ value: query })}
110130
style="width: 100%; min-height: 128px;"
111131
></textarea>
112-
113-
<pre>${formatData({ obj: result })}</pre>
132+
<pre>${tail({ partial, pending, lines: 5 })}
133+
<pre>${formatData({ obj: generatedData })}</pre>
114134
<common-button
115-
onclick=${onAcceptData({ data, lastData, result })}
135+
onclick=${onAcceptData({ data, lastData, generatedData })}
116136
>Accept</common-button>
117137
118138
</div>`,

typescript/packages/lookslike-high-level/src/recipes/prompts.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ const updateTitle = handler<{ detail: { value: string } }, { title: string }>(
3030
);
3131

3232
const grabPrompts = lift<{ result: string }, Prompt[]>(({ result }) => {
33-
console.log("grabPrompts", result);
3433
if (!result) {
3534
return [];
3635
}

0 commit comments

Comments
 (0)