Skip to content

Commit 3de0ec5

Browse files
committed
Run ui page
Signed-off-by: Nick Mitchell <[email protected]>
1 parent 948b5ab commit 3de0ec5

File tree

9 files changed

+170
-26
lines changed

9 files changed

+170
-26
lines changed

pdl-live-react/src-tauri/Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pdl-live-react/src-tauri/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ dirs = "6.0.0"
3636
serde_norway = "0.9.42"
3737
minijinja = { version = "2.9.0", features = ["custom_syntax"] }
3838
ollama-rs = { version = "0.3.0", features = ["tokio"] }
39-
tokio = "1.44.1"
4039
owo-colors = "4.2.0"
4140
rustpython-vm = "0.4.0"
4241

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use crate::pdl::interpreter::{pretty_print, run_string};
2+
3+
#[tauri::command]
4+
pub async fn run_pdl_program(program: String, debug: bool) -> Result<String, String> {
5+
let (messages, _) = run_string(&program, debug).map_err(|err| err.to_string())?;
6+
7+
Ok(pretty_print(&messages))
8+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
pub mod interpreter;
12
pub mod read_trace;
23
pub mod replay_prep;

pdl-live-react/src-tauri/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub fn run() {
3333
.invoke_handler(tauri::generate_handler![
3434
commands::read_trace::read_trace,
3535
commands::replay_prep::replay_prep,
36+
commands::interpreter::run_pdl_program,
3637
])
3738
.run(tauri::generate_context!())
3839
.expect("GUI opens")

pdl-live-react/src-tauri/src/pdl/interpreter.rs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ use ollama_rs::{
1919

2020
use serde_json::{from_str, to_string, Map, Value};
2121
use serde_norway::from_reader;
22-
use tokio::runtime::Runtime;
2322

2423
use crate::pdl::ast::{
2524
PdlBlock, PdlCallBlock, PdlModelBlock, PdlParser, PdlPythonCodeBlock, PdlRepeatBlock,
@@ -36,7 +35,7 @@ struct Interpreter<'a> {
3635
// cwd: Box<PathBuf>,
3736
// id_stack: Vec<String>,
3837
jinja_env: Environment<'a>,
39-
rt: Runtime,
38+
// rt: Runtime,
4039
scope: Vec<Scope>,
4140
debug: bool,
4241
emit: bool,
@@ -59,7 +58,7 @@ impl<'a> Interpreter<'a> {
5958
// cwd: Box::new(current_dir().unwrap_or(PathBuf::from("/"))),
6059
// id_stack: vec![],
6160
jinja_env: jinja_env,
62-
rt: Runtime::new().unwrap(),
61+
// rt: Runtime::new().unwrap(),
6362
scope: vec![Scope::new()],
6463
debug: false,
6564
emit: true,
@@ -90,7 +89,7 @@ impl<'a> Interpreter<'a> {
9089
_ => self.emit,
9190
} {
9291
// eprintln!("{:?}", program);
93-
pretty_print(&messages);
92+
println!("{}", pretty_print(&messages));
9493
}
9594
self.emit = prior_emit;
9695

@@ -320,7 +319,7 @@ impl<'a> Interpreter<'a> {
320319
let req = ChatMessageRequest::new(model.into(), vec![prompt.clone()])
321320
.options(options)
322321
.tools(tools);
323-
let res = self.rt.block_on(ollama.send_chat_messages_with_history(
322+
let res = /*self.rt.*/tauri::async_runtime::block_on(ollama.send_chat_messages_with_history(
324323
&mut history,
325324
req,
326325
//ollama.generate(GenerationRequest::new(model.into(), prompt),
@@ -474,23 +473,27 @@ pub fn run_json(source: Value, debug: bool) -> Interpretation {
474473
run_string(&to_string(&source)?, debug)
475474
}
476475

477-
fn pretty_print(messages: &Vec<ChatMessage>) {
478-
messages.into_iter().for_each(
479-
|ChatMessage {
480-
role: r,
481-
content: c,
482-
..
483-
}| {
484-
println!(
485-
"{:?}: {}",
486-
r.bold(),
487-
match r {
488-
MessageRole::Assistant => c.green().to_string(),
489-
MessageRole::System => c.cyan().to_string(),
490-
MessageRole::Tool => c.magenta().to_string(),
491-
_ => c.to_string(),
492-
}
493-
)
494-
},
495-
)
476+
pub fn pretty_print(messages: &Vec<ChatMessage>) -> String {
477+
messages
478+
.into_iter()
479+
.map(
480+
|ChatMessage {
481+
role: r,
482+
content: c,
483+
..
484+
}| {
485+
format!(
486+
"{:?}: {}",
487+
r.bold(),
488+
match r {
489+
MessageRole::Assistant => c.green().to_string(),
490+
MessageRole::System => c.cyan().to_string(),
491+
MessageRole::Tool => c.magenta().to_string(),
492+
_ => c.to_string(),
493+
}
494+
)
495+
},
496+
)
497+
.collect::<Vec<_>>()
498+
.join("\n")
496499
}

pdl-live-react/src/page/Run.tsx

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import { createRef, useEffect, useState } from "react"
2+
import { invoke } from "@tauri-apps/api/core"
3+
import { Terminal } from "@xterm/xterm"
4+
import { FitAddon } from "@xterm/addon-fit"
5+
import { ClipboardAddon } from "@xterm/addon-clipboard"
6+
import {
7+
Button,
8+
Panel,
9+
PanelHeader,
10+
PanelMain,
11+
PanelMainBody,
12+
PageSection,
13+
Split,
14+
SplitItem,
15+
TextArea,
16+
Toolbar,
17+
ToolbarItem,
18+
} from "@patternfly/react-core"
19+
20+
import Page from "./Page"
21+
import "../view/term/RunTerminal.css"
22+
23+
export default function Run() {
24+
const [input, setInput] = useState("")
25+
const [error, setError] = useState(false)
26+
27+
const ref = createRef<HTMLDivElement>()
28+
const [term, setTerm] = useState<null | Terminal>(null)
29+
30+
// Why a two-stage useEffect? Otherwise: cannot read properties of
31+
// undefined (reading 'dimensions')
32+
// See https://stackoverflow.com/a/78116690/5270773
33+
useEffect(() => {
34+
const term = new Terminal({
35+
fontFamily:
36+
'"Red Hat Mono", RedHatMono, "Courier New", Courier, monospace',
37+
fontSize: 12,
38+
convertEol: true,
39+
})
40+
setTerm(term)
41+
return () => {
42+
if (term) {
43+
term.dispose()
44+
}
45+
}
46+
}, [])
47+
48+
useEffect(() => {
49+
if (term && ref.current) {
50+
const fitAddon = new FitAddon()
51+
term.loadAddon(fitAddon)
52+
const clipboardAddon = new ClipboardAddon()
53+
term.loadAddon(clipboardAddon)
54+
55+
term.open(ref.current)
56+
fitAddon.fit()
57+
// term.focus()
58+
59+
// for debugging:
60+
// term.writeln(`Running ${cmd} ${args.join(" ")}`)
61+
}
62+
}, [term, ref])
63+
64+
const run = async () => {
65+
try {
66+
const result = await invoke("run_pdl_program", {
67+
program: input,
68+
debug: false,
69+
})
70+
term.write(result)
71+
console.error(result)
72+
} catch (err) {
73+
term.write(err)
74+
setError(true)
75+
}
76+
}
77+
78+
return (
79+
<Page breadcrumb1="Run">
80+
<PageSection>
81+
<Split hasGutter>
82+
<SplitItem isFilled>
83+
<Panel>
84+
<PanelHeader>Program</PanelHeader>
85+
<PanelMain>
86+
<PanelMainBody>
87+
<TextArea
88+
aria-label="text area to provide PDL program source"
89+
validated={!!error ? "error" : undefined}
90+
value={input}
91+
style={{ height: "600px" }}
92+
onChange={(_event, value) => {
93+
setError(null)
94+
setInput(value)
95+
term.clear()
96+
}}
97+
/>
98+
</PanelMainBody>
99+
</PanelMain>
100+
</Panel>
101+
</SplitItem>
102+
103+
<SplitItem>
104+
<Panel>
105+
<PanelHeader>Output</PanelHeader>
106+
<PanelMain>
107+
<PanelMainBody>
108+
<div
109+
className="pdl-run-terminal"
110+
ref={ref}
111+
style={{ height: "600px" }}
112+
/>
113+
</PanelMainBody>
114+
</PanelMain>
115+
</Panel>
116+
</SplitItem>
117+
</Split>
118+
119+
<Toolbar>
120+
<ToolbarItem>
121+
<Button onClick={run}>Run</Button>
122+
</ToolbarItem>
123+
</Toolbar>
124+
</PageSection>
125+
</Page>
126+
)
127+
}

pdl-live-react/src/page/welcome/Links.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { Link } from "react-router"
12
import { Button, Flex } from "@patternfly/react-core"
23

34
import ExternalLinkSquareAltIcon from "@patternfly/react-icons/dist/esm/icons/external-link-square-alt-icon"
@@ -29,6 +30,9 @@ export default function Links() {
2930
GitHub
3031
</a>
3132
</Button>
33+
<Button variant="link" isInline>
34+
<Link to="/run">Run</Link>
35+
</Button>
3236
</Flex>
3337
)
3438
}

pdl-live-react/src/routes/PdlRoutes.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import MyTraces from "../page/MyTracesPage"
66
import About from "../page/About"
77
import Local from "../page/Local"
88
import MyTrace from "../page/MyTrace"
9+
import Run from "../page/Run"
910
import Welcome from "../page/welcome/Welcome"
1011
import Uploader from "../page/Uploader"
1112
import ErrorBoundary from "../page/ErrorBoundary"
@@ -25,6 +26,7 @@ export default function PdlRoutes() {
2526
<Route path="upload" element={<Uploader />} />
2627
<Route path="my" element={<MyTraces />} />
2728
<Route path="demos" element={<Demos />} />
29+
<Route path="run" element={<Run />} />
2830

2931
{demos.map((demo, idx) => (
3032
<Route

0 commit comments

Comments
 (0)