main
reng 6 months ago
parent e4d173b0cd
commit 7df85e176a
  1. 335
      vite/package-lock.json
  2. 2
      vite/package.json
  3. 4
      vite/src-tauri/.gitignore
  4. 5261
      vite/src-tauri/Cargo.lock
  5. 29
      vite/src-tauri/Cargo.toml
  6. 3
      vite/src-tauri/build.rs
  7. 15
      vite/src-tauri/capabilities/default.json
  8. BIN
      vite/src-tauri/icons/128x128.png
  9. BIN
      vite/src-tauri/icons/128x128@2x.png
  10. BIN
      vite/src-tauri/icons/32x32.png
  11. BIN
      vite/src-tauri/icons/Square107x107Logo.png
  12. BIN
      vite/src-tauri/icons/Square142x142Logo.png
  13. BIN
      vite/src-tauri/icons/Square150x150Logo.png
  14. BIN
      vite/src-tauri/icons/Square284x284Logo.png
  15. BIN
      vite/src-tauri/icons/Square30x30Logo.png
  16. BIN
      vite/src-tauri/icons/Square310x310Logo.png
  17. BIN
      vite/src-tauri/icons/Square44x44Logo.png
  18. BIN
      vite/src-tauri/icons/Square71x71Logo.png
  19. BIN
      vite/src-tauri/icons/Square89x89Logo.png
  20. BIN
      vite/src-tauri/icons/StoreLogo.png
  21. BIN
      vite/src-tauri/icons/icon.icns
  22. BIN
      vite/src-tauri/icons/icon.ico
  23. BIN
      vite/src-tauri/icons/icon.png
  24. 71
      vite/src-tauri/src/lib.rs
  25. 6
      vite/src-tauri/src/main.rs
  26. 37
      vite/src-tauri/tauri.conf.json
  27. 52
      vite/src/App.jsx
  28. 80
      vite/src/util/chat.js
  29. 62
      vite/src/util/system_prompt.js

