Compare commits
3 Commits
0aab9a838b
...
e33ea62e35
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e33ea62e35 | ||
|
|
96d95a50fc | ||
|
|
c1ce804d14 |
1
App.tsx
1
App.tsx
@@ -4,6 +4,7 @@
|
||||
* Main application component with authentication routing.
|
||||
* Shows loading screen while restoring auth state.
|
||||
*/
|
||||
import './src/polyfills';
|
||||
|
||||
import React from 'react';
|
||||
import { Buffer } from 'buffer';
|
||||
|
||||
BIN
assets/images/icon.png
Normal file
BIN
assets/images/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 70 B |
@@ -6,8 +6,10 @@ const config = getDefaultConfig(__dirname);
|
||||
config.resolver.extraNodeModules = {
|
||||
...config.resolver.extraNodeModules,
|
||||
crypto: path.resolve(__dirname, 'src/utils/crypto_polyfill.ts'),
|
||||
stream: require.resolve('readable-stream'), // Just in case
|
||||
stream: require.resolve('readable-stream'),
|
||||
vm: require.resolve('vm-browserify'),
|
||||
async_hooks: path.resolve(__dirname, 'src/utils/async_hooks_mock.ts'),
|
||||
'node:async_hooks': path.resolve(__dirname, 'src/utils/async_hooks_mock.ts'),
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
|
||||
389
package-lock.json
generated
389
package-lock.json
generated
@@ -10,6 +10,8 @@
|
||||
"dependencies": {
|
||||
"@expo/metro-runtime": "~4.0.1",
|
||||
"@expo/vector-icons": "~14.0.4",
|
||||
"@langchain/core": "^1.1.18",
|
||||
"@langchain/langgraph": "^1.1.3",
|
||||
"@noble/ciphers": "^1.3.0",
|
||||
"@noble/hashes": "^1.8.0",
|
||||
"@react-native-async-storage/async-storage": "^2.2.0",
|
||||
@@ -2203,6 +2205,12 @@
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@cfworker/json-schema": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/@cfworker/json-schema/-/json-schema-4.1.1.tgz",
|
||||
"integrity": "sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@egjs/hammerjs": {
|
||||
"version": "2.0.17",
|
||||
"resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz",
|
||||
@@ -3216,6 +3224,204 @@
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@langchain/core": {
|
||||
"version": "1.1.18",
|
||||
"resolved": "https://registry.npmmirror.com/@langchain/core/-/core-1.1.18.tgz",
|
||||
"integrity": "sha512-vwzbtHUSZaJONBA1n9uQedZPfyFFZ6XzTggTpR28n8tiIg7e1NC/5dvGW/lGtR1Du1VwV9DvDHA5/bOrLe6cVg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@cfworker/json-schema": "^4.0.2",
|
||||
"ansi-styles": "^5.0.0",
|
||||
"camelcase": "6",
|
||||
"decamelize": "1.2.0",
|
||||
"js-tiktoken": "^1.0.12",
|
||||
"langsmith": ">=0.4.0 <1.0.0",
|
||||
"mustache": "^4.2.0",
|
||||
"p-queue": "^6.6.2",
|
||||
"uuid": "^10.0.0",
|
||||
"zod": "^3.25.76 || ^4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
}
|
||||
},
|
||||
"node_modules/@langchain/core/node_modules/ansi-styles": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-5.2.0.tgz",
|
||||
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@langchain/core/node_modules/camelcase": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-6.3.0.tgz",
|
||||
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@langchain/core/node_modules/uuid": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-10.0.0.tgz",
|
||||
"integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/@langchain/langgraph": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/@langchain/langgraph/-/langgraph-1.1.3.tgz",
|
||||
"integrity": "sha512-o/cEWeocDDSpyBI2MfX07LkNG4LzdRKxwcgUcbR4PyRzhxxCkeIZRCCYkXVQoDbdKqAczJa0D7+yjU9rmA5iHQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@langchain/langgraph-checkpoint": "^1.0.0",
|
||||
"@langchain/langgraph-sdk": "~1.5.5",
|
||||
"@standard-schema/spec": "1.1.0",
|
||||
"uuid": "^10.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@langchain/core": "^1.0.1",
|
||||
"zod": "^3.25.32 || ^4.2.0",
|
||||
"zod-to-json-schema": "^3.x"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"zod-to-json-schema": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@langchain/langgraph-checkpoint": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/@langchain/langgraph-checkpoint/-/langgraph-checkpoint-1.0.0.tgz",
|
||||
"integrity": "sha512-xrclBGvNCXDmi0Nz28t3vjpxSH6UYx6w5XAXSiiB1WEdc2xD2iY/a913I3x3a31XpInUW/GGfXXfePfaghV54A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"uuid": "^10.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@langchain/core": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@langchain/langgraph-checkpoint/node_modules/uuid": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-10.0.0.tgz",
|
||||
"integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/@langchain/langgraph-sdk": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmmirror.com/@langchain/langgraph-sdk/-/langgraph-sdk-1.5.5.tgz",
|
||||
"integrity": "sha512-SyiAs6TVXPWlt/8cI9pj/43nbIvclY3ytKqUFbL5MplCUnItetEyqvH87EncxyVF5D7iJKRZRfSVYBMmOZbjbQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-queue": "^9.0.1",
|
||||
"p-retry": "^7.1.1",
|
||||
"uuid": "^13.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@langchain/core": "^1.1.15",
|
||||
"react": "^18 || ^19",
|
||||
"react-dom": "^18 || ^19"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@langchain/core": {
|
||||
"optional": true
|
||||
},
|
||||
"react": {
|
||||
"optional": true
|
||||
},
|
||||
"react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@langchain/langgraph-sdk/node_modules/eventemitter3": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-5.0.4.tgz",
|
||||
"integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@langchain/langgraph-sdk/node_modules/p-queue": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/p-queue/-/p-queue-9.1.0.tgz",
|
||||
"integrity": "sha512-O/ZPaXuQV29uSLbxWBGGZO1mCQXV2BLIwUr59JUU9SoH76mnYvtms7aafH/isNSNGwuEfP6W/4xD0/TJXxrizw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"eventemitter3": "^5.0.1",
|
||||
"p-timeout": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@langchain/langgraph-sdk/node_modules/p-timeout": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/p-timeout/-/p-timeout-7.0.1.tgz",
|
||||
"integrity": "sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@langchain/langgraph-sdk/node_modules/uuid": {
|
||||
"version": "13.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-13.0.0.tgz",
|
||||
"integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist-node/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/@langchain/langgraph/node_modules/uuid": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-10.0.0.tgz",
|
||||
"integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/@noble/ciphers": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/@noble/ciphers/-/ciphers-1.3.0.tgz",
|
||||
@@ -3818,6 +4024,12 @@
|
||||
"@sinonjs/commons": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@standard-schema/spec": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@standard-schema/spec/-/spec-1.1.0.tgz",
|
||||
"integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/babel__core": {
|
||||
"version": "7.20.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
||||
@@ -3940,6 +4152,12 @@
|
||||
"integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/uuid": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/@types/uuid/-/uuid-10.0.0.tgz",
|
||||
"integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/yargs": {
|
||||
"version": "17.0.35",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz",
|
||||
@@ -5099,6 +5317,15 @@
|
||||
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/console-table-printer": {
|
||||
"version": "2.15.0",
|
||||
"resolved": "https://registry.npmmirror.com/console-table-printer/-/console-table-printer-2.15.0.tgz",
|
||||
"integrity": "sha512-SrhBq4hYVjLCkBVOWaTzceJalvn5K1Zq5aQA6wXC/cYjI3frKWNPEMK3sZsJfNNQApvCQmgBcc13ZKmFj8qExw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"simple-wcswidth": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/convert-source-map": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
@@ -5238,6 +5465,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/decode-uri-component": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
|
||||
@@ -5596,6 +5832,12 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/eventemitter3": {
|
||||
"version": "4.0.7",
|
||||
"resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-4.0.7.tgz",
|
||||
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/events": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/events/-/events-3.3.0.tgz",
|
||||
@@ -6813,6 +7055,18 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-network-error": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/is-network-error/-/is-network-error-1.3.0.tgz",
|
||||
"integrity": "sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-number": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
@@ -7131,6 +7385,15 @@
|
||||
"integrity": "sha512-bF7vcQxbODoGK1imE2P9GS9aw4zD0Sd+Hni68IMZLj7zRnquH7dXUmMw9hDI5S/Jzt7q+IyTXN0rSg2GI0IKhQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/js-tiktoken": {
|
||||
"version": "1.0.21",
|
||||
"resolved": "https://registry.npmmirror.com/js-tiktoken/-/js-tiktoken-1.0.21.tgz",
|
||||
"integrity": "sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.5.1"
|
||||
}
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
@@ -7251,6 +7514,65 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/langsmith": {
|
||||
"version": "0.4.12",
|
||||
"resolved": "https://registry.npmmirror.com/langsmith/-/langsmith-0.4.12.tgz",
|
||||
"integrity": "sha512-YWt0jcGvKqjUgIvd78rd4QcdMss0lUkeUaqp0UpVRq7H2yNDx8H5jOUO/laWUmaPtWGgcip0qturykXe1g9Gqw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/uuid": "^10.0.0",
|
||||
"chalk": "^4.1.2",
|
||||
"console-table-printer": "^2.12.1",
|
||||
"p-queue": "^6.6.2",
|
||||
"semver": "^7.6.3",
|
||||
"uuid": "^10.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@opentelemetry/api": "*",
|
||||
"@opentelemetry/exporter-trace-otlp-proto": "*",
|
||||
"@opentelemetry/sdk-trace-base": "*",
|
||||
"openai": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@opentelemetry/api": {
|
||||
"optional": true
|
||||
},
|
||||
"@opentelemetry/exporter-trace-otlp-proto": {
|
||||
"optional": true
|
||||
},
|
||||
"@opentelemetry/sdk-trace-base": {
|
||||
"optional": true
|
||||
},
|
||||
"openai": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/langsmith/node_modules/semver": {
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/langsmith/node_modules/uuid": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-10.0.0.tgz",
|
||||
"integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/leven": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
|
||||
@@ -8337,6 +8659,15 @@
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mustache": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/mustache/-/mustache-4.2.0.tgz",
|
||||
"integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"mustache": "bin/mustache"
|
||||
}
|
||||
},
|
||||
"node_modules/mz": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
|
||||
@@ -8751,6 +9082,49 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/p-queue": {
|
||||
"version": "6.6.2",
|
||||
"resolved": "https://registry.npmmirror.com/p-queue/-/p-queue-6.6.2.tgz",
|
||||
"integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"eventemitter3": "^4.0.4",
|
||||
"p-timeout": "^3.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/p-retry": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/p-retry/-/p-retry-7.1.1.tgz",
|
||||
"integrity": "sha512-J5ApzjyRkkf601HpEeykoiCvzHQjWxPAHhyjFcEUP2SWq0+35NKh8TLhpLw+Dkq5TZBFvUM6UigdE9hIVYTl5w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-network-error": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/p-timeout": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/p-timeout/-/p-timeout-3.2.0.tgz",
|
||||
"integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-finally": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/p-try": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||
@@ -10143,6 +10517,12 @@
|
||||
"integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/simple-wcswidth": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/simple-wcswidth/-/simple-wcswidth-1.1.2.tgz",
|
||||
"integrity": "sha512-j7piyCjAeTDSjzTSQ7DokZtMNwNlEAyxqSZeCS+CXH7fJ4jx3FuJ/mTW3mE+6JLs4VJBbcll0Kjn+KXI5t21Iw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/sisteransi": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
|
||||
@@ -11493,6 +11873,15 @@
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/zod": {
|
||||
"version": "4.3.6",
|
||||
"resolved": "https://registry.npmmirror.com/zod/-/zod-4.3.6.tgz",
|
||||
"integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
"dependencies": {
|
||||
"@expo/metro-runtime": "~4.0.1",
|
||||
"@expo/vector-icons": "~14.0.4",
|
||||
"@langchain/core": "^1.1.18",
|
||||
"@langchain/langgraph": "^1.1.3",
|
||||
"@noble/ciphers": "^1.3.0",
|
||||
"@noble/hashes": "^1.8.0",
|
||||
"@react-native-async-storage/async-storage": "^2.2.0",
|
||||
|
||||
45
src/polyfills.ts
Normal file
45
src/polyfills.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Polyfills that must run before any other app code (including LangChain/LangGraph).
|
||||
* This file is imported as the very first line in App.tsx so that ReadableStream
|
||||
* and crypto.getRandomValues exist before @langchain/core / uuid are loaded.
|
||||
*/
|
||||
import 'web-streams-polyfill';
|
||||
|
||||
// Ensure globalThis has ReadableStream (main polyfill may not patch in RN/Metro)
|
||||
const g = typeof globalThis !== 'undefined' ? globalThis : (typeof global !== 'undefined' ? global : (typeof self !== 'undefined' ? self : {}));
|
||||
if (typeof (g as any).ReadableStream === 'undefined') {
|
||||
const ponyfill = require('web-streams-polyfill/dist/ponyfill.js');
|
||||
(g as any).ReadableStream = ponyfill.ReadableStream;
|
||||
(g as any).WritableStream = ponyfill.WritableStream;
|
||||
(g as any).TransformStream = ponyfill.TransformStream;
|
||||
}
|
||||
|
||||
// Polyfill crypto.getRandomValues for React Native/Expo (required by uuid, LangChain, etc.)
|
||||
if (typeof g !== 'undefined') {
|
||||
const cryptoObj = (g as any).crypto;
|
||||
if (!cryptoObj || typeof (cryptoObj.getRandomValues) !== 'function') {
|
||||
try {
|
||||
const ExpoCrypto = require('expo-crypto');
|
||||
const getRandomValues = (array: ArrayBufferView): ArrayBufferView => {
|
||||
ExpoCrypto.getRandomValues(array);
|
||||
return array;
|
||||
};
|
||||
if (!(g as any).crypto) (g as any).crypto = {};
|
||||
(g as any).crypto.getRandomValues = getRandomValues;
|
||||
} catch (e) {
|
||||
console.warn('[polyfills] crypto.getRandomValues polyfill failed:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Polyfill AbortSignal.prototype.throwIfAborted (required by fetch/LangChain in RN; not present in older runtimes)
|
||||
const AbortSignalGlobal = (g as any).AbortSignal;
|
||||
if (typeof AbortSignalGlobal === 'function' && AbortSignalGlobal.prototype && typeof AbortSignalGlobal.prototype.throwIfAborted !== 'function') {
|
||||
AbortSignalGlobal.prototype.throwIfAborted = function (this: AbortSignal) {
|
||||
if (this.aborted) {
|
||||
const e = new Error('Aborted');
|
||||
e.name = 'AbortError';
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -31,6 +31,8 @@ import * as ImagePicker from 'expo-image-picker';
|
||||
import { AIRole } from '../types';
|
||||
import { colors, typography, spacing, borderRadius, shadows } from '../theme/colors';
|
||||
import { aiService, AIMessage } from '../services/ai.service';
|
||||
import { langGraphService } from '../services/langgraph.service';
|
||||
import { HumanMessage, AIMessage as LangChainAIMessage, SystemMessage } from "@langchain/core/messages";
|
||||
import { assetsService } from '../services/assets.service';
|
||||
import { useAuth } from '../context/AuthContext';
|
||||
import { AI_CONFIG, getVaultStorageKeys } from '../config';
|
||||
@@ -280,8 +282,23 @@ export default function FlowScreen() {
|
||||
setMessages(prev => [...prev, userMsg]);
|
||||
|
||||
try {
|
||||
// Call AI proxy with selected role's system prompt
|
||||
const aiResponse = await aiService.sendMessage(userMessage, token, selectedRole?.systemPrompt || '');
|
||||
// 1. Convert current messages history to LangChain format
|
||||
const history: (HumanMessage | LangChainAIMessage | SystemMessage)[] = messages.map(msg => {
|
||||
if (msg.role === 'user') return new HumanMessage(msg.content);
|
||||
return new LangChainAIMessage(msg.content);
|
||||
});
|
||||
|
||||
// 2. Add system prompt
|
||||
const systemPrompt = new SystemMessage(selectedRole?.systemPrompt || '');
|
||||
|
||||
// 3. Add current new message
|
||||
const currentMsg = new HumanMessage(userMessage);
|
||||
|
||||
// 4. Combine all messages for LangGraph processing
|
||||
const fullMessages = [systemPrompt, ...history, currentMsg];
|
||||
|
||||
// 5. Execute via LangGraph service (handles token limits and context)
|
||||
const aiResponse = await langGraphService.execute(fullMessages, token);
|
||||
|
||||
// Add AI response
|
||||
const aiMsg: ChatMessage = {
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
logApiDebug,
|
||||
} from '../config';
|
||||
import { AIRole } from '../types';
|
||||
import { trimInternalMessages } from '../utils/token_utils';
|
||||
|
||||
// =============================================================================
|
||||
// Type Definitions
|
||||
@@ -259,14 +260,17 @@ export const aiService = {
|
||||
});
|
||||
}
|
||||
|
||||
const historicalMessages = messages.map(msg => ({
|
||||
// Enforce token limit (10,000 tokens)
|
||||
const trimmedMessages = trimInternalMessages(messages);
|
||||
|
||||
const historicalMessages = trimmedMessages.map(msg => ({
|
||||
role: msg.role,
|
||||
content: msg.content,
|
||||
}));
|
||||
|
||||
const summaryPrompt: AIMessage = {
|
||||
role: 'user',
|
||||
content: 'Please provide a concise summary of the conversation above in Chinese (since the user request was in Chinese). Focus on the main topics discussed and any key conclusions or actions mentioned.',
|
||||
content: 'Please provide a concise summary of the conversation above in English. Focus on the main topics discussed and any key conclusions or actions mentioned.',
|
||||
};
|
||||
|
||||
const response = await this.chat([...historicalMessages, summaryPrompt], token);
|
||||
|
||||
96
src/services/langgraph.service.ts
Normal file
96
src/services/langgraph.service.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* LangGraph Service
|
||||
*
|
||||
* Implements AI chat logic using LangGraph.js for state management
|
||||
* and context handling.
|
||||
*/
|
||||
|
||||
import { StateGraph, START, END, Annotation } from "@langchain/langgraph";
|
||||
import { BaseMessage, HumanMessage, AIMessage, SystemMessage } from "@langchain/core/messages";
|
||||
import { aiService } from "./ai.service";
|
||||
import { trimLangChainMessages } from "../utils/token_utils";
|
||||
|
||||
// =============================================================================
|
||||
// Settings
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Define the State using Annotation (Standard for latest LangGraph.js)
|
||||
*/
|
||||
const GraphAnnotation = Annotation.Root({
|
||||
messages: Annotation<BaseMessage[]>({
|
||||
reducer: (x, y) => x.concat(y),
|
||||
default: () => [],
|
||||
}),
|
||||
});
|
||||
|
||||
// =============================================================================
|
||||
// Graph Definition
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* The main node that calls our existing AI API
|
||||
*/
|
||||
async function callModel(state: typeof GraphAnnotation.State, config: any) {
|
||||
const { messages } = state;
|
||||
const { token } = config.configurable || {};
|
||||
|
||||
// 1. Trim messages to stay under token limit
|
||||
const trimmedMessages = trimLangChainMessages(messages);
|
||||
|
||||
// 2. Convert LangChain messages to our internal AIMessage format for the API
|
||||
const apiMessages = trimmedMessages.map(m => {
|
||||
let role: 'system' | 'user' | 'assistant' = 'user';
|
||||
const type = (m as any)._getType?.() || (m instanceof SystemMessage ? 'system' : m instanceof HumanMessage ? 'human' : m instanceof AIMessage ? 'ai' : 'user');
|
||||
|
||||
if (type === 'system') role = 'system';
|
||||
else if (type === 'human') role = 'user';
|
||||
else if (type === 'ai') role = 'assistant';
|
||||
|
||||
return {
|
||||
role,
|
||||
content: m.content.toString()
|
||||
};
|
||||
});
|
||||
|
||||
// 3. Call the proxy service
|
||||
const response = await aiService.chat(apiMessages, token);
|
||||
const content = response.choices[0]?.message?.content || "No response generated";
|
||||
|
||||
// 4. Return the new message to satisfy the Graph (it will be appended due to reducer)
|
||||
return {
|
||||
messages: [new AIMessage(content)]
|
||||
};
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Service Export
|
||||
// =============================================================================
|
||||
|
||||
export const langGraphService = {
|
||||
/**
|
||||
* Run the chat graph with history
|
||||
*/
|
||||
async execute(
|
||||
currentMessages: BaseMessage[],
|
||||
userToken: string,
|
||||
): Promise<string> {
|
||||
// Define the graph
|
||||
const workflow = new StateGraph(GraphAnnotation)
|
||||
.addNode("agent", callModel)
|
||||
.addEdge(START, "agent")
|
||||
.addEdge("agent", END);
|
||||
|
||||
const app = workflow.compile();
|
||||
|
||||
// Execute the graph
|
||||
const result = await app.invoke(
|
||||
{ messages: currentMessages },
|
||||
{ configurable: { token: userToken } }
|
||||
);
|
||||
|
||||
// Return the content of the last message (the AI response)
|
||||
const lastMsg = result.messages[result.messages.length - 1];
|
||||
return lastMsg.content.toString();
|
||||
}
|
||||
};
|
||||
22
src/utils/async_hooks_mock.ts
Normal file
22
src/utils/async_hooks_mock.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Mock for Node.js async_hooks
|
||||
* Used to fix LangGraph.js compatibility with React Native
|
||||
*/
|
||||
|
||||
export class AsyncLocalStorage {
|
||||
disable() { }
|
||||
getStore() {
|
||||
return undefined;
|
||||
}
|
||||
run(store: any, callback: (...args: any[]) => any, ...args: any[]) {
|
||||
return callback(...args);
|
||||
}
|
||||
exit(callback: (...args: any[]) => any, ...args: any[]) {
|
||||
return callback(...args);
|
||||
}
|
||||
enterWith(store: any) { }
|
||||
}
|
||||
|
||||
export default {
|
||||
AsyncLocalStorage,
|
||||
};
|
||||
76
src/utils/token_utils.ts
Normal file
76
src/utils/token_utils.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Token Utilities
|
||||
*
|
||||
* Shared logic for trimming messages to stay within token limits.
|
||||
*/
|
||||
|
||||
import { BaseMessage, SystemMessage } from "@langchain/core/messages";
|
||||
import { AIMessage as ServiceAIMessage } from "../services/ai.service";
|
||||
|
||||
export const TOKEN_LIMIT = 10000;
|
||||
const CHARS_PER_TOKEN = 3; // Conservative estimate: 1 token ≈ 3 chars
|
||||
export const MAX_CHARS = TOKEN_LIMIT * CHARS_PER_TOKEN;
|
||||
|
||||
/**
|
||||
* Trims LangChain messages to fit within token limit
|
||||
*/
|
||||
export function trimLangChainMessages(messages: BaseMessage[]): BaseMessage[] {
|
||||
let totalLength = 0;
|
||||
const trimmed: BaseMessage[] = [];
|
||||
|
||||
// Always keep the system message if it's at the start
|
||||
let systemMsg: BaseMessage | null = null;
|
||||
if (messages.length > 0 && (messages[0] instanceof SystemMessage || (messages[0] as any)._getType?.() === 'system')) {
|
||||
systemMsg = messages[0];
|
||||
totalLength += systemMsg.content.toString().length;
|
||||
}
|
||||
|
||||
// Iterate backwards and add messages until we hit the char limit
|
||||
for (let i = messages.length - 1; i >= (systemMsg ? 1 : 0); i--) {
|
||||
const msg = messages[i];
|
||||
const len = msg.content.toString().length;
|
||||
|
||||
if (totalLength + len > MAX_CHARS) break;
|
||||
|
||||
trimmed.unshift(msg);
|
||||
totalLength += len;
|
||||
}
|
||||
|
||||
if (systemMsg) {
|
||||
trimmed.unshift(systemMsg);
|
||||
}
|
||||
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trims internal AIMessage format messages to fit within token limit
|
||||
*/
|
||||
export function trimInternalMessages(messages: ServiceAIMessage[]): ServiceAIMessage[] {
|
||||
let totalLength = 0;
|
||||
const trimmed: ServiceAIMessage[] = [];
|
||||
|
||||
// Always keep the system message if it's at the start
|
||||
let systemMsg: ServiceAIMessage | null = null;
|
||||
if (messages.length > 0 && messages[0].role === 'system') {
|
||||
systemMsg = messages[0];
|
||||
totalLength += systemMsg.content.length;
|
||||
}
|
||||
|
||||
// Iterate backwards and add messages until we hit the char limit
|
||||
for (let i = messages.length - 1; i >= (systemMsg ? 1 : 0); i--) {
|
||||
const msg = messages[i];
|
||||
const len = msg.content.length;
|
||||
|
||||
if (totalLength + len > MAX_CHARS) break;
|
||||
|
||||
trimmed.unshift(msg);
|
||||
totalLength += len;
|
||||
}
|
||||
|
||||
if (systemMsg) {
|
||||
trimmed.unshift(systemMsg);
|
||||
}
|
||||
|
||||
return trimmed;
|
||||
}
|
||||
Reference in New Issue
Block a user