From 2c262ff8a6cf0c878d1c4f931b338d1c62fdd71d Mon Sep 17 00:00:00 2001 From: Liam Griffiths Date: Thu, 22 Aug 2024 11:36:55 -0400 Subject: [PATCH] Update chat example to use newer template (#10) * Update chat example to use newer template * Replace JS code with TS code in example README --- tutorials/chat-with-an-llm/README.md | 14 ++- tutorials/chat-with-an-llm/diagram.d2 | 43 +++++++ tutorials/chat-with-an-llm/diagram.svg | 111 ++++++++++++++++++ tutorials/chat-with-an-llm/python/.gitignore | 10 ++ tutorials/chat-with-an-llm/python/README.md | 26 ++++ tutorials/chat-with-an-llm/python/poetry.lock | 38 +++--- tutorials/chat-with-an-llm/python/poetry.toml | 1 - .../chat-with-an-llm/python/pyproject.toml | 10 +- .../python/src/{ => python}/__init__.py | 0 .../python/src/{ => python}/example.py | 1 + .../chat-with-an-llm/typescript/README.md | 28 +++++ .../typescript/{main.js => example.ts} | 10 +- .../typescript/package-lock.json | 32 +++-- .../chat-with-an-llm/typescript/package.json | 15 ++- .../chat-with-an-llm/typescript/tsconfig.json | 20 ++++ 15 files changed, 315 insertions(+), 44 deletions(-) create mode 100644 tutorials/chat-with-an-llm/diagram.d2 create mode 100644 tutorials/chat-with-an-llm/diagram.svg create mode 100644 tutorials/chat-with-an-llm/python/.gitignore create mode 100644 tutorials/chat-with-an-llm/python/README.md rename tutorials/chat-with-an-llm/python/src/{ => python}/__init__.py (100%) rename tutorials/chat-with-an-llm/python/src/{ => python}/example.py (99%) create mode 100644 tutorials/chat-with-an-llm/typescript/README.md rename tutorials/chat-with-an-llm/typescript/{main.js => example.ts} (79%) mode change 100644 => 100755 create mode 100644 tutorials/chat-with-an-llm/typescript/tsconfig.json diff --git a/tutorials/chat-with-an-llm/README.md b/tutorials/chat-with-an-llm/README.md index 4415521..62c28a8 100644 --- a/tutorials/chat-with-an-llm/README.md +++ b/tutorials/chat-with-an-llm/README.md @@ -20,7 +20,7 @@ npm start # Run the example cd python # Navigate to the python example poetry install # Install dependencies and build the example -poetry run python src/example.py # Run the example +poetry run main # Run the example ``` @@ -39,23 +39,24 @@ we will be including the chat history that includes both the user input and LLM In NodeJS we can use the following program: -```js +```typescript import readline from "node:readline"; import { Substrate, ComputeText } from "substrate"; const substrate = new Substrate({ apiKey: process.env["SUBSTRATE_API_KEY"] }); -const message = (role, content) => ({ role, content }); +type Message = { role: "user" | "assistant", content: string }; +const message = (role: Message["role"], content: Message["content"]): Message => ({ role, content }); -const blue = (text) => `\x1b[34m${text}\x1b[0m`; +const blue = (text: string) => `\x1b[34m${text}\x1b[0m`; const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); -const prompt = (log) => ` +const prompt = (log: Message[]) => ` You are a friendly assistant. Have fun engaging in the conversation. === Rules @@ -66,7 +67,7 @@ You are a friendly assistant. Have fun engaging in the conversation. === Chat Log ${log.map((m) => `[${m.role}]: ${m.content}`).join("\n\n")}`; -const continueThread = (log) => { +const continueThread = (log: Message[]) => { rl.question(`> `, async (userPrompt) => { log.push(message("user", userPrompt)); @@ -161,3 +162,4 @@ We could extend these simple examples in many different ways to suit a new speci updating the prompts to guide the LLM responses toward a particular tone or personality. If there is data we'd like the LLM to reference we could incorportate some context from a relevant data source. Enjoy exploring what's possible with Substrate. + diff --git a/tutorials/chat-with-an-llm/diagram.d2 b/tutorials/chat-with-an-llm/diagram.d2 new file mode 100644 index 0000000..43037e9 --- /dev/null +++ b/tutorials/chat-with-an-llm/diagram.d2 @@ -0,0 +1,43 @@ +direction: right +classes: { + substrate: { + label: "substrate" + style: { + font: mono + font-color: gray + font-size: 20 + stroke: gray + stroke-dash: 1 + fill: "transparent" + border-radius: 16 + } + } + node: { + style: { + font: mono + font-size: 24 + stroke-width: 2 + fill: transparent + stroke: gray + border-radius: 16 + stroke-dash: 1 + 3d: true + } + } + edge: { + style: { + stroke: "#000" + stroke-dash: 2 + } + } +} + +substrate.class: substrate +substrate.a.class: node +substrate.b.class: node +substrate.c.class: node +substrate.a.label: heuristic +substrate.b.label: symbolic +substrate.c.label: computation +substrate.a->substrate.c { class: edge } +substrate.b->substrate.c { class: edge } diff --git a/tutorials/chat-with-an-llm/diagram.svg b/tutorials/chat-with-an-llm/diagram.svg new file mode 100644 index 0000000..290d401 --- /dev/null +++ b/tutorials/chat-with-an-llm/diagram.svg @@ -0,0 +1,111 @@ +substrate + +heuristic + +symbolic + +computation + + + + + + diff --git a/tutorials/chat-with-an-llm/python/.gitignore b/tutorials/chat-with-an-llm/python/.gitignore new file mode 100644 index 0000000..ae8554d --- /dev/null +++ b/tutorials/chat-with-an-llm/python/.gitignore @@ -0,0 +1,10 @@ +# python generated files +__pycache__/ +*.py[oc] +build/ +dist/ +wheels/ +*.egg-info + +# venv +.venv diff --git a/tutorials/chat-with-an-llm/python/README.md b/tutorials/chat-with-an-llm/python/README.md new file mode 100644 index 0000000..8a1841b --- /dev/null +++ b/tutorials/chat-with-an-llm/python/README.md @@ -0,0 +1,26 @@ +# Substrate Example Templates in Python + +This is a Substrate example template written in Python. To run this example, + +```bash +# Set your API key as an environment variable. +# Get one here https://www.substrate.run/dashboard/keys if this is your first time. +export SUBSTRATE_API_KEY= + +# Navigate to the python example directory. +cd python +``` + +To run the example with Poetry (default), run the following. + +```bash +poetry install +poetry run main +``` + +To run the example with Rye, comment out the Poetry sections and uncomment the Rye sections in `pyproject.toml` and run the following. + +```bash +rye sync +rye run main +``` diff --git a/tutorials/chat-with-an-llm/python/poetry.lock b/tutorials/chat-with-an-llm/python/poetry.lock index 5d06810..d28ab5f 100644 --- a/tutorials/chat-with-an-llm/python/poetry.lock +++ b/tutorials/chat-with-an-llm/python/poetry.lock @@ -588,29 +588,29 @@ files = [ [[package]] name = "ruff" -version = "0.6.1" +version = "0.6.2" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.6.1-py3-none-linux_armv6l.whl", hash = "sha256:b4bb7de6a24169dc023f992718a9417380301b0c2da0fe85919f47264fb8add9"}, - {file = "ruff-0.6.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:45efaae53b360c81043e311cdec8a7696420b3d3e8935202c2846e7a97d4edae"}, - {file = "ruff-0.6.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:bc60c7d71b732c8fa73cf995efc0c836a2fd8b9810e115be8babb24ae87e0850"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c7477c3b9da822e2db0b4e0b59e61b8a23e87886e727b327e7dcaf06213c5cf"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a0af7ab3f86e3dc9f157a928e08e26c4b40707d0612b01cd577cc84b8905cc9"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:392688dbb50fecf1bf7126731c90c11a9df1c3a4cdc3f481b53e851da5634fa5"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5278d3e095ccc8c30430bcc9bc550f778790acc211865520f3041910a28d0024"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fe6d5f65d6f276ee7a0fc50a0cecaccb362d30ef98a110f99cac1c7872df2f18"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2e0dd11e2ae553ee5c92a81731d88a9883af8db7408db47fc81887c1f8b672e"}, - {file = "ruff-0.6.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d812615525a34ecfc07fd93f906ef5b93656be01dfae9a819e31caa6cfe758a1"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:faaa4060f4064c3b7aaaa27328080c932fa142786f8142aff095b42b6a2eb631"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:99d7ae0df47c62729d58765c593ea54c2546d5de213f2af2a19442d50a10cec9"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9eb18dfd7b613eec000e3738b3f0e4398bf0153cb80bfa3e351b3c1c2f6d7b15"}, - {file = "ruff-0.6.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:c62bc04c6723a81e25e71715aa59489f15034d69bf641df88cb38bdc32fd1dbb"}, - {file = "ruff-0.6.1-py3-none-win32.whl", hash = "sha256:9fb4c4e8b83f19c9477a8745e56d2eeef07a7ff50b68a6998f7d9e2e3887bdc4"}, - {file = "ruff-0.6.1-py3-none-win_amd64.whl", hash = "sha256:c2ebfc8f51ef4aca05dad4552bbcf6fe8d1f75b2f6af546cc47cc1c1ca916b5b"}, - {file = "ruff-0.6.1-py3-none-win_arm64.whl", hash = "sha256:3bc81074971b0ffad1bd0c52284b22411f02a11a012082a76ac6da153536e014"}, - {file = "ruff-0.6.1.tar.gz", hash = "sha256:af3ffd8c6563acb8848d33cd19a69b9bfe943667f0419ca083f8ebe4224a3436"}, + {file = "ruff-0.6.2-py3-none-linux_armv6l.whl", hash = "sha256:5c8cbc6252deb3ea840ad6a20b0f8583caab0c5ef4f9cca21adc5a92b8f79f3c"}, + {file = "ruff-0.6.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:17002fe241e76544448a8e1e6118abecbe8cd10cf68fde635dad480dba594570"}, + {file = "ruff-0.6.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:3dbeac76ed13456f8158b8f4fe087bf87882e645c8e8b606dd17b0b66c2c1158"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:094600ee88cda325988d3f54e3588c46de5c18dae09d683ace278b11f9d4d534"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:316d418fe258c036ba05fbf7dfc1f7d3d4096db63431546163b472285668132b"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d72b8b3abf8a2d51b7b9944a41307d2f442558ccb3859bbd87e6ae9be1694a5d"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2aed7e243be68487aa8982e91c6e260982d00da3f38955873aecd5a9204b1d66"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d371f7fc9cec83497fe7cf5eaf5b76e22a8efce463de5f775a1826197feb9df8"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8f310d63af08f583363dfb844ba8f9417b558199c58a5999215082036d795a1"}, + {file = "ruff-0.6.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7db6880c53c56addb8638fe444818183385ec85eeada1d48fc5abe045301b2f1"}, + {file = "ruff-0.6.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1175d39faadd9a50718f478d23bfc1d4da5743f1ab56af81a2b6caf0a2394f23"}, + {file = "ruff-0.6.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:5b939f9c86d51635fe486585389f54582f0d65b8238e08c327c1534844b3bb9a"}, + {file = "ruff-0.6.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d0d62ca91219f906caf9b187dea50d17353f15ec9bb15aae4a606cd697b49b4c"}, + {file = "ruff-0.6.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7438a7288f9d67ed3c8ce4d059e67f7ed65e9fe3aa2ab6f5b4b3610e57e3cb56"}, + {file = "ruff-0.6.2-py3-none-win32.whl", hash = "sha256:279d5f7d86696df5f9549b56b9b6a7f6c72961b619022b5b7999b15db392a4da"}, + {file = "ruff-0.6.2-py3-none-win_amd64.whl", hash = "sha256:d9f3469c7dd43cd22eb1c3fc16926fb8258d50cb1b216658a07be95dd117b0f2"}, + {file = "ruff-0.6.2-py3-none-win_arm64.whl", hash = "sha256:f28fcd2cd0e02bdf739297516d5643a945cc7caf09bd9bcb4d932540a5ea4fa9"}, + {file = "ruff-0.6.2.tar.gz", hash = "sha256:239ee6beb9e91feb8e0ec384204a763f36cb53fb895a1a364618c6abb076b3be"}, ] [[package]] diff --git a/tutorials/chat-with-an-llm/python/poetry.toml b/tutorials/chat-with-an-llm/python/poetry.toml index 2c2faf1..ab1033b 100644 --- a/tutorials/chat-with-an-llm/python/poetry.toml +++ b/tutorials/chat-with-an-llm/python/poetry.toml @@ -1,3 +1,2 @@ [virtualenvs] in-project = true - diff --git a/tutorials/chat-with-an-llm/python/pyproject.toml b/tutorials/chat-with-an-llm/python/pyproject.toml index 70a0434..18d6a28 100644 --- a/tutorials/chat-with-an-llm/python/pyproject.toml +++ b/tutorials/chat-with-an-llm/python/pyproject.toml @@ -1,6 +1,10 @@ [project] -name = "chat-with-an-llm" +name = "template" +version = "0.1.0" +description = "" +authors = [{ name = "Hanwen Wu", email = "hwwu@substrate.run" }] readme = "README.md" + requires-python = ">= 3.9" dependencies = ["substrate"] @@ -28,7 +32,7 @@ build-backend = "poetry.core.masonry.api" name = "template" version = "0.1.0" description = "" -authors = [] +authors = ["Hanwen Wu "] readme = "README.md" packages = [{ include = "python", from = "src" }] @@ -42,7 +46,7 @@ ruff = "^0.6.1" marimo = "^0.8.0" [tool.poetry.scripts] -main = "example:main" +main = "python.example:main" ########################### diff --git a/tutorials/chat-with-an-llm/python/src/__init__.py b/tutorials/chat-with-an-llm/python/src/python/__init__.py similarity index 100% rename from tutorials/chat-with-an-llm/python/src/__init__.py rename to tutorials/chat-with-an-llm/python/src/python/__init__.py diff --git a/tutorials/chat-with-an-llm/python/src/example.py b/tutorials/chat-with-an-llm/python/src/python/example.py similarity index 99% rename from tutorials/chat-with-an-llm/python/src/example.py rename to tutorials/chat-with-an-llm/python/src/python/example.py index a06ef00..2e94a1d 100644 --- a/tutorials/chat-with-an-llm/python/src/example.py +++ b/tutorials/chat-with-an-llm/python/src/python/example.py @@ -56,3 +56,4 @@ def main(): if __name__ == "__main__": main() + diff --git a/tutorials/chat-with-an-llm/typescript/README.md b/tutorials/chat-with-an-llm/typescript/README.md new file mode 100644 index 0000000..22230b4 --- /dev/null +++ b/tutorials/chat-with-an-llm/typescript/README.md @@ -0,0 +1,28 @@ +# Substrate Example Templates in Typescript + +This is a Substrate example template written in Typescript. To run this example, + +```bash +# Set your API key as an environment variable. +# Get one here https://www.substrate.run/dashboard/keys if this is your first time. +export SUBSTRATE_API_KEY= + +# Navigate to the python example directory. +cd typescript +``` + +To run the example with tsx (default), run the following. + +```bash +npx tsx ./example.ts + +# Or you can use the package.json scripts +npm run start +``` + +To run the example with Deno, uncomment the Deno sections in `example.ts` and +run the following. + +```bash +deno run ./example.ts +``` diff --git a/tutorials/chat-with-an-llm/typescript/main.js b/tutorials/chat-with-an-llm/typescript/example.ts old mode 100644 new mode 100755 similarity index 79% rename from tutorials/chat-with-an-llm/typescript/main.js rename to tutorials/chat-with-an-llm/typescript/example.ts index 7ffd9f6..68992fa --- a/tutorials/chat-with-an-llm/typescript/main.js +++ b/tutorials/chat-with-an-llm/typescript/example.ts @@ -4,16 +4,17 @@ import { Substrate, ComputeText } from "substrate"; const substrate = new Substrate({ apiKey: process.env["SUBSTRATE_API_KEY"] }); -const message = (role, content) => ({ role, content }); +type Message = { role: "user" | "assistant", content: string }; +const message = (role: Message["role"], content: Message["content"]): Message => ({ role, content }); -const blue = (text) => `\x1b[34m${text}\x1b[0m`; +const blue = (text: string) => `\x1b[34m${text}\x1b[0m`; const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); -const prompt = (log) => ` +const prompt = (log: Message[]) => ` You are a friendly assistant. Have fun engaging in the conversation. === Rules @@ -24,7 +25,7 @@ You are a friendly assistant. Have fun engaging in the conversation. === Chat Log ${log.map((m) => `[${m.role}]: ${m.content}`).join("\n\n")}`; -const continueThread = (log) => { +const continueThread = (log: Message[]) => { rl.question(`> `, async (userPrompt) => { log.push(message("user", userPrompt)); @@ -46,3 +47,4 @@ const continueThread = (log) => { }; console.log("=== Welcome to the chat! (use ^C to quit)"); continueThread([]); + diff --git a/tutorials/chat-with-an-llm/typescript/package-lock.json b/tutorials/chat-with-an-llm/typescript/package-lock.json index b32cb26..cc44abe 100644 --- a/tutorials/chat-with-an-llm/typescript/package-lock.json +++ b/tutorials/chat-with-an-llm/typescript/package-lock.json @@ -1,19 +1,24 @@ { - "name": "chat-with-an-llm", + "name": "substrate-example", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "chat-with-an-llm", - "license": "MIT", + "name": "substrate-example", + "version": "1.0.0", "dependencies": { - "substrate": "^120240617.1.9" + "substrate": "^120240617" + }, + "devDependencies": { + "@types/node": "^22", + "typescript": "^5" } }, "node_modules/@types/node": { - "version": "22.4.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.4.1.tgz", - "integrity": "sha512-1tbpb9325+gPnKK0dMm+/LMriX0vKxf6RnB0SZUqfyVkQ4fMgUSySqhxE/y8Jvs4NyF1yHzTfG9KlnkIODxPKg==", + "version": "22.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.0.tgz", + "integrity": "sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==", "dependencies": { "undici-types": "~6.19.2" } @@ -125,6 +130,19 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, + "node_modules/typescript": { + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", diff --git a/tutorials/chat-with-an-llm/typescript/package.json b/tutorials/chat-with-an-llm/typescript/package.json index 3867218..46cac12 100644 --- a/tutorials/chat-with-an-llm/typescript/package.json +++ b/tutorials/chat-with-an-llm/typescript/package.json @@ -1,11 +1,18 @@ { - "name": "chat-with-an-llm", + "name": "substrate-example", + "version": "1.0.0", + "private": "true", + "main": "example.ts", "type": "module", "scripts": { - "start": "node main.js" + "start": "npx tsx example.ts", + "typecheck": "tsc --noEmit" }, - "license": "MIT", "dependencies": { - "substrate": "^120240617.1.9" + "substrate": "^120240617" + }, + "devDependencies": { + "@types/node": "^22", + "typescript": "^5" } } diff --git a/tutorials/chat-with-an-llm/typescript/tsconfig.json b/tutorials/chat-with-an-llm/typescript/tsconfig.json new file mode 100644 index 0000000..2f3b370 --- /dev/null +++ b/tutorials/chat-with-an-llm/typescript/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "moduleDetection": "force", + "module": "Preserve", + "resolveJsonModule": true, + "allowJs": true, + "esModuleInterop": true, + "skipLibCheck": true, + "isolatedModules": true, + "strict": true, + "noEmit": true, + "moduleResolution": "node", + "jsx": "preserve", + "incremental": true, + "plugins": [{ "name": "next" }], + "paths": { "@/*": ["./*"] } + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], + "exclude": ["node_modules"] +}