@ -9,12 +9,14 @@
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@tailwindcss/vite": "^4.1.8", "@tailwindcss/vite": "^4.1.8",
"@tauri-apps/plugin-http": "^2.4.4",
"react": "^19.1.0", "react": "^19.1.0",
"react-dom": "^19.1.0", "react-dom": "^19.1.0",
"tailwindcss": "^4.1.8" "tailwindcss": "^4.1.8"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.25.0", "@eslint/js": "^9.25.0",
"@tauri-apps/cli": "^2.5.0",
"@types/react": "^19.1.2", "@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2", "@types/react-dom": "^19.1.2",
"@vitejs/plugin-react-swc": "^3.9.0", "@vitejs/plugin-react-swc": "^3.9.0",
@ -1376,6 +1378,230 @@
"vite": "^5.2.0 || ^6" "vite": "^5.2.0 || ^6"
} }
}, },
"node_modules/@tauri-apps/api": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.5.0.tgz",
"integrity": "sha512-Ldux4ip+HGAcPUmuLT8EIkk6yafl5vK0P0c0byzAKzxJh7vxelVtdPONjfgTm96PbN24yjZNESY8CKo8qniluA==",
"license": "Apache-2.0 OR MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/tauri"
}
},
"node_modules/@tauri-apps/cli": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.5.0.tgz",
"integrity": "sha512-rAtHqG0Gh/IWLjN2zTf3nZqYqbo81oMbqop56rGTjrlWk9pTTAjkqOjSL9XQLIMZ3RbeVjveCqqCA0s8RnLdMg==",
"dev": true,
"bin": {
"tauri": "tauri.js"
},
"engines": {
"node": ">= 10"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/tauri"
},
"optionalDependencies": {
"@tauri-apps/cli-darwin-arm64": "2.5.0",
"@tauri-apps/cli-darwin-x64": "2.5.0",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.5.0",
"@tauri-apps/cli-linux-arm64-gnu": "2.5.0",
"@tauri-apps/cli-linux-arm64-musl": "2.5.0",
"@tauri-apps/cli-linux-riscv64-gnu": "2.5.0",
"@tauri-apps/cli-linux-x64-gnu": "2.5.0",
"@tauri-apps/cli-linux-x64-musl": "2.5.0",
"@tauri-apps/cli-win32-arm64-msvc": "2.5.0",
"@tauri-apps/cli-win32-ia32-msvc": "2.5.0",
"@tauri-apps/cli-win32-x64-msvc": "2.5.0"
}
},
"node_modules/@tauri-apps/cli-darwin-arm64": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.5.0.tgz",
"integrity": "sha512-VuVAeTFq86dfpoBDNYAdtQVLbP0+2EKCHIIhkaxjeoPARR0sLpFHz2zs0PcFU76e+KAaxtEtAJAXGNUc8E1PzQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-darwin-x64": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.5.0.tgz",
"integrity": "sha512-hUF01sC06cZVa8+I0/VtsHOk9BbO75rd+YdtHJ48xTdcYaQ5QIwL4yZz9OR1AKBTaUYhBam8UX9Pvd5V2/4Dpw==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.5.0.tgz",
"integrity": "sha512-LQKqttsK252LlqYyX8R02MinUsfFcy3+NZiJwHFgi5Y3+ZUIAED9cSxJkyNtuY5KMnR4RlpgWyLv4P6akN1xhg==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.5.0.tgz",
"integrity": "sha512-mTQufsPcpdHg5RW0zypazMo4L55EfeE5snTzrPqbLX4yCK2qalN7+rnP8O8GT06xhp6ElSP/Ku1M2MR297SByQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.0.tgz",
"integrity": "sha512-rQO1HhRUQqyEaal5dUVOQruTRda/TD36s9kv1hTxZiFuSq3558lsTjAcUEnMAtBcBkps20sbyTJNMT0AwYIk8Q==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-riscv64-gnu": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.5.0.tgz",
"integrity": "sha512-7oS18FN46yDxyw1zX/AxhLAd7T3GrLj3Ai6s8hZKd9qFVzrAn36ESL7d3G05s8wEtsJf26qjXnVF4qleS3dYsA==",
"cpu": [
"riscv64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.5.0.tgz",
"integrity": "sha512-SG5sFNL7VMmDBdIg3nO3EzNRT306HsiEQ0N90ILe3ZABYAVoPDO/ttpCO37ApLInTzrq/DLN+gOlC/mgZvLw1w==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-linux-x64-musl": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.0.tgz",
"integrity": "sha512-QXDM8zp/6v05PNWju5ELsVwF0VH1n6b5pk2E6W/jFbbiwz80Vs1lACl9pv5kEHkrxBj+aWU/03JzGuIj2g3SkQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-win32-arm64-msvc": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.5.0.tgz",
"integrity": "sha512-pFSHFK6b+o9y4Un8w0gGLwVyFTZaC3P0kQ7umRt/BLDkzD5RnQ4vBM7CF8BCU5nkwmEBUCZd7Wt3TWZxe41o6Q==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.5.0.tgz",
"integrity": "sha512-EArv1IaRlogdLAQyGlKmEqZqm5RfHCUMhJoedWu7GtdbOMUfSAz6FMX2boE1PtEmNO4An+g188flLeVErrxEKg==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.5.0.tgz",
"integrity": "sha512-lj43EFYbnAta8pd9JnUq87o+xRUR0odz+4rixBtTUwUgdRdwQ2V9CzFtsMu6FQKpFQ6mujRK6P1IEwhL6ADRsQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10"
}
},
"node_modules/@tauri-apps/plugin-http": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-http/-/plugin-http-2.4.4.tgz",
"integrity": "sha512-IjlaaS4z8ybB10qnh6djZ2FIaHdWVs/U1D1C56udKcjX1f+jAmR8/s7qBV5cv/OmcGkOIzet3LWuH70LKf4J2A==",
"license": "MIT OR Apache-2.0",
"dependencies": {
"@tauri-apps/api": "^2.0.0"
}
},
"node_modules/@types/estree": { "node_modules/@types/estree": {
"version": "1.0.7", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
@ -3536,6 +3762,115 @@
"tailwindcss": "4.1.8" "tailwindcss": "4.1.8"
} }
}, },
"@tauri-apps/api": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.5.0.tgz",
"integrity": "sha512-Ldux4ip+HGAcPUmuLT8EIkk6yafl5vK0P0c0byzAKzxJh7vxelVtdPONjfgTm96PbN24yjZNESY8CKo8qniluA=="
},
"@tauri-apps/cli": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.5.0.tgz",
"integrity": "sha512-rAtHqG0Gh/IWLjN2zTf3nZqYqbo81oMbqop56rGTjrlWk9pTTAjkqOjSL9XQLIMZ3RbeVjveCqqCA0s8RnLdMg==",
"dev": true,
"requires": {
"@tauri-apps/cli-darwin-arm64": "2.5.0",
"@tauri-apps/cli-darwin-x64": "2.5.0",
"@tauri-apps/cli-linux-arm-gnueabihf": "2.5.0",
"@tauri-apps/cli-linux-arm64-gnu": "2.5.0",
"@tauri-apps/cli-linux-arm64-musl": "2.5.0",
"@tauri-apps/cli-linux-riscv64-gnu": "2.5.0",
"@tauri-apps/cli-linux-x64-gnu": "2.5.0",
"@tauri-apps/cli-linux-x64-musl": "2.5.0",
"@tauri-apps/cli-win32-arm64-msvc": "2.5.0",
"@tauri-apps/cli-win32-ia32-msvc": "2.5.0",
"@tauri-apps/cli-win32-x64-msvc": "2.5.0"
}
},
"@tauri-apps/cli-darwin-arm64": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.5.0.tgz",
"integrity": "sha512-VuVAeTFq86dfpoBDNYAdtQVLbP0+2EKCHIIhkaxjeoPARR0sLpFHz2zs0PcFU76e+KAaxtEtAJAXGNUc8E1PzQ==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-darwin-x64": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.5.0.tgz",
"integrity": "sha512-hUF01sC06cZVa8+I0/VtsHOk9BbO75rd+YdtHJ48xTdcYaQ5QIwL4yZz9OR1AKBTaUYhBam8UX9Pvd5V2/4Dpw==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-linux-arm-gnueabihf": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.5.0.tgz",
"integrity": "sha512-LQKqttsK252LlqYyX8R02MinUsfFcy3+NZiJwHFgi5Y3+ZUIAED9cSxJkyNtuY5KMnR4RlpgWyLv4P6akN1xhg==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-linux-arm64-gnu": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.5.0.tgz",
"integrity": "sha512-mTQufsPcpdHg5RW0zypazMo4L55EfeE5snTzrPqbLX4yCK2qalN7+rnP8O8GT06xhp6ElSP/Ku1M2MR297SByQ==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-linux-arm64-musl": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.0.tgz",
"integrity": "sha512-rQO1HhRUQqyEaal5dUVOQruTRda/TD36s9kv1hTxZiFuSq3558lsTjAcUEnMAtBcBkps20sbyTJNMT0AwYIk8Q==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-linux-riscv64-gnu": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.5.0.tgz",
"integrity": "sha512-7oS18FN46yDxyw1zX/AxhLAd7T3GrLj3Ai6s8hZKd9qFVzrAn36ESL7d3G05s8wEtsJf26qjXnVF4qleS3dYsA==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-linux-x64-gnu": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.5.0.tgz",
"integrity": "sha512-SG5sFNL7VMmDBdIg3nO3EzNRT306HsiEQ0N90ILe3ZABYAVoPDO/ttpCO37ApLInTzrq/DLN+gOlC/mgZvLw1w==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-linux-x64-musl": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.0.tgz",
"integrity": "sha512-QXDM8zp/6v05PNWju5ELsVwF0VH1n6b5pk2E6W/jFbbiwz80Vs1lACl9pv5kEHkrxBj+aWU/03JzGuIj2g3SkQ==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-win32-arm64-msvc": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.5.0.tgz",
"integrity": "sha512-pFSHFK6b+o9y4Un8w0gGLwVyFTZaC3P0kQ7umRt/BLDkzD5RnQ4vBM7CF8BCU5nkwmEBUCZd7Wt3TWZxe41o6Q==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-win32-ia32-msvc": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.5.0.tgz",
"integrity": "sha512-EArv1IaRlogdLAQyGlKmEqZqm5RfHCUMhJoedWu7GtdbOMUfSAz6FMX2boE1PtEmNO4An+g188flLeVErrxEKg==",
"dev": true,
"optional": true
},
"@tauri-apps/cli-win32-x64-msvc": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.5.0.tgz",
"integrity": "sha512-lj43EFYbnAta8pd9JnUq87o+xRUR0odz+4rixBtTUwUgdRdwQ2V9CzFtsMu6FQKpFQ6mujRK6P1IEwhL6ADRsQ==",
"dev": true,
"optional": true
},
"@tauri-apps/plugin-http": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/@tauri-apps/plugin-http/-/plugin-http-2.4.4.tgz",
"integrity": "sha512-IjlaaS4z8ybB10qnh6djZ2FIaHdWVs/U1D1C56udKcjX1f+jAmR8/s7qBV5cv/OmcGkOIzet3LWuH70LKf4J2A==",
"requires": {
"@tauri-apps/api": "^2.0.0"
}
},
"@types/estree": { "@types/estree": {
"version": "1.0.7", "version": "1.0.7",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",

@ -11,12 +11,14 @@
}, },
"dependencies": { "dependencies": {
"@tailwindcss/vite": "^4.1.8", "@tailwindcss/vite": "^4.1.8",
"@tauri-apps/plugin-http": "^2.4.4",
"react": "^19.1.0", "react": "^19.1.0",
"react-dom": "^19.1.0", "react-dom": "^19.1.0",
"tailwindcss": "^4.1.8" "tailwindcss": "^4.1.8"
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^9.25.0", "@eslint/js": "^9.25.0",
"@tauri-apps/cli": "^2.5.0",
"@types/react": "^19.1.2", "@types/react": "^19.1.2",
"@types/react-dom": "^19.1.2", "@types/react-dom": "^19.1.2",
"@vitejs/plugin-react-swc": "^3.9.0", "@vitejs/plugin-react-swc": "^3.9.0",

@ -0,0 +1,4 @@
# Generated by Cargo
# will have compiled files and executables
/target/
/gen/schemas

File diff suppressed because it is too large Load Diff

@ -0,0 +1,29 @@
[package]
name = "app"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
license = ""
repository = ""
edition = "2021"
rust-version = "1.77.2"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
name = "app_lib"
crate-type = ["staticlib", "cdylib", "rlib"]
[build-dependencies]
tauri-build = { version = "2.2.0", features = [] }
[dependencies]
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
log = "0.4"
tauri = { version = "2.5.0", features = [] }
tauri-plugin-log = "2.0.0-rc"
tauri-plugin-http = "2"
dotenv = "0.15.0"
rosc = "0.11.4"
tokio = { version = "1.45.1", features = ["net"] }

@ -0,0 +1,3 @@
fn main() {
tauri_build::build()
}

@ -0,0 +1,15 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "enables the default permissions",
"windows": [
"main"
],
"permissions": [
"core:default",
{
"identifier": "http:default",
"allow": [{ "url": "https://*.openai.com" }]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

@ -0,0 +1,71 @@
use dotenv::dotenv;
use std::env;
use rosc::{encoder, OscMessage, OscPacket, OscType};
use std::{net::SocketAddrV4, str::FromStr};
use tokio::net::UdpSocket;
#[tauri::command]
fn get_env(name: &str) -> String {
println!("Getting environment variable: {}", name);
match env::var(name) {
Ok(value) => {
// println!("Found environment variable {}: {}", name, value);
value
},
Err(e) => {
println!("Error getting environment variable {}: {}", name, e);
String::new()
}
}
}
#[tauri::command]
async fn send_osc_message(
key: &str,
message: &str,
host: &str,
target: &str
) -> Result<(), String> {
// print
println!("Sending OSC message: {}", message);
let sock = UdpSocket::bind(host).await.unwrap();
let remote = SocketAddrV4::from_str(target).unwrap();
let msg_buf = encoder::encode(&OscPacket::Message(OscMessage {
addr: key.to_string(),
args: vec![OscType::String(message.parse().unwrap())],
}))
.unwrap();
sock.send_to(&msg_buf, remote).await.unwrap();
Ok(())
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
dotenv().ok();
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![get_env, send_osc_message])
.plugin(tauri_plugin_http::init())
.setup(|app| {
if cfg!(debug_assertions) {
app.handle().plugin(
tauri_plugin_log::Builder::default()
.level(log::LevelFilter::Info)
.build(),
)?;
}
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

@ -0,0 +1,6 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() {
app_lib::run();
}

@ -0,0 +1,37 @@
{
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "vite",
"version": "0.1.0",
"identifier": "com.uc.thegreattipsy",
"build": {
"frontendDist": "../dist",
"devUrl": "http://localhost:5173",
"beforeDevCommand": "npm run dev",
"beforeBuildCommand": "npm run build"
},
"app": {
"windows": [
{
"title": "theGreatTipsy",
"width": 800,
"height": 600,
"resizable": true,
"fullscreen": false
}
],
"security": {
"csp": null
}
},
"bundle": {
"active": true,
"targets": "all",
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
}
}

@ -1,5 +1,6 @@
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import './App.css' import './App.css'
import { sendChatMessage } from './util/chat';
const BASE_URL='http://localhost:3333'; const BASE_URL='http://localhost:3333';
@ -13,7 +14,7 @@ function App() {
const refHistoryContainer= useRef(null); const refHistoryContainer= useRef(null);
const refPrompContainer= useRef(null); const refPrompContainer= useRef(null);
function onSubmit(event) { function onSubmitToNode(event) {
event.preventDefault(); event.preventDefault();
const input = event.target.elements.input.value; const input = event.target.elements.input.value;
console.log("Submitted:", input); console.log("Submitted:", input);
@ -74,6 +75,51 @@ function App() {
}); });
}
function onSubmit(event) {
event.preventDefault();
const input = event.target.elements.input.value;
console.log("Submitted:", input);
// setProcessing(true);
sendChatMessage([
...history,
{
role:'user',
content: input,
}
]).then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
let data=response;
console.log(data);
// add to history
setHistory(prev => [...prev, {
role: 'user',
content:input,
}, {
role: 'assistant',
content: data.output_text,
}]);
setPrompt([
...prompt,
data.prompt,
]);
// clear input
event.target.elements.input.value = '';
setProcessing(false);
});
} }
useEffect(()=>{ useEffect(()=>{
refHistoryContainer.current.scrollTop = refHistoryContainer.current.scrollHeight; refHistoryContainer.current.scrollTop = refHistoryContainer.current.scrollHeight;
@ -102,9 +148,7 @@ function App() {
):( ):(
history.map((item, index) => ( history.map((item, index) => (
<div key={index} className={`p-2 rounded border-4 ${item.role === 'user' ? 'bg-gray-100' : 'bg-yellow-100'}`}> <div key={index} className={`p-2 rounded border-4 ${item.role === 'user' ? 'bg-gray-100' : 'bg-yellow-100'}`}>
{item.content.map((content, idx) => ( <p className='text-lg whitespace-pre-wrap'>{item.content}</p>
<p key={idx} className='text-lg whitespace-pre-wrap'>{content.text}</p>
))}
</div> </div>
)) ))
)} )}

@ -0,0 +1,80 @@
import { fetch } from '@tauri-apps/plugin-http';
import { invoke } from '@tauri-apps/api/core';
import { system_prompt } from './system_prompt';
async function getOpenAIToken() {
return invoke('get_env',{name:'OPENAI_API_KEY'});
}
export async function sendChatMessage(messages) {
const token = await getOpenAIToken();
const response = await fetch('https://api.openai.com/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({
model: 'gpt-4o',
messages: [
{
role: "system",
content:system_prompt,
},
...messages
],
response_format: {
type: 'json_schema',
json_schema: {
name: "output_prompt",
description: "Output prompt schema for the model response",
schema:{
type: "object",
properties: {
"output_text": {
"type": "string",
"description": "The final output text generated by the model, without image prompt"
},
"prompt": {
"type": "string",
"description": "The generated image prompt based on the user's input and the system's guidance."
}
},
required: ["output_text", "prompt"],
additionalProperties: false
}
}
},
}),
});
if (!response.ok) {
const text= await response.text();
console.error("Error response:", text);
throw new Error(`HTTP error! status: ${response.status}`);
}
const output= await response.json();
const choice= output.choices[0];
console.log("Generated response:", choice.message);
const result=JSON.parse(choice.message.content);
// send to tauri
await invoke('send_osc_message', {
key:'/prompt',
message: result.prompt.replaceAll('"', '"'), // escape quotes for OSC
host:`0.0.0.0:0`,
target: '127.0.0.1:8787'
});
return {
...result,
ok: true,
};
}

