Skip to content

Commit

Permalink
chore: simplify patch step improve performance
Browse files Browse the repository at this point in the history
  • Loading branch information
CNSeniorious000 committed Mar 6, 2024
1 parent 3869d34 commit 72f2a7f
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 84 deletions.
2 changes: 1 addition & 1 deletion _redirects
Original file line number Diff line number Diff line change
@@ -1 +1 @@
/pyodide/* https://promplate.dev/pyodide/:splat 200
/pyodide/* https://cdn.jsdelivr.net/pyodide/v0.25.0/full/:splat 200
26 changes: 13 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,35 @@
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
},
"devDependencies": {
"@antfu/eslint-config": "^2.6.4",
"@antfu/eslint-config": "^2.8.0",
"@ethercorps/sveltekit-og": "^3.0.0",
"@iconify/json": "^2.2.187",
"@iconify/json": "^2.2.189",
"@neodrag/svelte": "^2.0.3",
"@shikijs/rehype": "^1.1.7",
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@typescript-eslint/eslint-plugin": "^7.1.0",
"@typescript-eslint/parser": "^7.1.0",
"@sveltejs/adapter-auto": "^3.1.1",
"@sveltejs/kit": "^2.5.2",
"@sveltejs/vite-plugin-svelte": "^3.0.2",
"@typescript-eslint/eslint-plugin": "^7.1.1",
"@typescript-eslint/parser": "^7.1.1",
"@unocss/eslint-config": "^0.58.5",
"@unocss/extractor-svelte": "^0.58.5",
"@unocss/reset": "^0.58.5",
"eslint": "^8.57.0",
"eslint-plugin-format": "^0.1.0",
"eslint-plugin-svelte": "^2.35.1",
"openai": "^4.28.0",
"openai": "^4.28.4",
"pyodide": "^0.25.0",
"rehype-stringify": "^10.0.0",
"remark-parse": "^11.0.0",
"remark-rehype": "^11.1.0",
"shiki": "^1.1.7",
"svelte": "^4.2.7",
"svelte-check": "^3.6.0",
"svelte": "^4.2.12",
"svelte-check": "^3.6.6",
"svelte-sonner": "^0.3.19",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"tslib": "^2.6.2",
"typescript": "^5.3.3",
"unified": "^11.0.4",
"unocss": "^0.58.5",
"vite": "^5.0.3"
"vite": "^5.1.5"
}
}
6 changes: 3 additions & 3 deletions src/lib/pyodide/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
await install(
[
"promplate==0.3.3.4",
"promplate-pyodide==0.0.1",
"promplate-pyodide==0.0.2.3",
]
)
del install

from promplate_pyodide import patch_promplate
from promplate_pyodide import patch_all

patch_promplate(True)
await patch_all()

from promplate import *
from promplate.llm.openai import *
40 changes: 25 additions & 15 deletions src/lib/pyodide/init.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,50 @@
import type { ClientOptions } from "openai";

import { pyodideReady } from "../stores";
import * as env from "$env/static/public";
import { cacheSingleton } from "$lib/utils/cache";
import { getEnv } from "$lib/utils/env";
import { withToast } from "$lib/utils/toast";
import { toast } from "svelte-sonner";

const indexURL = typeof window === "undefined" ? undefined : (process.env.NODE_ENV === "production" && "/pyodide/") || "https://promplate.dev/pyodide/";
const indexURL = typeof window === "undefined" ? undefined : (process.env.NODE_ENV === "production" && "/pyodide/") || "https://cdn.jsdelivr.net/pyodide/v0.25.0/full/";

async function initPyodide() {
const { loadPyodide } = await import("pyodide");
return await loadPyodide({ indexURL, env: { ...env }, packages: ["micropip", "typing-extensions"] });
const py = await loadPyodide({ indexURL, env: getEnv(), packages: ["micropip", "typing-extensions"] });
pyodideReady.set(true);
return py;
}

const getPyodide = cacheSingleton(withToast(initPyodide, { loading: "loading pyodide runtime" }));

async function initPy() {
const [py, { AsyncClient }, version, { default: initCode }] = await Promise.all([
initPyodide(),
import("./translate"),
const [py, { OpenAI }, version, { default: initCode }] = await Promise.all([
getPyodide(),
import("openai"),
import("openai/version"),
import("./init.py?raw"),
]);
const info = toast.loading("installing extra python dependencies");

py.registerJsModule("openai", { AsyncClient, Client: () => null, version, __all__: [] });
py.registerJsModule("httpx", { AsyncClient: () => null, Client: () => null });

await py.runPythonAsync(initCode);
class PatchedOpenAI extends OpenAI {
constructor(options: ClientOptions) {
if (!options.apiKey)
(options.apiKey = env.PUBLIC_OPENAI_API_KEY);
if (!options.baseURL)
options.baseURL = env.PUBLIC_OPENAI_BASE_URL;
super(options);
}
}

toast.dismiss(info);
py.registerJsModule("openai", { OpenAI: PatchedOpenAI, version, __all__: [] });

pyodideReady.set(true);
await withToast(py.runPythonAsync.bind(null, initCode), { loading: "installing extra python dependencies", duration: 300 })();

return py;
}

export const getPy = cacheSingleton(withToast(initPy, { loading: "preparing pyodide runtime", success: `successfully initialized pyodide runtime` }));
export const getPy = cacheSingleton(initPy);

export async function initConsole() {
const [py, { default: initConsoleCode }] = await Promise.all([getPy(), import("./console.py?raw")]);
const [py, { default: initConsoleCode }] = await Promise.all([getPyodide(), import("./console.py?raw")]);
await py.runPythonAsync(initConsoleCode);
}
40 changes: 5 additions & 35 deletions src/lib/pyodide/translate.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import type * as Core from "openai/core";
import type { ClientOptions } from "openai";
import type { PyProxy } from "pyodide/ffi";

import { env } from "$env/dynamic/public";
import { type ClientOptions, OpenAI } from "openai";

interface PyClientOptions {
api_key?: string;
base_url?: string;
Expand Down Expand Up @@ -34,39 +31,12 @@ export async function toPyOptions(options: ClientOptions) {
} as PyClientOptions;
}

export function toJsOptions(options: PyClientOptions) {
return {
baseURL: options.base_url ?? env.PUBLIC_OPENAI_BASE_URL,
apiKey: options.api_key ?? env.PUBLIC_OPENAI_API_KEY ?? "",
organization: options.organization,
timeout: options.timeout,
maxRetries: options.max_retries,
defaultQuery: options.defaultQuery?.toJs() as Core.DefaultQuery,
defaultHeaders: options.defaultHeaders?.toJs() as Core.Headers,
dangerouslyAllowBrowser: true,
} as ClientOptions;
}

export function AsyncClient(options: PyClientOptions) {
return new OpenAI(toJsOptions(options));
}

export function toAsync(source: string) {
return source
.replaceAll(/(\S+|\(.*\))\.invoke/g, "await $1.ainvoke")
.replaceAll("ChatComplete", "AsyncChatComplete")
.replaceAll("complete(", "await complete(")
.replaceAll(/for (\w+) in generate/g, "async for $1 in generate");
}

export function patchSource(source: string) {
const shouldStrip = source.includes(">>> ");

return (
shouldStrip
? source.split("\n").filter(line => line.startsWith(">>>") || line.startsWith("...")).map(line => toAsync(line.slice(4)))
: source.split("\n").map(toAsync)
).join("\n");
source.includes(">>> ")
? source.split("\n").filter(line => line.startsWith(">>>") || line.startsWith("...")).map(line => line.slice(4)).join("\n")
: source
);
}

export function reformatInputSource(source: string) {
Expand Down
5 changes: 5 additions & 0 deletions src/lib/utils/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import * as env from "$env/static/public";

export function getEnv() {
return Object.fromEntries(Object.entries(env).map(([k, v]) => [k.replace("PUBLIC_", ""), v]));
}
5 changes: 4 additions & 1 deletion src/lib/utils/toast.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { tick } from "svelte";
import { toast } from "svelte-sonner";

export function withToast<T extends () => Promise<any>>(asyncFunction: T, data: { loading: string; success: string }): T {
export function withToast<T extends () => Promise<any>>(asyncFunction: T, data: { loading: string; success?: string; duration?: number }): T {
data.success = data.success ?? data.loading;
return (async () => {
const promise: Promise<ReturnType<T>> = asyncFunction();
await tick();
toast.promise(promise, data);
return await promise;
}) as T;
Expand Down
16 changes: 1 addition & 15 deletions src/routes/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
<script lang="ts">
import type { ActionData } from "./playground/$types";
import type { AutoComplete, Item } from "$lib/components/console/HeadlessConsole.svelte";
import type { Source } from "$lib/utils/source";
import type { PyProxy } from "pyodide/ffi";
import type { KeyboardEventHandler } from "svelte/elements";
import { page } from "$app/stores";
import { Err, In, Out, Repr } from "$lib/components/console";
import HeadlessConsole from "$lib/components/console/HeadlessConsole.svelte";
import ConsolePrompt from "$lib/components/ConsolePrompt.svelte";
import Modal from "$lib/components/Modal.svelte";
import { patchSource, reformatInputSource } from "$lib/pyodide/translate";
import { reformatInputSource } from "$lib/pyodide/translate";
import { pyodideReady } from "$lib/stores";
import { onMount } from "svelte";
import { cubicIn, cubicOut } from "svelte/easing";
import { scale } from "svelte/transition";
export let form: ActionData;
const { sources } = (form ?? $page.state) as { sources?: Source[] };
let log: Item[] = [];
const history: string[] = [];
Expand Down Expand Up @@ -65,13 +58,6 @@
let ready: boolean;
$: if (ready) {
(async () => {
if (sources?.length)
for (const { source, hidden, wait } of sources) await pushMany(patchSource(source).split("\n"), Boolean(wait), hidden);
})();
}
function handleInput() {
push(input);
if (input.trim() && input !== history[0]) {
Expand Down
2 changes: 1 addition & 1 deletion src/templates/groundings.j2
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Here are some groundings informations about the runtime environment:

Here are some information about the current conversation:

User's language preference: {{ js.navigator.languages }}
User's language preference: {{ js.navigator.language }}
Current datetime: {{ js.Date() }}

Answer in user's language.

0 comments on commit 72f2a7f

Please sign in to comment.