Skip to content

Commit 661fd5b

Browse files
author
colinmcneil
committed
Preload prompts image
Handle `error` messages
1 parent 6e91480 commit 661fd5b

File tree

2 files changed

+84
-51
lines changed

2 files changed

+84
-51
lines changed

src/extension/ui/src/App.tsx

Lines changed: 81 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,46 @@ const client = createDockerDesktopClient();
1313
const track = (event: string) =>
1414
client.extension.vm?.service?.post('/analytics/track', { event });
1515

16+
class OutputParser {
17+
output: any[] = [];
18+
callback: (output: any[]) => void;
19+
constructor(callback: (output: any[]) => void) {
20+
this.output = [];
21+
this.callback = callback;
22+
}
23+
updateOutput = (line: any) => {
24+
let output = [...this.output];
25+
if (line.method === 'functions') {
26+
const functions = line.params;
27+
for (const func of functions) {
28+
const functionId = func.id;
29+
const existingFunction = output.find(o =>
30+
o.method === 'functions'
31+
&&
32+
o.params.find((p: { id: string }) => p.id === functionId)
33+
);
34+
if (existingFunction) {
35+
const existingFunctionParamsIndex = existingFunction.params.findIndex((p: { id: string }) => p.id === functionId);
36+
existingFunction.params[existingFunctionParamsIndex] = { ...existingFunction.params[existingFunctionParamsIndex], ...func };
37+
output = output.map(
38+
o => o.method === 'functions'
39+
?
40+
{ ...o, params: o.params.map((p: { id: string }) => p.id === functionId ? { ...p, ...func } : p) }
41+
:
42+
o
43+
);
44+
} else {
45+
output = [...output, line];
46+
}
47+
}
48+
}
49+
else {
50+
output = [...output, line];
51+
}
52+
this.callback(output);
53+
}
54+
}
55+
1656
const debounce = (fn: Function, ms: number) => {
1757
let timeout: NodeJS.Timeout;
1858
return function (...args: any) {
@@ -40,6 +80,39 @@ export function App() {
4080

4181
const [showDebug, setShowDebug] = React.useState(false);
4282

83+
useEffect(() => {
84+
const runOutput = new OutputParser(setRunOut);
85+
try {
86+
client.docker.cli.exec("pull", ["vonwig/function_write_files"]).then(() => {
87+
client.docker.cli.exec("run", [
88+
"-v",
89+
"openai_key:/root",
90+
"--workdir", "/root",
91+
"vonwig/function_write_files",
92+
`'` + JSON.stringify({ files: [{ path: ".openai-api-key", content: openAIKey, executable: false }] }) + `'`
93+
]);
94+
});
95+
client.docker.cli.exec("pull", ["vonwig/prompts"], {
96+
stream: {
97+
onOutput: ({ stdout, stderr }) => {
98+
if (stdout) {
99+
runOutput.updateOutput({ method: 'message', params: { debug: stdout } });
100+
}
101+
if (stderr) {
102+
runOutput.updateOutput({ method: 'error', params: { content: stderr } });
103+
}
104+
},
105+
onError: (err) => {
106+
runOutput.updateOutput({ method: 'error', params: { content: err } });
107+
},
108+
},
109+
});
110+
}
111+
catch (e) {
112+
runOutput.updateOutput({ method: 'message', params: { debug: JSON.stringify(e) } });
113+
}
114+
}, []);
115+
43116
useEffect(() => {
44117
localStorage.setItem('projects', JSON.stringify(projects));
45118
if (!selectedProject && projects.length > 0) {
@@ -94,54 +167,11 @@ export function App() {
94167

95168
const startPrompt = async () => {
96169
track('start-prompt');
97-
let output: any[] = []
98-
const updateOutput = (line: any) => {
99-
if (line.method === 'functions') {
100-
const functions = line.params;
101-
for (const func of functions) {
102-
const functionId = func.id;
103-
const existingFunction = output.find(o =>
104-
o.method === 'functions'
105-
&&
106-
o.params.find((p: { id: string }) => p.id === functionId)
107-
);
108-
if (existingFunction) {
109-
const existingFunctionParamsIndex = existingFunction.params.findIndex((p: { id: string }) => p.id === functionId);
110-
existingFunction.params[existingFunctionParamsIndex] = { ...existingFunction.params[existingFunctionParamsIndex], ...func };
111-
output = output.map(
112-
o => o.method === 'functions'
113-
?
114-
{ ...o, params: o.params.map((p: { id: string }) => p.id === functionId ? { ...p, ...func } : p) }
115-
:
116-
o
117-
);
118-
} else {
119-
output = [...output, line];
120-
}
121-
}
122-
}
123-
else {
124-
output = [...output, line];
125-
}
126-
setRunOut(output);
127-
}
128-
updateOutput({ method: 'message', params: { debug: 'Pulling images' } })
129-
try {
130-
const pullWriteFiles = await client.docker.cli.exec("pull", ["vonwig/function_write_files"]);
131-
const pullPrompts = await client.docker.cli.exec("pull", ["vonwig/prompts"]);
132-
const writeKey = await client.docker.cli.exec("run", [
133-
"-v",
134-
"openai_key:/root",
135-
"--workdir", "/root",
136-
"vonwig/function_write_files",
137-
`'` + JSON.stringify({ files: [{ path: ".openai-api-key", content: openAIKey, executable: false }] }) + `'`
138-
]);
139-
updateOutput({ method: 'message', params: { debug: JSON.stringify({ pullWriteFiles, pullPrompts, writeKey }) } });
140-
}
141-
catch (e) {
142-
updateOutput({ method: 'message', params: { debug: JSON.stringify(e) } });
143-
}
144-
updateOutput({ method: 'message', params: { debug: 'Running prompts...' } })
170+
171+
const runOutput = new OutputParser(setRunOut);
172+
runOutput.updateOutput({ method: 'message', params: { debug: 'Pulling images' } })
173+
174+
runOutput.updateOutput({ method: 'message', params: { debug: 'Running prompts...' } })
145175
const args = getRunArgs(selectedPrompt!, selectedProject!, "", client.host.platform)
146176

147177
client.docker.cli.exec("run", args, {
@@ -154,15 +184,15 @@ export function App() {
154184
rpcMessage += '}'
155185
}
156186
const json = JSON.parse(rpcMessage)
157-
updateOutput(json)
187+
runOutput.updateOutput(json)
158188
}
159189
if (stderr) {
160-
updateOutput({ method: 'message', params: { debug: stderr } });
190+
runOutput.updateOutput({ method: 'message', params: { debug: stderr } });
161191
}
162192
},
163193
onError: (err) => {
164194
console.error(err);
165-
updateOutput({ method: 'message', params: { debug: err } });
195+
runOutput.updateOutput({ method: 'message', params: { debug: err } });
166196
},
167197
}
168198
});

src/extension/ui/src/components/RunOutput.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ const RunOutput: React.FC<RunOutputProps> = ({ runOut, showDebug, setShowDebug }
3434
if (line.method === 'prompts') {
3535
return showDebug ? <Typography key={i} variant='body1' sx={{ whiteSpace: 'pre-wrap' }}>{JSON.stringify(line.params.messages, null, 2)}</Typography> : null;
3636
}
37+
if (line.method === 'error') {
38+
return <Typography key={i} variant='body1' sx={theme => ({ whiteSpace: 'pre-wrap', color: theme.palette.docker.red[500] })}>{line.params.content}</Typography>
39+
}
3740
return <Typography key={i} variant='body1'>{JSON.stringify(line)}</Typography>
3841
})}
3942
</div>

0 commit comments

Comments
 (0)