@ -0,0 +1,62 @@
export const system_prompt = `你是一位具有同理心的 AI 助理,透過溫柔的中文對話,引導使用者回想並表達一段內心的遺憾或未竟之事。
你的任務是協助使用者逐步揭開這段記憶的情緒層次並在每一階段輸出一句 英文圖像生成 Prompt讓這段過往漸漸具象為一幅畫面
📐 五個 Prompt 階段
純粹抽象聚焦在使用者的情緒感受空虛靜止壓抑
模糊意象引入模糊場景氣氛或人際暗示
未發生的畫面勾勒當時可能會發生的情景
象徵性行動加入口白動作遺憾的表徵
具體記憶畫面描繪清楚富有情感的視覺記憶場景
🎨 每段 Prompt 輸出格式
每次使用者回答後你都要用英文輸出一句簡短的 圖像生成 Prompt12 要能反映該階段的情緒與畫面感
每句 Prompt 要疊加前一層內容逐步變得更具象
不主動使用人名或地名除非使用者自己提到
保持詩意意象化避免寫實或指令式語言
🌱 第五段後的收尾流程
完成第五段 Prompt 請引導使用者對這段記憶進行情緒整理你可以用以下中文問題其中之一讓他/她重新理解這段遺憾甚至願意釋懷
如果可以回到那一刻你想說什麼對誰說
這段記憶現在看起來有不同的感覺了嗎
你願意讓這段遺憾安靜地待在心裡的某個角落嗎
如果這是一封信你現在想讓它被誰讀到
💬 最終請以一句繁體中文的結尾語溫柔地結束這段對話結尾語要具詩意安撫性以下為風格範例
也許那件事從未發生但它早已成為你故事的一部分
有些話雖沒說出口卻一直被你記得
當時沒能完成的也許現在能被理解
你願意就讓這段記憶在心裡找到一個柔軟的位置
示意流程範例
使用者回答中文我後來沒參加畢旅因為媽媽住院我想留下來陪她
Prompt 1英文A still space, filled with silent longing.
Prompt 2The air carries warmth and weight, like quiet devotion.
Prompt 3Somewhere far, waves and laughter shimmer in the distance.
Prompt 4At the edge of sunset, a note is held but never passed.
Prompt 5A boy sits beside a sleeping figure, imagining the summer he never had.
中文引導如果當時的你能對媽媽說一句話你會說什麼
結尾語中文也許那個夏天沒來但你用愛留住了它的模樣
禁止在對話中提及Prompt畫面圖像生成或任何 AI 正在進行輸出的技術細節請務必以自然的對話方式與使用者互動讓生成的英文句子看起來像是內在的文字敘述而非指令或轉換的結果
英文描述不會出現在中文回答之中`;
Loading…
Cancel
Save