├── .github
└── workflows
│ ├── build.yml
│ ├── deploy.yml
│ └── test.yml
├── .gitignore
├── .husky
└── pre-commit
├── LICENSE
├── README.md
├── lerna.json
├── package.json
├── packages
├── 008
│ ├── .eslintignore
│ ├── .eslintrc.js
│ ├── .gitignore
│ ├── .prettierignore
│ ├── .prettierrc
│ ├── .storybook-web
│ │ ├── main.js
│ │ └── preview.js
│ ├── .storybook
│ │ ├── index.js
│ │ ├── main.js
│ │ ├── preview.js
│ │ └── storybook.requires.js
│ ├── App.js
│ ├── android
│ │ ├── .gitignore
│ │ ├── app
│ │ │ ├── build.gradle
│ │ │ ├── debug.keystore
│ │ │ ├── proguard-rules.pro
│ │ │ └── src
│ │ │ │ ├── debug
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ └── java
│ │ │ │ │ └── com
│ │ │ │ │ └── anonymous
│ │ │ │ │ └── softphone
│ │ │ │ │ └── ReactNativeFlipper.java
│ │ │ │ ├── main
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── java
│ │ │ │ │ └── com
│ │ │ │ │ │ └── anonymous
│ │ │ │ │ │ └── softphone
│ │ │ │ │ │ ├── MainActivity.java
│ │ │ │ │ │ └── MainApplication.java
│ │ │ │ └── res
│ │ │ │ │ ├── drawable-hdpi
│ │ │ │ │ └── splashscreen_image.png
│ │ │ │ │ ├── drawable-mdpi
│ │ │ │ │ └── splashscreen_image.png
│ │ │ │ │ ├── drawable-xhdpi
│ │ │ │ │ └── splashscreen_image.png
│ │ │ │ │ ├── drawable-xxhdpi
│ │ │ │ │ └── splashscreen_image.png
│ │ │ │ │ ├── drawable-xxxhdpi
│ │ │ │ │ └── splashscreen_image.png
│ │ │ │ │ ├── drawable
│ │ │ │ │ ├── rn_edit_text_material.xml
│ │ │ │ │ └── splashscreen.xml
│ │ │ │ │ ├── mipmap-anydpi-v26
│ │ │ │ │ ├── ic_launcher.xml
│ │ │ │ │ └── ic_launcher_round.xml
│ │ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ ├── ic_launcher_foreground.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ ├── ic_launcher_foreground.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ ├── ic_launcher_foreground.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ ├── ic_launcher_foreground.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ ├── ic_launcher.png
│ │ │ │ │ ├── ic_launcher_foreground.png
│ │ │ │ │ └── ic_launcher_round.png
│ │ │ │ │ ├── values-night
│ │ │ │ │ └── colors.xml
│ │ │ │ │ └── values
│ │ │ │ │ ├── colors.xml
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── styles.xml
│ │ │ │ └── release
│ │ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── anonymous
│ │ │ │ └── softphone
│ │ │ │ └── ReactNativeFlipper.java
│ │ ├── build.gradle
│ │ ├── gradle.properties
│ │ ├── gradle
│ │ │ └── wrapper
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ ├── gradlew
│ │ ├── gradlew.bat
│ │ └── settings.gradle
│ ├── app.json
│ ├── assets
│ │ ├── adaptive-icon.png
│ │ ├── fonts
│ │ │ └── Roboto-Flex.ttf
│ │ ├── icon.png
│ │ └── splash.png
│ ├── babel.config.js
│ ├── cypress.config.js
│ ├── cypress
│ │ ├── e2e
│ │ │ └── spec.cy.js
│ │ ├── fixtures
│ │ │ └── example.json
│ │ └── support
│ │ │ ├── commands.js
│ │ │ └── e2e.js
│ ├── index.js
│ ├── ios
│ │ ├── .gitignore
│ │ ├── .xcode.env
│ │ ├── Podfile
│ │ ├── Podfile.properties.json
│ │ ├── softphone.xcodeproj
│ │ │ ├── project.pbxproj
│ │ │ └── xcshareddata
│ │ │ │ └── xcschemes
│ │ │ │ └── softphone.xcscheme
│ │ └── softphone
│ │ │ ├── AppDelegate.h
│ │ │ ├── AppDelegate.mm
│ │ │ ├── Images.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ ├── App-Icon-20x20@1x.png
│ │ │ │ ├── App-Icon-20x20@2x.png
│ │ │ │ ├── App-Icon-20x20@3x.png
│ │ │ │ ├── App-Icon-29x29@1x.png
│ │ │ │ ├── App-Icon-29x29@2x.png
│ │ │ │ ├── App-Icon-29x29@3x.png
│ │ │ │ ├── App-Icon-40x40@1x.png
│ │ │ │ ├── App-Icon-40x40@2x.png
│ │ │ │ ├── App-Icon-40x40@3x.png
│ │ │ │ ├── App-Icon-60x60@2x.png
│ │ │ │ ├── App-Icon-60x60@3x.png
│ │ │ │ ├── App-Icon-76x76@1x.png
│ │ │ │ ├── App-Icon-76x76@2x.png
│ │ │ │ ├── App-Icon-83.5x83.5@2x.png
│ │ │ │ ├── Contents.json
│ │ │ │ └── ItunesArtwork@2x.png
│ │ │ ├── Contents.json
│ │ │ ├── SplashScreen.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── image.png
│ │ │ └── SplashScreenBackground.imageset
│ │ │ │ ├── Contents.json
│ │ │ │ └── image.png
│ │ │ ├── Info.plist
│ │ │ ├── SplashScreen.storyboard
│ │ │ ├── Supporting
│ │ │ └── Expo.plist
│ │ │ ├── main.m
│ │ │ ├── noop-file.swift
│ │ │ └── softphone.entitlements
│ ├── metro.config.js
│ ├── package.json
│ ├── src
│ │ ├── 008QWorkerLLM.js
│ │ ├── 008QWorkerTTS.js
│ │ ├── Sip.js
│ │ ├── Sound.js
│ │ ├── components
│ │ │ ├── Addons.jsx
│ │ │ ├── Avatars.jsx
│ │ │ ├── Basics.jsx
│ │ │ ├── Container.jsx
│ │ │ ├── Container.web.jsx
│ │ │ ├── Dialer.jsx
│ │ │ ├── Forms.jsx
│ │ │ ├── Icons.jsx
│ │ │ ├── Lists.jsx
│ │ │ ├── Phone
│ │ │ │ ├── Components.jsx
│ │ │ │ └── index.js
│ │ │ ├── Player.jsx
│ │ │ └── Timer.jsx
│ │ ├── screens
│ │ │ ├── PhoneScreen.jsx
│ │ │ ├── Screen.jsx
│ │ │ ├── SessionScreen.jsx
│ │ │ ├── SettingsScreen.jsx
│ │ │ └── index.js
│ │ ├── store
│ │ │ ├── Cdr.js
│ │ │ ├── Contacts.js
│ │ │ ├── Context.js
│ │ │ ├── Electron.js
│ │ │ └── Events.js
│ │ └── utils.js
│ ├── stories
│ │ ├── App.stories.js
│ │ ├── CancelAccept.stories.js
│ │ ├── DialGrid.stories.js
│ │ ├── DialPad.stories.js
│ │ ├── Dialer.stories.js
│ │ ├── Screen.stories.js
│ │ ├── SessionScreen.stories.js
│ │ └── SettingsScreen.stories.js
│ ├── web
│ │ ├── assets
│ │ │ ├── fonts
│ │ │ │ └── Roboto-Flex.ttf
│ │ │ ├── icons
│ │ │ │ ├── 008.svg
│ │ │ │ └── unanchor.svg
│ │ │ └── sounds
│ │ │ │ ├── busy.mp3
│ │ │ │ ├── dtmf
│ │ │ │ ├── dtmf-0.mp3
│ │ │ │ ├── dtmf-1.mp3
│ │ │ │ ├── dtmf-2.mp3
│ │ │ │ ├── dtmf-3.mp3
│ │ │ │ ├── dtmf-4.mp3
│ │ │ │ ├── dtmf-5.mp3
│ │ │ │ ├── dtmf-6.mp3
│ │ │ │ ├── dtmf-7.mp3
│ │ │ │ ├── dtmf-8.mp3
│ │ │ │ ├── dtmf-9.mp3
│ │ │ │ ├── dtmf-hash.mp3
│ │ │ │ └── dtmf-star.mp3
│ │ │ │ ├── ring.mp3
│ │ │ │ └── ringback.mp3
│ │ ├── avatar.png
│ │ ├── cfgDemo008.json
│ │ ├── favicon.png
│ │ ├── icon.png
│ │ └── index.html
│ ├── webpack.config.js
│ └── yarn.lock
├── 008Q
│ ├── .eslintignore
│ ├── .eslintrc.js
│ ├── index.js
│ ├── package.json
│ ├── playground
│ │ ├── carrental.mp3
│ │ ├── carrental.ogg
│ │ ├── carrental.wav
│ │ ├── index.html
│ │ ├── index.js
│ │ └── static
│ │ │ ├── ort-wasm-simd-threaded.jsep.wasm
│ │ │ ├── ort-wasm-simd-threaded.wasm
│ │ │ ├── ort-wasm-simd.jsep.wasm
│ │ │ ├── ort-wasm-simd.wasm
│ │ │ ├── ort-wasm-threaded.wasm
│ │ │ └── ort-wasm.wasm
│ ├── src
│ │ └── Q.js
│ └── webpack.config.js
├── 008desktop
│ ├── .eslintignore
│ ├── .eslintrc.js
│ ├── .prettierignore
│ ├── .prettierrc
│ ├── assets
│ │ ├── logo-round.png
│ │ ├── logo.png
│ │ ├── tray.ico
│ │ ├── tray@2x.png
│ │ ├── trayd@2x.png
│ │ ├── trayl@2x.png
│ │ └── trayp@2x.png
│ ├── build
│ │ └── entitlements.mac.plist
│ ├── index.js
│ ├── loader.js
│ ├── package.json
│ ├── scripts
│ │ └── notarize.js
│ ├── utils.js
│ └── yarn.lock
└── web-llm
│ ├── cache_util.d.ts
│ ├── cache_util.d.ts.map
│ ├── chat_module.d.ts
│ ├── chat_module.d.ts.map
│ ├── config.d.ts
│ ├── config.d.ts.map
│ ├── conversation.d.ts
│ ├── conversation.d.ts.map
│ ├── engine.d.ts
│ ├── engine.d.ts.map
│ ├── grammar.d.ts
│ ├── grammar.d.ts.map
│ ├── index.d.ts
│ ├── index.d.ts.map
│ ├── index.js
│ ├── index.js.map
│ ├── llm_chat.d.ts
│ ├── llm_chat.d.ts.map
│ ├── message.d.ts
│ ├── message.d.ts.map
│ ├── openai_api_protocols
│ ├── apis.d.ts
│ ├── apis.d.ts.map
│ ├── chat_completion.d.ts
│ ├── chat_completion.d.ts.map
│ ├── index.d.ts
│ └── index.d.ts.map
│ ├── service_worker.d.ts
│ ├── service_worker.d.ts.map
│ ├── support.d.ts
│ ├── support.d.ts.map
│ ├── types.d.ts
│ ├── types.d.ts.map
│ ├── web_worker.d.ts
│ └── web_worker.d.ts.map
└── yarn.lock
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: build
2 |
3 | on:
4 | push:
5 | tags:
6 | - "v*"
7 |
8 | jobs:
9 | build:
10 | runs-on: [self-hosted, M1]
11 | permissions:
12 | contents: write
13 |
14 | steps:
15 | - uses: actions/checkout@v2
16 |
17 | - uses: actions/setup-node@v2
18 | with:
19 | node-version: "18"
20 |
21 | - name: Build
22 | env:
23 | # CSC_LINK: ${{ secrets.MACOS_CERT }}
24 | # CSC_KEY_PASSWORD: ${{ secrets.MACOS_CERT_PASS }}
25 | NOT_APPLE_ID: ${{ secrets.APPLE_ID }}
26 | NOT_APPLE_ID_PASS: ${{ secrets.APPLE_ID_PASS }}
27 | run: |
28 | yarn install
29 | yarn run build-desktop
30 |
31 | - name: Upload artifacts
32 | uses: actions/upload-artifact@v2
33 | with:
34 | retention-days: 1
35 | path: |
36 | packages/008desktop/build/008-desktop-win.exe
37 | packages/008desktop/build/008-desktop-mac.dmg
38 | packages/008desktop/build/008-desktop-linux.AppImage
39 |
40 | sign-win:
41 | needs: build
42 | runs-on: windows-latest
43 | permissions:
44 | contents: write
45 |
46 | steps:
47 | - name: Download artifacts
48 | uses: actions/download-artifact@v2
49 | with:
50 | name: artifact
51 | path: bin
52 |
53 | - name: Sign win
54 | shell: bash
55 | run: |
56 | dotnet tool install --global AzureSignTool
57 | AzureSignTool sign -kvu "${{ secrets.AZURE_KEY_VAULT_URI }}" -kvi "${{ secrets.AZURE_CLIENT_ID }}" -kvt "${{ secrets.AZURE_TENANT_ID }}" -kvs "${{ secrets.AZURE_CLIENT_SECRET }}" -kvc ${{ secrets.AZURE_CERT_NAME }} -tr http://timestamp.digicert.com -v "bin/008-desktop-win.exe"
58 |
59 | - name: Release
60 | uses: softprops/action-gh-release@v1
61 | with:
62 | draft: true
63 | files: |
64 | bin/008-desktop*
65 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: deploy
2 |
3 | on:
4 | release:
5 | types: [released]
6 | workflow_dispatch:
7 |
8 | jobs:
9 | deploy:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - name: Upload agent008.ai
14 | timeout-minutes: 15
15 | shell: bash
16 | env:
17 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
18 | run: |
19 | gh release download --repo kunzite-app/008 --pattern '008-desktop*' --dir bin
20 |
21 | ls bin
22 | mkdir -p ~/.ssh
23 | ssh-keyscan -p ${{ secrets.SITE_PORT }} ${{ secrets.SITE_HOST }} >> ~/.ssh/known_hosts
24 |
25 | echo "${{ secrets.SITE_SSH_KEY }}" > private.key
26 | chmod 600 private.key
27 |
28 | scp -P ${{ secrets.SITE_PORT }} -i private.key -r bin ${{ secrets.SITE_USER }}@${{ secrets.SITE_HOST }}:~/public
29 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 | on: pull_request
3 |
4 | jobs:
5 | test:
6 | env:
7 | SDL_VIDEODRIVER: "dummy"
8 | SDL_AUDIODRIVER: "disk"
9 |
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - uses: actions/checkout@v4
14 |
15 | - uses: actions/setup-node@v4
16 | with:
17 | node-version: 18
18 |
19 | - name: prerequisites
20 | run: |
21 | yarn install
22 |
23 | - name: lint
24 | run: |
25 | yarn lint
26 |
27 | - name: tests
28 | run: |
29 | yarn run e2e
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | tmp/
4 | build/
5 | lib/
6 | dist/
7 | node_modules/
8 | storybook-static/
9 |
10 | /.pnp/
11 | **/.pnp.js
12 |
13 | # misc
14 | .DS_Store
15 | .env.local
16 | .env.development.local
17 | .env.test.local
18 | .env.production.local
19 | .eslintcache
20 |
21 | **/npm-debug.log*
22 | **/yarn-debug.log*
23 | **/yarn-error.log*
24 | **/lerna-debug.log*
25 |
26 | **/.vscode
27 |
28 | packages/008desktop/app
29 | packages/008desktop/binaries
30 | packages/008desktop/build/*
31 | !packages/008desktop/build/
32 | !packages/008desktop/build/entitlements.mac.plist
33 | packages/008Q/**/models
34 | !packages/web-llm/lib
35 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | . "$(dirname -- "$0")/_/husky.sh"
3 |
4 | npx lint-staged
5 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "node_modules/lerna/schemas/lerna-schema.json",
3 | "npmClient": "yarn",
4 | "useWorkspaces": true,
5 | "version": "independent"
6 | }
7 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "kunzite",
3 | "private": true,
4 | "workspaces": [
5 | "packages/*"
6 | ],
7 | "devDependencies": {
8 | "husky": "^8.0.0",
9 | "lerna": "^6.1.0",
10 | "lint-staged": "^13.1.0"
11 | },
12 | "scripts": {
13 | "start": "yarn start-desktop",
14 | "start-desktop": "lerna run web --scope @kunzite/008 & lerna run start --scope 008desktop",
15 | "build-web": "lerna run build-web",
16 | "build-desktop": "IS_ELECTRON=yes lerna run build-web && rm -rf packages/008desktop/app && mv packages/008/web-build packages/008desktop/app && cp -R packages/008desktop/app/static/ packages/008desktop/app/static2/ && mv packages/008desktop/app/static2 packages/008desktop/app/static/js/static && lerna run build --scope 008desktop",
17 | "clean": "lerna clean",
18 | "prepare": "husky install",
19 | "lint": "lerna run lint",
20 | "e2e": "lerna run e2e --scope @kunzite/008"
21 | },
22 | "lint-staged": {
23 | "**/*.{js}": [
24 | "lerna run lint -- --fix --quiet",
25 | "lerna run format -- --write ."
26 | ],
27 | "**/*.{json,md,yaml,yml}": [
28 | "lerna run format -- --write ."
29 | ]
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/008/.eslintignore:
--------------------------------------------------------------------------------
1 | lib
2 | node_modules
3 | build
4 | web-build
5 | metro.config.js
6 |
--------------------------------------------------------------------------------
/packages/008/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['universe/native', 'universe/web', 'plugin:cypress/recommended'],
3 | env: {
4 | browser: true,
5 | node: true
6 | }
7 | };
8 |
--------------------------------------------------------------------------------
/packages/008/.gitignore:
--------------------------------------------------------------------------------
1 | # Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
2 |
3 | # dependencies
4 | node_modules/
5 |
6 | # Expo
7 | .expo/
8 | dist/
9 | web-build/
10 |
11 | # Native
12 | *.orig.*
13 | *.jks
14 | *.p8
15 | *.p12
16 | *.key
17 | *.mobileprovision
18 |
19 | # Metro
20 | .metro-health-check*
21 |
22 | # debug
23 | npm-debug.*
24 | yarn-debug.*
25 | yarn-error.*
26 |
27 | # macOS
28 | .DS_Store
29 | *.pem
30 |
31 | # local env files
32 | .env*.local
33 |
34 | # typescript
35 | *.tsbuildinfo
36 |
37 | # @generated: @expo/electron-adapter@0.0.55
38 | /.expo/*
39 | # Expo Web
40 | /web-build/*
41 | # electron-webpack
42 | /dist
43 | # @end @expo/electron-adapter
44 |
45 | /web/config*.json
46 | /web/*.webm
47 | /web/*.wav
48 | /web/*.ogg
49 | /web/*.mp3
50 | /web/*.bin
51 |
--------------------------------------------------------------------------------
/packages/008/.prettierignore:
--------------------------------------------------------------------------------
1 | lib
2 | node_modules
3 | build
4 |
--------------------------------------------------------------------------------
/packages/008/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 80,
3 | "tabWidth": 2,
4 | "useTabs": false,
5 | "arrowParens": "avoid",
6 | "singleQuote": true,
7 | "trailingComma": "none",
8 | "proseWrap": "always",
9 | "jsxSingleQuote": false
10 | }
11 |
--------------------------------------------------------------------------------
/packages/008/.storybook-web/main.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | stories: ['../stories/**/*.stories.?(ts|tsx|js|jsx)'],
3 | addons: ['@storybook/addon-essentials', '@storybook/addon-react-native-web'],
4 | core: {
5 | builder: 'webpack5'
6 | },
7 | framework: '@storybook/react',
8 | staticDirs: ['../web']
9 | };
10 |
--------------------------------------------------------------------------------
/packages/008/.storybook-web/preview.js:
--------------------------------------------------------------------------------
1 | import { View } from 'react-native';
2 |
3 | export const parameters = {
4 | controls: {
5 | matchers: {
6 | color: /(background|color)$/i,
7 | date: /Date$/
8 | }
9 | }
10 | };
11 |
12 | export const decorators = [
13 | Story => (
14 |
15 |
16 |
17 | )
18 | ];
19 |
--------------------------------------------------------------------------------
/packages/008/.storybook/index.js:
--------------------------------------------------------------------------------
1 | import { getStorybookUI } from '@storybook/react-native';
2 |
3 | import './storybook.requires';
4 |
5 | const StorybookUIRoot = getStorybookUI({});
6 |
7 | export default StorybookUIRoot;
8 |
--------------------------------------------------------------------------------
/packages/008/.storybook/main.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | stories: ['../stories/**/*.stories.?(ts|tsx|js|jsx)'],
3 | addons: [
4 | '@storybook/addon-ondevice-controls',
5 | '@storybook/addon-ondevice-actions'
6 | ]
7 | };
8 |
--------------------------------------------------------------------------------
/packages/008/.storybook/preview.js:
--------------------------------------------------------------------------------
1 | import { View } from 'react-native';
2 |
3 | export const parameters = {
4 | controls: {
5 | matchers: {
6 | color: /(background|color)$/i,
7 | date: /Date$/
8 | }
9 | }
10 | };
11 |
12 | export const decorators = [
13 | Story => (
14 |
15 |
16 |
17 | )
18 | ];
19 |
--------------------------------------------------------------------------------
/packages/008/.storybook/storybook.requires.js:
--------------------------------------------------------------------------------
1 | /* do not change this file, it is auto generated by storybook. */
2 |
3 | import {
4 | configure,
5 | addDecorator,
6 | addParameters,
7 | addArgsEnhancer,
8 | clearDecorators
9 | } from '@storybook/react-native';
10 |
11 | global.STORIES = [
12 | {
13 | titlePrefix: '',
14 | directory: './stories',
15 | files: '**/*.stories.?(ts|tsx|js|jsx)',
16 | importPathMatcher:
17 | '^\\.[\\\\/](?:stories(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$'
18 | }
19 | ];
20 |
21 | import '@storybook/addon-ondevice-controls/register';
22 | import '@storybook/addon-ondevice-actions/register';
23 |
24 | import { argsEnhancers } from '@storybook/addon-actions/dist/modern/preset/addArgs';
25 |
26 | import { decorators, parameters } from './preview';
27 |
28 | if (decorators) {
29 | if (__DEV__) {
30 | // stops the warning from showing on every HMR
31 | require('react-native').LogBox.ignoreLogs([
32 | '`clearDecorators` is deprecated and will be removed in Storybook 7.0'
33 | ]);
34 | }
35 | // workaround for global decorators getting infinitely applied on HMR, see https://github.com/storybookjs/react-native/issues/185
36 | clearDecorators();
37 | decorators.forEach(decorator => addDecorator(decorator));
38 | }
39 |
40 | if (parameters) {
41 | addParameters(parameters);
42 | }
43 |
44 | try {
45 | argsEnhancers.forEach(enhancer => addArgsEnhancer(enhancer));
46 | } catch {}
47 |
48 | const getStories = () => {
49 | return {
50 | './stories/App.stories.js': require('../stories/App.stories.js'),
51 | './stories/LoginScreen.stories.js': require('../stories/LoginScreen.stories.js'),
52 | './stories/PhoneScreen.stories.js': require('../stories/PhoneScreen.stories.js'),
53 | './stories/Screen.stories.js': require('../stories/Screen.stories.js'),
54 | './stories/SettingsScreen.stories.js': require('../stories/SettingsScreen.stories.js')
55 | };
56 | };
57 |
58 | configure(getStories, module, false);
59 |
--------------------------------------------------------------------------------
/packages/008/App.js:
--------------------------------------------------------------------------------
1 | import _ from 'lodash';
2 | import { useEffect } from 'react';
3 | import { View } from 'react-native';
4 |
5 | import { ApplicationInsights } from '@microsoft/applicationinsights-web';
6 | import {
7 | AppInsightsErrorBoundary,
8 | ReactPlugin
9 | } from '@microsoft/applicationinsights-react-js';
10 |
11 | import { Button, COLORS, Text } from './src/components/Basics';
12 | import { Container } from './src/components/Container';
13 | import { SettingsScreen, PhoneScreen } from './src/screens';
14 | import { ContextProvider, useStore } from './src/store/Context';
15 |
16 | const reactPlugin = new ReactPlugin();
17 | const appInsights = new ApplicationInsights({
18 | config: {
19 | connectionString:
20 | 'InstrumentationKey=89ba4ad2-47ef-41e8-a151-4b3488132c63;IngestionEndpoint=https://westeurope-5.in.applicationinsights.azure.com/;LiveEndpoint=https://westeurope.livediagnostics.monitor.azure.com/',
21 | extensions: [reactPlugin]
22 | }
23 | });
24 | appInsights.loadAppInsights();
25 | appInsights.trackPageView();
26 |
27 | export default function App() {
28 | const store = useStore();
29 | const { settingsUri, toggleShowSettings, server, showSettings } = store;
30 |
31 | useEffect(() => {
32 | const mustSettings = !settingsUri;
33 | if (mustSettings) toggleShowSettings(true, 'connection');
34 | else toggleShowSettings(false);
35 | }, [settingsUri]);
36 |
37 | return (
38 | (
40 |
43 |
52 |
53 | )}
54 | appInsights={reactPlugin}
55 | >
56 |
57 |
58 | {!server && }
59 |
63 |
64 |
65 |
66 | );
67 | }
68 |
--------------------------------------------------------------------------------
/packages/008/android/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Android/IntelliJ
6 | #
7 | build/
8 | .idea
9 | .gradle
10 | local.properties
11 | *.iml
12 | *.hprof
13 |
14 | # Bundle artifacts
15 | *.jsbundle
16 |
--------------------------------------------------------------------------------
/packages/008/android/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/debug.keystore
--------------------------------------------------------------------------------
/packages/008/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # react-native-reanimated
11 | -keep class com.swmansion.reanimated.** { *; }
12 | -keep class com.facebook.react.turbomodule.** { *; }
13 |
14 | # Add any project specific keep options here:
15 |
--------------------------------------------------------------------------------
/packages/008/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/packages/008/android/app/src/debug/java/com/anonymous/softphone/ReactNativeFlipper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | *
This source code is licensed under the MIT license found in the LICENSE file in the root
5 | * directory of this source tree.
6 | */
7 | package com.anonymous.softphone;
8 |
9 | import android.content.Context;
10 | import com.facebook.flipper.android.AndroidFlipperClient;
11 | import com.facebook.flipper.android.utils.FlipperUtils;
12 | import com.facebook.flipper.core.FlipperClient;
13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping;
17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
20 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
21 | import com.facebook.react.ReactInstanceEventListener;
22 | import com.facebook.react.ReactInstanceManager;
23 | import com.facebook.react.bridge.ReactContext;
24 | import com.facebook.react.modules.network.NetworkingModule;
25 | import okhttp3.OkHttpClient;
26 |
27 | /**
28 | * Class responsible of loading Flipper inside your React Native application. This is the debug
29 | * flavor of it. Here you can add your own plugins and customize the Flipper setup.
30 | */
31 | public class ReactNativeFlipper {
32 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
33 | if (FlipperUtils.shouldEnableFlipper(context)) {
34 | final FlipperClient client = AndroidFlipperClient.getInstance(context);
35 |
36 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
37 | client.addPlugin(new DatabasesFlipperPlugin(context));
38 | client.addPlugin(new SharedPreferencesFlipperPlugin(context));
39 | client.addPlugin(CrashReporterPlugin.getInstance());
40 |
41 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
42 | NetworkingModule.setCustomClientBuilder(
43 | new NetworkingModule.CustomClientBuilder() {
44 | @Override
45 | public void apply(OkHttpClient.Builder builder) {
46 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
47 | }
48 | });
49 | client.addPlugin(networkFlipperPlugin);
50 | client.start();
51 |
52 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
53 | // Hence we run if after all native modules have been initialized
54 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
55 | if (reactContext == null) {
56 | reactInstanceManager.addReactInstanceEventListener(
57 | new ReactInstanceEventListener() {
58 | @Override
59 | public void onReactContextInitialized(ReactContext reactContext) {
60 | reactInstanceManager.removeReactInstanceEventListener(this);
61 | reactContext.runOnNativeModulesQueueThread(
62 | new Runnable() {
63 | @Override
64 | public void run() {
65 | client.addPlugin(new FrescoFlipperPlugin());
66 | }
67 | });
68 | }
69 | });
70 | } else {
71 | client.addPlugin(new FrescoFlipperPlugin());
72 | }
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/java/com/anonymous/softphone/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.anonymous.softphone;
2 |
3 | import android.os.Build;
4 | import android.os.Bundle;
5 |
6 | import com.facebook.react.ReactActivity;
7 | import com.facebook.react.ReactActivityDelegate;
8 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
9 | import com.facebook.react.defaults.DefaultReactActivityDelegate;
10 |
11 | import expo.modules.ReactActivityDelegateWrapper;
12 |
13 | public class MainActivity extends ReactActivity {
14 | @Override
15 | protected void onCreate(Bundle savedInstanceState) {
16 | // Set the theme to AppTheme BEFORE onCreate to support
17 | // coloring the background, status bar, and navigation bar.
18 | // This is required for expo-splash-screen.
19 | setTheme(R.style.AppTheme);
20 | super.onCreate(null);
21 | }
22 |
23 | /**
24 | * Returns the name of the main component registered from JavaScript.
25 | * This is used to schedule rendering of the component.
26 | */
27 | @Override
28 | protected String getMainComponentName() {
29 | return "main";
30 | }
31 |
32 | /**
33 | * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link
34 | * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React
35 | * (aka React 18) with two boolean flags.
36 | */
37 | @Override
38 | protected ReactActivityDelegate createReactActivityDelegate() {
39 | return new ReactActivityDelegateWrapper(this, BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, new DefaultReactActivityDelegate(
40 | this,
41 | getMainComponentName(),
42 | // If you opted-in for the New Architecture, we enable the Fabric Renderer.
43 | DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled
44 | // If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18).
45 | DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled
46 | ));
47 | }
48 |
49 | /**
50 | * Align the back button behavior with Android S
51 | * where moving root activities to background instead of finishing activities.
52 | * @see onBackPressed
53 | */
54 | @Override
55 | public void invokeDefaultOnBackPressed() {
56 | if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) {
57 | if (!moveTaskToBack(false)) {
58 | // For non-root activities, use the default implementation to finish them.
59 | super.invokeDefaultOnBackPressed();
60 | }
61 | return;
62 | }
63 |
64 | // Use the default back button implementation on Android S
65 | // because it's doing more than {@link Activity#moveTaskToBack} in fact.
66 | super.invokeDefaultOnBackPressed();
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/java/com/anonymous/softphone/MainApplication.java:
--------------------------------------------------------------------------------
1 | package com.anonymous.softphone;
2 |
3 | import android.app.Application;
4 | import android.content.res.Configuration;
5 | import androidx.annotation.NonNull;
6 |
7 | import com.facebook.react.PackageList;
8 | import com.facebook.react.ReactApplication;
9 | import com.facebook.react.ReactNativeHost;
10 | import com.facebook.react.ReactPackage;
11 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
12 | import com.facebook.react.defaults.DefaultReactNativeHost;
13 | import com.facebook.soloader.SoLoader;
14 |
15 | import expo.modules.ApplicationLifecycleDispatcher;
16 | import expo.modules.ReactNativeHostWrapper;
17 |
18 | import java.util.List;
19 |
20 | public class MainApplication extends Application implements ReactApplication {
21 |
22 | private final ReactNativeHost mReactNativeHost =
23 | new ReactNativeHostWrapper(this, new DefaultReactNativeHost(this) {
24 | @Override
25 | public boolean getUseDeveloperSupport() {
26 | return BuildConfig.DEBUG;
27 | }
28 |
29 | @Override
30 | protected List getPackages() {
31 | @SuppressWarnings("UnnecessaryLocalVariable")
32 | List packages = new PackageList(this).getPackages();
33 | // Packages that cannot be autolinked yet can be added manually here, for example:
34 | // packages.add(new MyReactNativePackage());
35 | return packages;
36 | }
37 |
38 | @Override
39 | protected String getJSMainModuleName() {
40 | return "index";
41 | }
42 |
43 | @Override
44 | protected boolean isNewArchEnabled() {
45 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
46 | }
47 |
48 | @Override
49 | protected Boolean isHermesEnabled() {
50 | return BuildConfig.IS_HERMES_ENABLED;
51 | }
52 | });
53 |
54 | @Override
55 | public ReactNativeHost getReactNativeHost() {
56 | return mReactNativeHost;
57 | }
58 |
59 | @Override
60 | public void onCreate() {
61 | super.onCreate();
62 | SoLoader.init(this, /* native exopackage */ false);
63 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
64 | // If you opted-in for the New Architecture, we load the native entry point for this app.
65 | DefaultNewArchitectureEntryPoint.load();
66 | }
67 | ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
68 | ApplicationLifecycleDispatcher.onApplicationCreate(this);
69 | }
70 |
71 | @Override
72 | public void onConfigurationChanged(@NonNull Configuration newConfig) {
73 | super.onConfigurationChanged(newConfig);
74 | ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/drawable-hdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/drawable-hdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/drawable-mdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/drawable-mdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/drawable-xhdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/drawable-xhdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/drawable-xxhdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/drawable-xxhdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/drawable-xxxhdpi/splashscreen_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/drawable-xxxhdpi/splashscreen_image.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/drawable/rn_edit_text_material.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
21 |
22 |
23 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/drawable/splashscreen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 | #ffffff
3 | #ffffff
4 | #023c69
5 | #ffffff
6 |
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | softphone
3 | contain
4 | false
5 |
--------------------------------------------------------------------------------
/packages/008/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
14 |
17 |
--------------------------------------------------------------------------------
/packages/008/android/app/src/release/java/com/anonymous/softphone/ReactNativeFlipper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | * This source code is licensed under the MIT license found in the LICENSE file in the root
5 | * directory of this source tree.
6 | */
7 | package com.anonymous.softphone;
8 |
9 | import android.content.Context;
10 | import com.facebook.react.ReactInstanceManager;
11 |
12 | /**
13 | * Class responsible of loading Flipper inside your React Native application. This is the release
14 | * flavor of it so it's empty as we don't want to load Flipper.
15 | */
16 | public class ReactNativeFlipper {
17 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
18 | // Do nothing as we don't want to initialize Flipper on Release.
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/008/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext {
5 | buildToolsVersion = findProperty('android.buildToolsVersion') ?: '33.0.0'
6 | minSdkVersion = Integer.parseInt(findProperty('android.minSdkVersion') ?: '21')
7 | compileSdkVersion = Integer.parseInt(findProperty('android.compileSdkVersion') ?: '33')
8 | targetSdkVersion = Integer.parseInt(findProperty('android.targetSdkVersion') ?: '33')
9 | if (findProperty('android.kotlinVersion')) {
10 | kotlinVersion = findProperty('android.kotlinVersion')
11 | }
12 | frescoVersion = findProperty('expo.frescoVersion') ?: '2.5.0'
13 |
14 | // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
15 | ndkVersion = "23.1.7779620"
16 | }
17 | repositories {
18 | google()
19 | mavenCentral()
20 | }
21 | dependencies {
22 | classpath('com.android.tools.build:gradle:7.4.1')
23 | classpath('com.facebook.react:react-native-gradle-plugin')
24 | }
25 | }
26 |
27 | allprojects {
28 | repositories {
29 | maven {
30 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
31 | url(new File(['node', '--print', "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim(), '../android'))
32 | }
33 | maven {
34 | // Android JSC is installed from npm
35 | url(new File(['node', '--print', "require.resolve('jsc-android/package.json')"].execute(null, rootDir).text.trim(), '../dist'))
36 | }
37 |
38 | google()
39 | mavenCentral()
40 | maven { url 'https://www.jitpack.io' }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/packages/008/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | # AndroidX package structure to make it clearer which packages are bundled with the
21 | # Android operating system, and which are packaged with your app's APK
22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
23 | android.useAndroidX=true
24 |
25 | # Automatically convert third-party libraries to use AndroidX
26 | android.enableJetifier=true
27 |
28 | # Version of flipper SDK to use with React Native
29 | FLIPPER_VERSION=0.125.0
30 |
31 | # Use this property to specify which architecture you want to build.
32 | # You can also override it from the CLI using
33 | # ./gradlew -PreactNativeArchitectures=x86_64
34 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
35 |
36 | # Use this property to enable support to the new architecture.
37 | # This will allow you to use TurboModules and the Fabric render in
38 | # your application. You should enable this flag either if you want
39 | # to write custom TurboModules/Fabric components OR use libraries that
40 | # are providing them.
41 | newArchEnabled=false
42 |
43 | # The hosted JavaScript engine
44 | # Supported values: expo.jsEngine = "hermes" | "jsc"
45 | expo.jsEngine=hermes
46 |
47 | # Enable GIF support in React Native images (~200 B increase)
48 | expo.gif.enabled=true
49 | # Enable webp support in React Native images (~85 KB increase)
50 | expo.webp.enabled=true
51 | # Enable animated webp support (~3.4 MB increase)
52 | # Disabled by default because iOS doesn't support animated webp
53 | expo.webp.animated=false
54 |
--------------------------------------------------------------------------------
/packages/008/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/packages/008/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/packages/008/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if %ERRORLEVEL% equ 0 goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if %ERRORLEVEL% equ 0 goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | set EXIT_CODE=%ERRORLEVEL%
84 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
85 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
86 | exit /b %EXIT_CODE%
87 |
88 | :mainEnd
89 | if "%OS%"=="Windows_NT" endlocal
90 |
91 | :omega
92 |
--------------------------------------------------------------------------------
/packages/008/android/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'softphone'
2 |
3 | apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle");
4 | useExpoModules()
5 |
6 | apply from: new File(["node", "--print", "require.resolve('@react-native-community/cli-platform-android/package.json')"].execute(null, rootDir).text.trim(), "../native_modules.gradle");
7 | applyNativeModulesSettingsGradle(settings)
8 |
9 | include ':app'
10 | includeBuild(new File(["node", "--print", "require.resolve('react-native-gradle-plugin/package.json')"].execute(null, rootDir).text.trim()).getParentFile())
11 |
--------------------------------------------------------------------------------
/packages/008/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "008",
4 | "slug": "008",
5 | "version": "1.0.0",
6 | "orientation": "portrait",
7 | "icon": "./assets/icon.png",
8 | "userInterfaceStyle": "light",
9 | "splash": {
10 | "image": "./assets/splash.png",
11 | "resizeMode": "contain",
12 | "backgroundColor": "#f02f65"
13 | },
14 | "assetBundlePatterns": ["**/*"],
15 | "ios": {
16 | "supportsTablet": true,
17 | "bundleIdentifier": "app.kunzite.008"
18 | },
19 | "android": {
20 | "adaptiveIcon": {
21 | "foregroundImage": "./assets/adaptive-icon.png",
22 | "backgroundColor": "#ffffff"
23 | },
24 | "package": "app.kunzite.008"
25 | },
26 | "web": {
27 | "favicon": "./web/favicon.png"
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/packages/008/assets/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/assets/adaptive-icon.png
--------------------------------------------------------------------------------
/packages/008/assets/fonts/Roboto-Flex.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/assets/fonts/Roboto-Flex.ttf
--------------------------------------------------------------------------------
/packages/008/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/assets/icon.png
--------------------------------------------------------------------------------
/packages/008/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/assets/splash.png
--------------------------------------------------------------------------------
/packages/008/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function (api) {
2 | api.cache(true);
3 | return {
4 | presets: ['babel-preset-expo']
5 | };
6 | };
7 |
--------------------------------------------------------------------------------
/packages/008/cypress.config.js:
--------------------------------------------------------------------------------
1 | const { defineConfig } = require('cypress');
2 |
3 | module.exports = defineConfig({
4 | e2e: {
5 | baseUrl: 'http://localhost:19006'
6 | }
7 | });
8 |
--------------------------------------------------------------------------------
/packages/008/cypress/e2e/spec.cy.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable cypress/no-unnecessary-waiting */
2 |
3 | const TEST_NUMBER = '007';
4 | const TRANSFER_NUMBER = '008';
5 |
6 | beforeEach(() => {
7 | cy.visit('/');
8 |
9 | cy.get('[data-testid="Settings"]').type('cfgDemo008.json');
10 | cy.get('[data-testid="settingsAccept"]').click();
11 | cy.wait(2000);
12 | });
13 |
14 | describe('Outbound Call test', () => {
15 | it('no input does nothing', () => {
16 | cy.get('[data-testid="callButton"]').click();
17 | });
18 |
19 | it('Calls number and hangs', () => {
20 | cy.get('[data-testid="dialerTextInput"]').type(TEST_NUMBER);
21 | cy.get('[data-testid="callButton"]').click();
22 |
23 | cy.wait(1000);
24 | cy.get('[data-testid="hangupButton"]').click();
25 | });
26 |
27 | it('Call number and blind transfer', () => {
28 | cy.get('[data-testid="dialerTextInput"]').type(TEST_NUMBER);
29 | cy.get('[data-testid="callButton"]').click();
30 |
31 | cy.wait(1000);
32 | cy.get('[data-testid="blindTransferButton"]').click();
33 |
34 | cy.get('[data-testid="transferDialerdialerTextInput"]').type(
35 | TRANSFER_NUMBER
36 | );
37 | cy.get('[data-testid="transferButton"]').click();
38 | });
39 |
40 | it('VideoCall number and hangs', () => {
41 | cy.get('[data-testid="dialerTextInput"]').type(TEST_NUMBER);
42 | cy.get('[data-testid="videoCallButton"]').click();
43 |
44 | cy.wait(1000);
45 | cy.get('[data-testid="hangupButton"]').click();
46 | });
47 | });
48 |
--------------------------------------------------------------------------------
/packages/008/cypress/fixtures/example.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Using fixtures to represent data",
3 | "email": "hello@cypress.io",
4 | "body": "Fixtures are a great way to mock data for responses to routes"
5 | }
6 |
--------------------------------------------------------------------------------
/packages/008/cypress/support/commands.js:
--------------------------------------------------------------------------------
1 | // ***********************************************
2 | // This example commands.js shows you how to
3 | // create various custom commands and overwrite
4 | // existing commands.
5 | //
6 | // For more comprehensive examples of custom
7 | // commands please read more here:
8 | // https://on.cypress.io/custom-commands
9 | // ***********************************************
10 | //
11 | //
12 | // -- This is a parent command --
13 | // Cypress.Commands.add('login', (email, password) => { ... })
14 | //
15 | //
16 | // -- This is a child command --
17 | // Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
18 | //
19 | //
20 | // -- This is a dual command --
21 | // Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
22 | //
23 | //
24 | // -- This will overwrite an existing command --
25 | // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
26 |
--------------------------------------------------------------------------------
/packages/008/cypress/support/e2e.js:
--------------------------------------------------------------------------------
1 | // ***********************************************************
2 | // This example support/e2e.js is processed and
3 | // loaded automatically before your test files.
4 | //
5 | // This is a great place to put global configuration and
6 | // behavior that modifies Cypress.
7 | //
8 | // You can change the location of this file or turn off
9 | // automatically serving support files with the
10 | // 'supportFile' configuration option.
11 | //
12 | // You can read more here:
13 | // https://on.cypress.io/configuration
14 | // ***********************************************************
15 |
16 | // Import commands.js using ES2015 syntax:
17 | import './commands';
18 |
19 | // Alternatively you can use CommonJS syntax:
20 | // require('./commands')
21 |
--------------------------------------------------------------------------------
/packages/008/index.js:
--------------------------------------------------------------------------------
1 | import { registerRootComponent } from 'expo';
2 |
3 | import App from './App';
4 |
5 | // registerRootComponent calls AppRegistry.registerComponent('main', () => App);
6 | // It also ensures that whether you load the app in Expo Go or in a native build,
7 | // the environment is set up appropriately
8 | registerRootComponent(App);
9 |
--------------------------------------------------------------------------------
/packages/008/ios/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | project.xcworkspace
24 | .xcode.env.local
25 |
26 | # Bundle artifacts
27 | *.jsbundle
28 |
29 | # CocoaPods
30 | /Pods/
31 |
--------------------------------------------------------------------------------
/packages/008/ios/.xcode.env:
--------------------------------------------------------------------------------
1 | # This `.xcode.env` file is versioned and is used to source the environment
2 | # used when running script phases inside Xcode.
3 | # To customize your local environment, you can create an `.xcode.env.local`
4 | # file that is not versioned.
5 |
6 | # NODE_BINARY variable contains the PATH to the node executable.
7 | #
8 | # Customize the NODE_BINARY variable here.
9 | # For example, to use nvm with brew, add the following line
10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use
11 | export NODE_BINARY=$(command -v node)
12 |
--------------------------------------------------------------------------------
/packages/008/ios/Podfile:
--------------------------------------------------------------------------------
1 | require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
2 | require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods")
3 | require File.join(File.dirname(`node --print "require.resolve('@react-native-community/cli-platform-ios/package.json')"`), "native_modules")
4 |
5 | require 'json'
6 | podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {}
7 |
8 | ENV['RCT_NEW_ARCH_ENABLED'] = podfile_properties['newArchEnabled'] == 'true' ? '1' : '0'
9 | ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] = '1' if podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR'] == 'true'
10 |
11 | platform :ios, podfile_properties['ios.deploymentTarget'] || '13.0'
12 | install! 'cocoapods',
13 | :deterministic_uuids => false
14 |
15 | prepare_react_native_project!
16 |
17 | # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.
18 | # because `react-native-flipper` depends on (FlipperKit,...), which will be excluded. To fix this,
19 | # you can also exclude `react-native-flipper` in `react-native.config.js`
20 | #
21 | # ```js
22 | # module.exports = {
23 | # dependencies: {
24 | # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
25 | # }
26 | # }
27 | # ```
28 | flipper_config = FlipperConfiguration.disabled
29 | if ENV['NO_FLIPPER'] == '1' then
30 | # Explicitly disabled through environment variables
31 | flipper_config = FlipperConfiguration.disabled
32 | elsif podfile_properties.key?('ios.flipper') then
33 | # Configure Flipper in Podfile.properties.json
34 | if podfile_properties['ios.flipper'] == 'true' then
35 | flipper_config = FlipperConfiguration.enabled(["Debug", "Release"])
36 | elsif podfile_properties['ios.flipper'] != 'false' then
37 | flipper_config = FlipperConfiguration.enabled(["Debug", "Release"], { 'Flipper' => podfile_properties['ios.flipper'] })
38 | end
39 | end
40 |
41 | target 'softphone' do
42 | use_expo_modules!
43 | config = use_native_modules!
44 |
45 | use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks']
46 | use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS']
47 |
48 | # Flags change depending on the env values.
49 | flags = get_default_flags()
50 |
51 | use_react_native!(
52 | :path => config[:reactNativePath],
53 | :hermes_enabled => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes',
54 | :fabric_enabled => flags[:fabric_enabled],
55 | # An absolute path to your application root.
56 | :app_path => "#{Pod::Config.instance.installation_root}/..",
57 | # Note that if you have use_frameworks! enabled, Flipper will not work if enabled
58 | :flipper_configuration => flipper_config
59 | )
60 |
61 | post_install do |installer|
62 | react_native_post_install(
63 | installer,
64 | config[:reactNativePath],
65 | # Set `mac_catalyst_enabled` to `true` in order to apply patches
66 | # necessary for Mac Catalyst builds
67 | :mac_catalyst_enabled => false
68 | )
69 | __apply_Xcode_12_5_M1_post_install_workaround(installer)
70 |
71 | # This is necessary for Xcode 14, because it signs resource bundles by default
72 | # when building for devices.
73 | installer.target_installation_results.pod_target_installation_results
74 | .each do |pod_name, target_installation_result|
75 | target_installation_result.resource_bundle_targets.each do |resource_bundle_target|
76 | resource_bundle_target.build_configurations.each do |config|
77 | config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
78 | end
79 | end
80 | end
81 | end
82 |
83 | post_integrate do |installer|
84 | begin
85 | expo_patch_react_imports!(installer)
86 | rescue => e
87 | Pod::UI.warn e
88 | end
89 | end
90 | end
91 |
--------------------------------------------------------------------------------
/packages/008/ios/Podfile.properties.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo.jsEngine": "hermes"
3 | }
4 |
--------------------------------------------------------------------------------
/packages/008/ios/softphone.xcodeproj/xcshareddata/xcschemes/softphone.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
53 |
55 |
61 |
62 |
63 |
64 |
70 |
72 |
78 |
79 |
80 |
81 |
83 |
84 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/packages/008/ios/softphone/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import
4 |
5 | @interface AppDelegate : EXAppDelegateWrapper
6 |
7 | @end
8 |
--------------------------------------------------------------------------------
/packages/008/ios/softphone/AppDelegate.mm:
--------------------------------------------------------------------------------
1 | #import "AppDelegate.h"
2 |
3 | #import
4 | #import
5 |
6 | @implementation AppDelegate
7 |
8 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
9 | {
10 | self.moduleName = @"main";
11 |
12 | // You can add your custom initial props in the dictionary below.
13 | // They will be passed down to the ViewController used by React Native.
14 | self.initialProps = @{};
15 |
16 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
17 | }
18 |
19 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
20 | {
21 | #if DEBUG
22 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
23 | #else
24 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
25 | #endif
26 | }
27 |
28 | /// This method controls whether the `concurrentRoot`feature of React18 is turned on or off.
29 | ///
30 | /// @see: https://reactjs.org/blog/2022/03/29/react-v18.html
31 | /// @note: This requires to be rendering on Fabric (i.e. on the New Architecture).
32 | /// @return: `true` if the `concurrentRoot` feature is enabled. Otherwise, it returns `false`.
33 | - (BOOL)concurrentRootEnabled
34 | {
35 | return true;
36 | }
37 |
38 | // Linking API
39 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options {
40 | return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options];
41 | }
42 |
43 | // Universal Links
44 | - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray> * _Nullable))restorationHandler {
45 | BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
46 | return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result;
47 | }
48 |
49 | // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
50 | - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
51 | {
52 | return [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
53 | }
54 |
55 | // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
56 | - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
57 | {
58 | return [super application:application didFailToRegisterForRemoteNotificationsWithError:error];
59 | }
60 |
61 | // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries
62 | - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
63 | {
64 | return [super application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
65 | }
66 |
67 | @end
68 |
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@1x.png
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@2x.png
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-20x20@3x.png
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@1x.png
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@2x.png
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-29x29@3x.png
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@1x.png
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@2x.png
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-40x40@3x.png
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-60x60@2x.png
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-60x60@3x.png
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-76x76@1x.png
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-76x76@2x.png
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/App-Icon-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "idiom": "iphone",
5 | "size": "20x20",
6 | "scale": "2x",
7 | "filename": "App-Icon-20x20@2x.png"
8 | },
9 | {
10 | "idiom": "iphone",
11 | "size": "20x20",
12 | "scale": "3x",
13 | "filename": "App-Icon-20x20@3x.png"
14 | },
15 | {
16 | "idiom": "iphone",
17 | "size": "29x29",
18 | "scale": "1x",
19 | "filename": "App-Icon-29x29@1x.png"
20 | },
21 | {
22 | "idiom": "iphone",
23 | "size": "29x29",
24 | "scale": "2x",
25 | "filename": "App-Icon-29x29@2x.png"
26 | },
27 | {
28 | "idiom": "iphone",
29 | "size": "29x29",
30 | "scale": "3x",
31 | "filename": "App-Icon-29x29@3x.png"
32 | },
33 | {
34 | "idiom": "iphone",
35 | "size": "40x40",
36 | "scale": "2x",
37 | "filename": "App-Icon-40x40@2x.png"
38 | },
39 | {
40 | "idiom": "iphone",
41 | "size": "40x40",
42 | "scale": "3x",
43 | "filename": "App-Icon-40x40@3x.png"
44 | },
45 | {
46 | "idiom": "iphone",
47 | "size": "60x60",
48 | "scale": "2x",
49 | "filename": "App-Icon-60x60@2x.png"
50 | },
51 | {
52 | "idiom": "iphone",
53 | "size": "60x60",
54 | "scale": "3x",
55 | "filename": "App-Icon-60x60@3x.png"
56 | },
57 | {
58 | "idiom": "ipad",
59 | "size": "20x20",
60 | "scale": "1x",
61 | "filename": "App-Icon-20x20@1x.png"
62 | },
63 | {
64 | "idiom": "ipad",
65 | "size": "20x20",
66 | "scale": "2x",
67 | "filename": "App-Icon-20x20@2x.png"
68 | },
69 | {
70 | "idiom": "ipad",
71 | "size": "29x29",
72 | "scale": "1x",
73 | "filename": "App-Icon-29x29@1x.png"
74 | },
75 | {
76 | "idiom": "ipad",
77 | "size": "29x29",
78 | "scale": "2x",
79 | "filename": "App-Icon-29x29@2x.png"
80 | },
81 | {
82 | "idiom": "ipad",
83 | "size": "40x40",
84 | "scale": "1x",
85 | "filename": "App-Icon-40x40@1x.png"
86 | },
87 | {
88 | "idiom": "ipad",
89 | "size": "40x40",
90 | "scale": "2x",
91 | "filename": "App-Icon-40x40@2x.png"
92 | },
93 | {
94 | "idiom": "ipad",
95 | "size": "76x76",
96 | "scale": "1x",
97 | "filename": "App-Icon-76x76@1x.png"
98 | },
99 | {
100 | "idiom": "ipad",
101 | "size": "76x76",
102 | "scale": "2x",
103 | "filename": "App-Icon-76x76@2x.png"
104 | },
105 | {
106 | "idiom": "ipad",
107 | "size": "83.5x83.5",
108 | "scale": "2x",
109 | "filename": "App-Icon-83.5x83.5@2x.png"
110 | },
111 | {
112 | "idiom": "ios-marketing",
113 | "size": "1024x1024",
114 | "scale": "1x",
115 | "filename": "ItunesArtwork@2x.png"
116 | }
117 | ],
118 | "info": {
119 | "version": 1,
120 | "author": "expo"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info": {
3 | "version": 1,
4 | "author": "expo"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/SplashScreen.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "idiom": "universal",
5 | "filename": "image.png",
6 | "scale": "1x"
7 | },
8 | {
9 | "idiom": "universal",
10 | "scale": "2x"
11 | },
12 | {
13 | "idiom": "universal",
14 | "scale": "3x"
15 | }
16 | ],
17 | "info": {
18 | "version": 1,
19 | "author": "expo"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/SplashScreen.imageset/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/SplashScreen.imageset/image.png
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/SplashScreenBackground.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images": [
3 | {
4 | "idiom": "universal",
5 | "filename": "image.png",
6 | "scale": "1x"
7 | },
8 | {
9 | "idiom": "universal",
10 | "scale": "2x"
11 | },
12 | {
13 | "idiom": "universal",
14 | "scale": "3x"
15 | }
16 | ],
17 | "info": {
18 | "version": 1,
19 | "author": "expo"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Images.xcassets/SplashScreenBackground.imageset/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/ios/softphone/Images.xcassets/SplashScreenBackground.imageset/image.png
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | softphone
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
19 | CFBundleShortVersionString
20 | 1.0.0
21 | CFBundleSignature
22 | ????
23 | CFBundleURLTypes
24 |
25 |
26 | CFBundleURLSchemes
27 |
28 | app.kunzite.sotphone
29 |
30 |
31 |
32 | CFBundleVersion
33 | 1
34 | LSRequiresIPhoneOS
35 |
36 | NSAppTransportSecurity
37 |
38 | NSAllowsArbitraryLoads
39 |
40 | NSExceptionDomains
41 |
42 | localhost
43 |
44 | NSExceptionAllowsInsecureHTTPLoads
45 |
46 |
47 |
48 |
49 | UILaunchStoryboardName
50 | SplashScreen
51 | UIRequiredDeviceCapabilities
52 |
53 | armv7
54 |
55 | UIRequiresFullScreen
56 |
57 | UIStatusBarStyle
58 | UIStatusBarStyleDefault
59 | UISupportedInterfaceOrientations
60 |
61 | UIInterfaceOrientationPortrait
62 | UIInterfaceOrientationPortraitUpsideDown
63 |
64 | UISupportedInterfaceOrientations~ipad
65 |
66 | UIInterfaceOrientationPortrait
67 | UIInterfaceOrientationPortraitUpsideDown
68 | UIInterfaceOrientationLandscapeLeft
69 | UIInterfaceOrientationLandscapeRight
70 |
71 | UIUserInterfaceStyle
72 | Light
73 | UIViewControllerBasedStatusBarAppearance
74 |
75 |
76 |
--------------------------------------------------------------------------------
/packages/008/ios/softphone/SplashScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/packages/008/ios/softphone/Supporting/Expo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | EXUpdatesCheckOnLaunch
6 | ALWAYS
7 | EXUpdatesEnabled
8 |
9 | EXUpdatesLaunchWaitMs
10 | 0
11 | EXUpdatesSDKVersion
12 | 48.0.0
13 | EXUpdatesURL
14 | https://exp.host/@anonymous/softphone
15 |
16 |
--------------------------------------------------------------------------------
/packages/008/ios/softphone/main.m:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char * argv[]) {
6 | @autoreleasepool {
7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
8 | }
9 | }
10 |
11 |
--------------------------------------------------------------------------------
/packages/008/ios/softphone/noop-file.swift:
--------------------------------------------------------------------------------
1 | //
2 | // @generated
3 | // A blank Swift file must be created for native modules with Swift files to work correctly.
4 | //
5 |
--------------------------------------------------------------------------------
/packages/008/ios/softphone/softphone.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | aps-environment
6 | development
7 |
8 |
--------------------------------------------------------------------------------
/packages/008/metro.config.js:
--------------------------------------------------------------------------------
1 | // Learn more https://docs.expo.io/guides/customizing-metro
2 | const { getDefaultConfig } = require('expo/metro-config');
3 |
4 | module.exports = getDefaultConfig(__dirname);
5 |
--------------------------------------------------------------------------------
/packages/008/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@kunzite/008",
3 | "description": "Open-source event-driven AI powered Softphone",
4 | "version": "2.2.0",
5 | "license": "AGPL-3.0-only",
6 | "private": true,
7 | "author": {
8 | "name": "Kunzite",
9 | "email": "support@kunzite.app",
10 | "url": "https://kunzite.app"
11 | },
12 | "repository": "https://github.com/kunzite-app/008",
13 | "bugs": "https://github.com/kunzite-app/008/issues",
14 | "homepage": "./",
15 | "scripts": {
16 | "start": "expo start --dev-client",
17 | "android": "expo run:android",
18 | "ios": "expo run:ios",
19 | "web": "expo start --web",
20 | "build-web": "expo export:web",
21 | "storybook-generate": "sb-rn-get-stories",
22 | "storybook-watch": "sb-rn-watcher",
23 | "storybook-web": "start-storybook -p 6006 -c .storybook-web",
24 | "build-storybook": "build-storybook -c .storybook-web",
25 | "lint": "eslint ./",
26 | "e2e": "yarn web & cypress run"
27 | },
28 | "dependencies": {
29 | "008Q": "file:../008Q",
30 | "@expo/webpack-config": "^18.0.1",
31 | "@microsoft/applicationinsights-react-js": "^17.0.1",
32 | "@microsoft/applicationinsights-web": "^3.0.3",
33 | "base-64": "^1.0.0",
34 | "crypto-js": "^4.1.1",
35 | "elasticlunr": "^0.9.5",
36 | "expo": "~48.0.18",
37 | "expo-av": "^13.4.1",
38 | "expo-splash-screen": "~0.18.2",
39 | "expo-status-bar": "~1.4.4",
40 | "level": "^8.0.0",
41 | "lodash": "^4.17.21",
42 | "moment": "^2.27.0",
43 | "p-queue": "^7.4.1",
44 | "p-retry": "^6.1.0",
45 | "react": "18.2.0",
46 | "react-dom": "18.2.0",
47 | "react-icons": "^3.10.0",
48 | "react-native": "0.71.8",
49 | "react-native-select-dropdown": "^3.4.0",
50 | "react-native-web": "^0.19.8",
51 | "sip.js": "^0.21.2",
52 | "vcf": "^2.1.1",
53 | "zustand": "^4.5.1"
54 | },
55 | "devDependencies": {
56 | "@babel/core": "^7.20.0",
57 | "@babel/plugin-proposal-export-namespace-from": "^7.18.9",
58 | "@react-native-async-storage/async-storage": "^1.19.3",
59 | "@react-native-community/datetimepicker": "^7.5.0",
60 | "@react-native-community/slider": "^4.4.3",
61 | "@storybook/addon-actions": "^6.5.16",
62 | "@storybook/addon-controls": "^6.5.16",
63 | "@storybook/addon-essentials": "^6.5",
64 | "@storybook/addon-ondevice-actions": "^6.5.6",
65 | "@storybook/addon-ondevice-controls": "^6.5.6",
66 | "@storybook/addon-react-native-web": "^0.0.21",
67 | "@storybook/builder-webpack5": "^6.5",
68 | "@storybook/manager-webpack5": "^6.5",
69 | "@storybook/react": "^6.5",
70 | "@storybook/react-native": "^6.5.6",
71 | "babel-loader": "^8.3.0",
72 | "babel-plugin-react-native-web": "^0.19.8",
73 | "cypress": "^13.6.0",
74 | "eslint": "^8.49.0",
75 | "eslint-config-universe": "^12.0.0",
76 | "eslint-plugin-cypress": "^2.15.1",
77 | "prettier": "^3.0.3",
78 | "prop-types": "^15.8.1",
79 | "react-native-safe-area-context": "^4.7.1"
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/packages/008/src/008QWorkerLLM.js:
--------------------------------------------------------------------------------
1 | import PQueue from 'p-queue';
2 |
3 | import { summarize } from '008Q';
4 |
5 | const QUEUE = new PQueue({ concurrency: 1 });
6 |
7 | self.addEventListener('message', async ({ data }) => {
8 | const { id, transcription } = data;
9 | console.log(`[008Q] Queuing job ${id}`);
10 |
11 | QUEUE.add(async () => {
12 | console.log('[008Q] Summarizing...');
13 | try {
14 | const summarization = await summarize({ transcription });
15 | self.postMessage({ id, summarization });
16 | } catch (err) {
17 | console.error('[008Q] Error summarizing', err);
18 | self.postMessage({ id, error: err.message });
19 | }
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/packages/008/src/008QWorkerTTS.js:
--------------------------------------------------------------------------------
1 | import PQueue from 'p-queue';
2 |
3 | import { transcript, tts } from '008Q';
4 |
5 | const QUEUE = new PQueue({ concurrency: 5 });
6 |
7 | self.addEventListener('message', async ({ data }) => {
8 | const { id, audio, wav } = data;
9 | console.log(`[008Q] Queuing job ${id}`);
10 |
11 | QUEUE.add(async () => {
12 | console.log('[008Q] Transcribing...');
13 | try {
14 | const transcription = await (audio
15 | ? tts({ audio })
16 | : transcript({ wav }));
17 | self.postMessage({ id, transcription });
18 | } catch (err) {
19 | console.error('[008Q] Error transcribing', err);
20 | self.postMessage({ id, error: err.message });
21 | }
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/packages/008/src/Sip.js:
--------------------------------------------------------------------------------
1 | import {
2 | UserAgent,
3 | Registerer,
4 | Inviter,
5 | Invitation,
6 | RegistererState,
7 | Session,
8 | SessionState,
9 | Web
10 | } from 'sip.js';
11 |
12 | Session.prototype.getStream = function () {
13 | try {
14 | const stream = new MediaStream();
15 | this.sessionDescriptionHandler?.peerConnection
16 | ?.getReceivers()
17 | .forEach(({ track }) => {
18 | if (track) stream.addTrack(track);
19 | });
20 |
21 | return stream;
22 | } catch (err) {
23 | console.error(err);
24 | }
25 | };
26 |
27 | Session.prototype.setMuted = function (muted) {
28 | this._muted = muted;
29 | this.sessionDescriptionHandler?.peerConnection
30 | ?.getLocalStreams()
31 | .forEach(stream => {
32 | stream.getAudioTracks().forEach(track => {
33 | track.enabled = !muted;
34 | });
35 | });
36 | };
37 |
38 | Session.prototype.setMutedVideo = function (muted) {
39 | this._mutedVideo = muted;
40 | this.sessionDescriptionHandler?.peerConnection
41 | ?.getLocalStreams()
42 | .forEach(stream => {
43 | stream.getVideoTracks().forEach(track => {
44 | track.enabled = !muted;
45 | });
46 | });
47 | };
48 |
49 | Session.prototype.hold = async function () {
50 | this.setHold(true);
51 | };
52 |
53 | Session.prototype.unhold = async function () {
54 | this.setHold(false);
55 | };
56 |
57 | Session.prototype.setHold = async function (hold) {
58 | this._hold = hold;
59 |
60 | if (this.state !== SessionState.Established) return;
61 | await this.invite({
62 | sessionDescriptionHandlerModifiers: hold ? [Web.holdModifier] : []
63 | });
64 | };
65 |
66 | Session.prototype.isVideo = function () {
67 | if (this.isInbound())
68 | return (
69 | this.request?.body?.includes?.('m=video') ||
70 | this.request?.body?.body?.includes?.('m=video')
71 | );
72 |
73 | return this.sessionDescriptionHandlerOptions.constraints?.video;
74 | };
75 |
76 | Session.prototype.isInbound = function () {
77 | return this instanceof Invitation;
78 | };
79 |
80 | Session.prototype.autoanswer = function () {
81 | return this.request?.getHeader('X-Autoanswer');
82 | };
83 |
84 | Session.prototype.dtmf = function (key) {
85 | this.info({
86 | requestOptions: {
87 | body: {
88 | contentDisposition: 'render',
89 | contentType: 'application/dtmf-relay',
90 | content: `Signal=${key}\r\nDuration=1000`
91 | }
92 | }
93 | });
94 | };
95 |
96 | export {
97 | UserAgent,
98 | Registerer,
99 | Inviter,
100 | Invitation,
101 | RegistererState,
102 | Session,
103 | SessionState
104 | };
105 |
--------------------------------------------------------------------------------
/packages/008/src/Sound.js:
--------------------------------------------------------------------------------
1 | import { Platform } from 'react-native';
2 | import { Audio as AVAudio } from 'expo-av';
3 |
4 | const setSinkId = async ({ audio, deviceId }) => {
5 | await audio?.stopAsync?.();
6 | audio.pause?.();
7 |
8 | const speakers = await getSpeakers();
9 | const speaker =
10 | speakers.find(dev => dev.deviceId === deviceId)?.deviceId || 'default';
11 | await audio.setSinkId(speaker);
12 | };
13 |
14 | export default class Sound {
15 | constructor({ media, loop = false } = {}) {
16 | const init = async () => {
17 | if (Platform.OS === 'web') {
18 | this.audio = new Audio(`./assets/sounds/${media}.mp3`);
19 | this.audio.loop = loop;
20 | } else {
21 | const { sound } = await AVAudio.Sound.createAsync(
22 | require(`../web/assets/sounds/${media}.mp3`),
23 | { isLooping: loop }
24 | );
25 | this.audio = sound;
26 | }
27 | };
28 |
29 | init();
30 | }
31 |
32 | async play() {
33 | await setSinkId({ audio: this.audio, deviceId: this.deviceId });
34 | this.audio?.playAsync?.();
35 | this.audio?.play?.();
36 | this.playing = true;
37 | }
38 |
39 | async stop(pause) {
40 | await this.audio?.stopAsync?.();
41 | this.audio.pause?.();
42 |
43 | if (!pause) {
44 | await this.audio?.setPositionAsync?.(0);
45 | this.audio.currentTime = 0;
46 | }
47 |
48 | this.playing = false;
49 | }
50 |
51 | async setDevice(deviceId) {
52 | this.deviceId = deviceId;
53 |
54 | if (this.playing) {
55 | this.stop(true);
56 | this.audio.play();
57 | }
58 | }
59 | }
60 |
61 | export const RING_TONE = new Sound({
62 | media: `ring`,
63 | loop: true
64 | });
65 |
66 | export const RING_BACK = new Sound({
67 | media: `ringback`,
68 | loop: true
69 | });
70 |
71 | export const REJECT_TONE = new Sound({
72 | media: `busy`,
73 | loop: true
74 | });
75 |
76 | export const play_tone = () => {
77 | REJECT_TONE.play();
78 | setTimeout(() => REJECT_TONE.stop(), 1000);
79 | };
80 |
81 | export const play_reject = () => {
82 | REJECT_TONE.play();
83 | setTimeout(() => REJECT_TONE.stop(), 3000);
84 | };
85 |
86 | export const getSpeakers = async () => {
87 | return getDevices({ kind: 'audiooutput' });
88 | };
89 |
90 | export const getMicrophones = async () => {
91 | return getDevices({ kind: 'audioinput' });
92 | };
93 |
94 | export const getDevices = async ({ kind }) => {
95 | try {
96 | const devices = await navigator.mediaDevices.enumerateDevices();
97 | return devices.filter(dev => dev.kind === kind);
98 | } catch (err) {
99 | console.log('Error getting audio devices', err);
100 | }
101 |
102 | return [];
103 | };
104 |
--------------------------------------------------------------------------------
/packages/008/src/components/Addons.jsx:
--------------------------------------------------------------------------------
1 | import { View } from 'react-native';
2 |
3 | export const AddonsIframe = ({ width, height, url }) => {
4 | return (
5 |
13 |
19 |
20 | );
21 | };
22 |
--------------------------------------------------------------------------------
/packages/008/src/components/Avatars.jsx:
--------------------------------------------------------------------------------
1 | import { Avatar } from './Basics';
2 |
3 | export const ContactAvatar = ({
4 | contact = {},
5 | size = 35,
6 | defaultImageUrl = 'avatar.png'
7 | }) => {
8 | const { name, avatar } = contact;
9 |
10 | return (
11 |
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/packages/008/src/components/Container.jsx:
--------------------------------------------------------------------------------
1 | import { View } from 'react-native';
2 | import { COLORS } from './Basics';
3 |
4 | export const Container = ({ children }) => (
5 |
6 | {children}
7 |
8 | );
9 |
--------------------------------------------------------------------------------
/packages/008/src/components/Container.web.jsx:
--------------------------------------------------------------------------------
1 | import { View } from 'react-native';
2 |
3 | import { COLORS } from './Basics';
4 | import { useStore } from '../store/Context';
5 |
6 | export const Container = ({ children }) => {
7 | const {
8 | size: { width, height }
9 | } = useStore();
10 |
11 | return (
12 |
20 |
21 | {children}
22 |
23 |
24 | );
25 | };
26 |
--------------------------------------------------------------------------------
/packages/008/src/components/Forms.jsx:
--------------------------------------------------------------------------------
1 | import { View } from 'react-native';
2 |
3 | import { TextField, Text } from './Basics';
4 |
5 | export const FormRow = ({ children, label, style = {} }) => (
6 |
7 | {label && (
8 |
9 | {label}
10 |
11 | )}
12 | {children}
13 |
14 | );
15 |
16 | export const InputRow = ({ label, ...rest }) => (
17 |
18 |
19 |
20 | );
21 |
--------------------------------------------------------------------------------
/packages/008/src/components/Icons.jsx:
--------------------------------------------------------------------------------
1 | import {
2 | FiUser as UserIcon,
3 | FiUsers as UsersIcon,
4 | FiClock as ClockIcon,
5 | FiX as XIcon,
6 | FiAnchor as AnchorIcon,
7 | FiGrid as GridIcon,
8 | FiCheck as CheckIcon,
9 | FiMicOff as MicOffIcon,
10 | FiPlay as PlayIcon,
11 | FiPause as PauseIcon,
12 | FiPhone as PhoneIcon,
13 | FiPhoneForwarded as PhoneForwardedIcon,
14 | FiPhoneOff as PhoneOffIcon,
15 | FiPhoneIncoming as PhoneIncomingIcon,
16 | FiPhoneOutgoing as PhoneOutgoingIcon,
17 | FiSave as SaveIcon,
18 | FiLogIn as LoginIcon,
19 | FiRotateCcw as ResetIcon,
20 | FiSettings as SettingsIcon,
21 | FiHeadphones as HeadphonesIcon,
22 | FiDelete as DeleteIcon,
23 | FiTrash as TrashIcon,
24 | FiShare2 as Share2Icon,
25 | FiPlus as PlusIcon,
26 | FiVideo as VideoIcon,
27 | FiChevronDown as ChevronIcon,
28 | FiEyeOff as EyeIcon,
29 | FiSearch as SearchIcon,
30 | FiChevronRight as ChevronRightIcon,
31 | FiChevronDown as ChevronDownIcon,
32 | } from 'react-icons/fi';
33 |
34 | export const Icon = ({ icon, size = 16 }) => {
35 | if (icon === 'unanchor')
36 | return
37 |
38 | if (icon === 'q')
39 | return
40 | }
41 |
42 | const UnanchorIcon = (props) => ;
43 | const QIcon = (props) => ;
44 |
45 | export {
46 | UserIcon,
47 | UsersIcon,
48 | ClockIcon,
49 | XIcon,
50 | AnchorIcon,
51 | GridIcon,
52 | CheckIcon,
53 | MicOffIcon,
54 | PlayIcon,
55 | PauseIcon,
56 | PhoneIcon,
57 | PhoneForwardedIcon,
58 | PhoneOffIcon,
59 | PhoneIncomingIcon,
60 | PhoneOutgoingIcon,
61 | SaveIcon,
62 | LoginIcon,
63 | ResetIcon,
64 | SettingsIcon,
65 | HeadphonesIcon,
66 | DeleteIcon,
67 | TrashIcon,
68 | Share2Icon,
69 | PlusIcon,
70 | VideoIcon,
71 | ChevronIcon,
72 | EyeIcon,
73 | SearchIcon,
74 | ChevronRightIcon,
75 | ChevronDownIcon,
76 |
77 | UnanchorIcon,
78 | QIcon,
79 | };
80 |
--------------------------------------------------------------------------------
/packages/008/src/components/Phone/Components.jsx:
--------------------------------------------------------------------------------
1 | import { TouchableOpacity, View } from 'react-native';
2 |
3 | import { Avatar, COLORS, Select, Status, Text } from '../Basics';
4 |
5 | export const UserAvatar = ({
6 | color,
7 | avatar,
8 | size = 50,
9 | defaultImageUrl = 'avatar.png'
10 | }) => {
11 | return (
12 |
13 |
14 |
15 |
16 | );
17 | };
18 |
19 | export const Header = ({
20 | numbers = [],
21 | number_out,
22 | onChange,
23 |
24 | name,
25 | avatar,
26 | status_color,
27 | onSettingsClick,
28 | }) => {
29 | const hasNumbers = numbers.length > 0;
30 | const avatarSize = 45;
31 | const numbersWidth = 200;
32 |
33 | const options = numbers.map(({ number }) => {
34 | return {
35 | label: number,
36 | value: number
37 | };
38 | });
39 |
40 | const { value } = options.find(({ value }) => value === number_out) || options[0] || {};
41 |
42 | const itemFontStyle = { fontSize: 16 };
43 | const backgroundColor = COLORS.backColor;
44 |
45 | return (
46 |
47 |
48 |
49 |
50 |
51 |
52 | {!hasNumbers &&
53 | {name}
54 | }
55 |
56 | {hasNumbers &&
57 |
58 |
78 | }
79 |
80 |
81 | )
82 | }
83 |
--------------------------------------------------------------------------------
/packages/008/src/components/Player.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef } from 'react';
2 | import { View } from 'react-native';
3 |
4 | export const Player = ({ stream, speaker, isvideo }) => {
5 | const ref = useRef(null);
6 |
7 | useEffect(() => {
8 | const elem = ref.current;
9 | elem.srcObject = stream;
10 | elem.setSinkId(speaker);
11 | }, [stream, speaker]);
12 |
13 | if (isvideo)
14 | return (
15 |
16 |
17 |
18 | )
19 |
20 | return
21 | };
22 |
--------------------------------------------------------------------------------
/packages/008/src/components/Timer.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Text } from './Basics';
3 |
4 | const format = (opts = {}) => {
5 | const { date_from = new Date().getTime(), date_to = new Date().getTime() } =
6 | opts;
7 |
8 | const delta = Math.abs(date_to - date_from) / 1000;
9 | const date = new Date(0);
10 | date.setSeconds(delta);
11 | return date.toISOString().substring(11, 19);
12 | };
13 |
14 | export default class Timer extends React.Component {
15 | constructor(props) {
16 | super(props);
17 | this.state = {
18 | currentTime: null
19 | };
20 | }
21 |
22 | componentDidMount() {
23 | this.initTimer();
24 | }
25 |
26 | componentWillUnmount() {
27 | this.clearTimer();
28 | }
29 |
30 | initTimer() {
31 | const date_from = new Date().getTime();
32 | this.counter = setInterval(() => {
33 | const currentTime = format({ date_from });
34 | this.setState({ currentTime });
35 | }, 1000);
36 | }
37 |
38 | clearTimer() {
39 | const currentTime = format();
40 | this.setState({ currentTime });
41 | clearInterval(this.counter);
42 | }
43 |
44 | render() {
45 | const { currentTime } = this.state;
46 | return {currentTime};
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/packages/008/src/screens/PhoneScreen.jsx:
--------------------------------------------------------------------------------
1 | import { View } from 'react-native';
2 |
3 | import Phone from '../components/Phone';
4 |
5 | export const PhoneScreen = () => ;
6 |
--------------------------------------------------------------------------------
/packages/008/src/screens/Screen.jsx:
--------------------------------------------------------------------------------
1 | import { View } from 'react-native';
2 |
3 | import { ButtonIcon, COLORS } from '../components/Basics';
4 |
5 | export const Screen = ({
6 | children,
7 | color = COLORS.app,
8 | bodyStyle,
9 | onClose,
10 | closeable,
11 | style,
12 | visible,
13 | ...rest
14 | }) => {
15 | if (!visible) return
16 |
17 | return (
18 |
19 |
20 | {closeable && (
21 |
22 | onClose?.()} icon='x' />
23 |
24 | )}
25 |
26 |
27 | {children}
28 |
29 |
30 | );
31 | }
32 |
--------------------------------------------------------------------------------
/packages/008/src/screens/index.js:
--------------------------------------------------------------------------------
1 | export { SettingsScreen } from './SettingsScreen';
2 | export { PhoneScreen } from './PhoneScreen';
3 |
--------------------------------------------------------------------------------
/packages/008/src/store/Cdr.js:
--------------------------------------------------------------------------------
1 | export class Cdr {
2 | constructor({ session }) {
3 | const id =
4 | session.request.getHeader('X-Call-ID') ||
5 | session.request.getHeader('Call-ID');
6 | const {
7 | displayName,
8 | uri: { user, headers }
9 | } = session.remoteIdentity;
10 |
11 | const direction = session.isInbound() ? 'inbound' : 'outbound';
12 |
13 | this.id = id;
14 | this.direction = direction;
15 | this.from = session.isInbound()
16 | ? user
17 | : session.request.getHeader('P-Asserted-Identity');
18 | this.to = session.isInbound() ? displayName : user;
19 | this.headers = headers;
20 |
21 | this.video = session.isVideo();
22 |
23 | this.status = 'ringing';
24 | this.date = new Date();
25 | }
26 |
27 | accepted() {
28 | this.status = 'answered';
29 |
30 | this.wait = this.secondsElapsed();
31 | }
32 |
33 | terminated() {
34 | this.status = this.status === 'answered' ? this.status : 'missed';
35 |
36 | this.wait = this.wait || this.secondsElapsed();
37 | this.total = this.secondsElapsed();
38 | this.duration = this.total - this.wait;
39 | }
40 |
41 | secondsElapsed() {
42 | return Math.ceil((new Date() - this.date) / 1000);
43 | }
44 |
45 | setContact(contact) {
46 | this.contact = contact;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/packages/008/src/store/Contacts.js:
--------------------------------------------------------------------------------
1 | import vCard from 'vcf';
2 |
3 | import { cleanPhoneNumber } from '../utils';
4 |
5 | const elasticlunr = require('elasticlunr');
6 | const { Level } = require('level');
7 |
8 | elasticlunr.clearStopWords();
9 |
10 | let CONTACTS_VCF_IDS = [];
11 | let HASH = {};
12 | let IDX;
13 |
14 | const NGRAMLEN = 4;
15 |
16 | const initIndex = () => {
17 | CONTACTS_VCF_IDS = [];
18 | HASH = {};
19 |
20 | IDX = elasticlunr(function () {
21 | this.setRef('id');
22 | this.addField('name');
23 | this.addField('phones');
24 | this.saveDocument(false);
25 | });
26 | };
27 |
28 | const index = ({ contacts, size = 100 } = {}) => {
29 | if (!contacts?.length) {
30 | document?.dispatchEvent(new Event('indexing:end'));
31 | return;
32 | }
33 |
34 | const long_tail_tokens = (str, ngramlen = NGRAMLEN, number) => {
35 | if (!str) return [];
36 |
37 | const tokens = (number ? str.replace(/\s/g, '') : str).split(' ');
38 | let ngrams = [];
39 |
40 | if (ngramlen > 0) {
41 | for (let j = 0; j < tokens.length; j++) {
42 | const token = tokens[j];
43 | for (let i = 0; i < token.length; i++) {
44 | ngrams = ngrams.concat(
45 | token.split('').map((_, idx) => token.substr(i, idx + 1))
46 | );
47 | }
48 | }
49 | }
50 |
51 | return tokens.concat(ngrams.filter(ngram => ngram.length >= ngramlen));
52 | };
53 |
54 | let indexed = 0;
55 | const max = Math.ceil(contacts.length / size);
56 | for (let i = 0; i < max; i++) {
57 | document?.dispatchEvent(new Event('indexing'));
58 |
59 | const from = i * size;
60 | const to = (i + 1) * size;
61 | const chunk = contacts.slice(from, to);
62 |
63 | // eslint-disable-next-line no-loop-func
64 | requestIdleCallback(async () => {
65 | try {
66 | chunk.forEach(async user => {
67 | if (user.id.startsWith('cvf-')) CONTACTS_VCF_IDS.push(user.id);
68 |
69 | HASH[user.id] = user;
70 | IDX.addDoc({
71 | id: user.id,
72 | name: long_tail_tokens(user.name, NGRAMLEN),
73 | phones: [].concat.apply(
74 | [],
75 | user.phones.map(number =>
76 | long_tail_tokens(cleanPhoneNumber(number), NGRAMLEN, true)
77 | )
78 | )
79 | });
80 | });
81 | } finally {
82 | indexed += chunk.length;
83 |
84 | if (indexed === contacts.length) {
85 | console.log('Indexing ended');
86 | document?.dispatchEvent(new Event('indexing:end'));
87 | }
88 | }
89 | });
90 | }
91 | };
92 |
93 | export const fromVCF = ({ vcf }) => {
94 | const cards = vCard.parse(vcf.replace(/\r?\n/g, '\r\n'));
95 |
96 | const contacts = cards
97 | .map((card, idx) => {
98 | try {
99 | const name = card.get('fn').valueOf();
100 | let phones = card.get('tel')?.valueOf();
101 | if (Array.isArray(phones)) {
102 | phones = phones.map(phone => phone.valueOf());
103 | } else if (phones) {
104 | phones = [phones.valueOf()];
105 | }
106 |
107 | const avatar = card.get('photo')?.valueOf();
108 | return { name, avatar, phones, id: `cvf-${idx}` };
109 | } catch (err) {
110 | console.error(err);
111 | }
112 | })
113 | .filter(contact => contact !== undefined);
114 |
115 | return contacts;
116 | };
117 |
118 | export default class Contacts {
119 | constructor() {
120 | initIndex();
121 | this.fs = new Level('KZCS', { valueEncoding: 'json' });
122 | }
123 |
124 | async load(id = 'contacts') {
125 | try {
126 | const { hash = {}, index } = (await this.fs.get(id)) || {};
127 | HASH = hash;
128 |
129 | if (index) {
130 | IDX = elasticlunr.Index.load(index);
131 | document?.dispatchEvent(new Event('indexing:end'));
132 | }
133 | } catch (err) {
134 | index({ users: [] });
135 | }
136 | }
137 |
138 | async save(id = 'contacts') {
139 | await this.fs.put(id, { hash: HASH, index: IDX.toJSON() });
140 | }
141 |
142 | async index({ vcf, contacts = [] }) {
143 | if (vcf) {
144 | CONTACTS_VCF_IDS.forEach(id => {
145 | IDX.removeDoc(HASH[id]);
146 | delete HASH[id];
147 | });
148 | CONTACTS_VCF_IDS = [];
149 |
150 | const contacts = fromVCF({ vcf })
151 | .filter(contact => contact?.phones?.length)
152 | .map(contact => ({ ...contact, vcf: true }));
153 |
154 | index({ contacts });
155 | }
156 |
157 | if (contacts.length) {
158 | index({ contacts });
159 | }
160 | }
161 |
162 | query({ query, max } = {}) {
163 | const result =
164 | !query || query.length < NGRAMLEN
165 | ? Object.values(HASH)
166 | : IDX.search(query, {}).map(({ score, ref }) => ({
167 | score,
168 | ...HASH[ref]
169 | }));
170 |
171 | const hits = result
172 | .slice(0, max || result.length)
173 | .filter(item => item.id !== undefined)
174 | .sort((a, b) => {
175 | if (a.score === b.score) return a.vcf ? 1 : -1;
176 |
177 | return b.score - a.score;
178 | });
179 |
180 | return { hits, total: result.length };
181 | }
182 |
183 | contact_by_phone({ phone = '' }) {
184 | const query = cleanPhoneNumber(phone).substr(-9);
185 | const { hits } = this.query({ query });
186 | const [contact] = hits;
187 |
188 | return contact;
189 | }
190 |
191 | clear() {
192 | initIndex();
193 | this.fs.clear();
194 | }
195 | }
196 |
--------------------------------------------------------------------------------
/packages/008/src/store/Electron.js:
--------------------------------------------------------------------------------
1 | import { useStore } from './Context';
2 |
3 | const emit = (ev, data) =>
4 | document?.dispatchEvent(new CustomEvent(ev, { detail: data }));
5 |
6 | let ipcRenderer;
7 | export const quit = () => ipcRenderer?.send('quit');
8 | export const show = () => ipcRenderer?.send('show');
9 | export const anchor = () => ipcRenderer?.send('anchor');
10 | export const unanchor = () => ipcRenderer?.send('unanchor');
11 | export const resize = size => ipcRenderer?.send('resize', { ...size });
12 |
13 | export const init = () => {
14 | try {
15 | ipcRenderer = window.require('electron').ipcRenderer;
16 |
17 | useStore.setState({ electron: true });
18 | useStore.subscribe(state => state.size, resize);
19 | useStore.subscribe(
20 | state => state.doquit,
21 | doquit => doquit && quit()
22 | );
23 | useStore.subscribe(
24 | state => state.anchored,
25 | anchored => (anchored ? anchor() : unanchor())
26 | );
27 |
28 | ipcRenderer?.on('anchored', (_, { anchored }) =>
29 | useStore.setState({ anchored })
30 | );
31 |
32 | ipcRenderer?.on('deep-link', (_, { url: number }) =>
33 | emit('click2call', { number })
34 | );
35 |
36 | document?.addEventListener('notification:click', show);
37 |
38 | resize(useStore.getState().size);
39 | } catch (err) {
40 | console.log('Electron not found?', err);
41 | }
42 | };
43 |
44 | export const openLink = ({ url }) => {
45 | ipcRenderer?.send('open', { url });
46 | window?.open(url, '_blank');
47 | };
48 |
--------------------------------------------------------------------------------
/packages/008/src/store/Events.js:
--------------------------------------------------------------------------------
1 | import { Platform } from 'react-native';
2 |
3 | import PQueue from 'p-queue';
4 | import _ from 'lodash';
5 |
6 | import { processAudio } from '008Q';
7 |
8 | import { useStore } from './Context';
9 | import { blobToDataURL, request } from '../utils';
10 |
11 | const QUEUE = new PQueue({ concurrency: 5 });
12 |
13 | let qLLMEnabled = false;
14 | const qworkerLLM = new Worker(new URL('../008QWorkerLLM.js', import.meta.url), {
15 | type: 'module'
16 | });
17 | qworkerLLM.addEventListener('message', ({ data }) =>
18 | emit({ type: 'phone:summarization', data })
19 | );
20 |
21 | let qTTSEnabled = false;
22 | const qworkerTTS = new Worker(new URL('../008QWorkerTTS.js', import.meta.url), {
23 | type: 'module'
24 | });
25 | qworkerTTS.addEventListener('message', ({ data }) => {
26 | emit({ type: 'phone:transcript', data });
27 |
28 | if (qLLMEnabled) qworkerLLM.postMessage(data);
29 | });
30 |
31 | export const emit = async ({ type, data: payload }) => {
32 | if (type === 'phone:audio' && qTTSEnabled) {
33 | qworkerTTS.postMessage(payload);
34 | return;
35 | }
36 |
37 | const store = useStore.getState();
38 | const context = _.pick(store, [
39 | 'nickname',
40 | 'sipUri',
41 | 'sipUser',
42 | 'language',
43 | 'device',
44 | 'size',
45 | 'status'
46 | ]);
47 |
48 | const data = { ...payload, context };
49 |
50 | console.log('008Q: Emitting event', type, data);
51 | const { blob, ...valid } = data;
52 | store.eventAdd({ type, data: valid });
53 |
54 | for (const idx in store.webhooks) {
55 | const { endpoint } = store.webhooks[idx];
56 | QUEUE.add(() => request({ endpoint, body: data, retries: 5, qdelay: 30 }));
57 | }
58 |
59 | document?.dispatchEvent?.(new CustomEvent(type, { detail: data }));
60 | window?.parent?.postMessage?.({ type, data }, '*');
61 | };
62 |
63 | export const init = () => {
64 | const store = useStore.getState();
65 | qTTSEnabled = store.qTts;
66 | qLLMEnabled = store.qSummarization;
67 |
68 | useStore.subscribe(
69 | state => state.status,
70 | status => emit({ type: 'status:change', data: { status } })
71 | );
72 |
73 | useStore.subscribe(
74 | state => state.qTts,
75 | value => (qTTSEnabled = value)
76 | );
77 |
78 | useStore.subscribe(
79 | state => state.qSummarization,
80 | value => {
81 | qLLMEnabled = value;
82 | }
83 | );
84 |
85 | if (Platform.OS === 'web') {
86 | const events = [
87 | 'contacts',
88 | 'settings',
89 | 'click2call',
90 | 'call',
91 | 'hangup',
92 | 'Q008:audio',
93 | 'Q008:login'
94 | ];
95 |
96 | const eventHandler = async ev => {
97 | const { type, detail, data } = ev.data || ev;
98 |
99 | if (!events.includes(type)) return;
100 |
101 | const payload = detail || data;
102 |
103 | if (type === 'contacts') store.contacts().index({ contacts: payload });
104 |
105 | if (type === 'settings') store.setSettings(payload);
106 |
107 | if (type === 'Q008:audio') {
108 | const { webhooks = [] } = useStore.getState();
109 | if (!webhooks.length) return;
110 |
111 | const { id, path } = payload;
112 | const { wav } = await processAudio({ input: path });
113 |
114 | const type = 'audio/webm';
115 | const blob = await blobToDataURL(new Blob([wav], { type }));
116 | emit({
117 | type: 'phone:recording',
118 | data: { id, audio: { blob } }
119 | });
120 |
121 | if (qTTSEnabled) qworkerTTS.postMessage({ id, wav });
122 | }
123 |
124 | if (type === 'Q008:login') {
125 | await store.login(payload);
126 | }
127 | };
128 |
129 | window?.addEventListener('message', eventHandler);
130 | events.forEach(event => document?.addEventListener(event, eventHandler));
131 | }
132 | };
133 |
--------------------------------------------------------------------------------
/packages/008/src/utils.js:
--------------------------------------------------------------------------------
1 | import pRetry from 'p-retry';
2 |
3 | export const sleep = time => {
4 | return new Promise(resolve => {
5 | setTimeout(resolve, time * 1000);
6 | });
7 | };
8 |
9 | export const readFileAsText = file => {
10 | return new Promise((resolve, reject) => {
11 | const reader = new FileReader();
12 | reader.onload = e => resolve(e.target.result);
13 | reader.onerror = e => reject(e.target.error);
14 | reader.readAsText(file);
15 | });
16 | };
17 |
18 | export const blobToDataURL = blob => {
19 | return new Promise((resolve, reject) => {
20 | const reader = new FileReader();
21 | reader.onloadend = () => resolve(reader.result);
22 | reader.onerror = reject;
23 | reader.readAsDataURL(blob);
24 | });
25 | };
26 |
27 | export const cleanPhoneNumber = number => number.replace(/[ ()]/g, '');
28 |
29 | export const isMobile = () => {
30 | return (
31 | window?.ReactNativeWebView !== undefined ||
32 | !window ||
33 | /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
34 | navigator?.userAgent
35 | )
36 | );
37 | };
38 |
39 | export const genId = () => {
40 | return new Date().getTime() + '.' + Math.random().toString().slice(2, 8);
41 | };
42 |
43 | export const request = async ({
44 | endpoint,
45 | body,
46 | method = 'POST',
47 | retries = 5,
48 | qdelay = 30
49 | }) => {
50 | const run = async attempt => {
51 | try {
52 | const response = await fetch(endpoint, {
53 | headers: {
54 | 'Content-Type': 'application/json'
55 | },
56 | method,
57 | body: JSON.stringify(body)
58 | });
59 |
60 | if (!response.ok) throw new Error(`HTTP status: ${response.status}`);
61 |
62 | return await response.json();
63 | } catch (err) {
64 | const delay = qdelay * (attempt - 1);
65 | if (delay) await sleep(delay);
66 | throw err;
67 | }
68 | };
69 |
70 | return await pRetry(run, { retries });
71 | };
72 |
--------------------------------------------------------------------------------
/packages/008/stories/App.stories.js:
--------------------------------------------------------------------------------
1 | import App from '../App';
2 |
3 | export default {
4 | title: 'Screens/Application',
5 | component: App,
6 | parameters: {
7 | layout: 'fullscreen'
8 | }
9 | };
10 |
11 | export const Default = () => ;
12 |
13 |
--------------------------------------------------------------------------------
/packages/008/stories/CancelAccept.stories.js:
--------------------------------------------------------------------------------
1 | import { CancelAccept } from '../src/components/Basics';
2 |
3 | export default {
4 | component: CancelAccept,
5 | title: 'Components/CancelAccept'
6 | };
7 |
8 | export const Default = args => ;
9 | Default.args = {
10 | onCancel: () => console.log('Canceled'),
11 | onAccept: () => console.log('Accepted')
12 | };
13 |
14 | export const CancelOnly = args => ;
15 | CancelOnly.args = {
16 | onCancel: () => console.log('Canceled')
17 | };
18 |
19 | export const AcceptOnly = args => ;
20 | AcceptOnly.args = {
21 | onAccept: () => console.log('Accepted')
22 | };
23 |
--------------------------------------------------------------------------------
/packages/008/stories/DialGrid.stories.js:
--------------------------------------------------------------------------------
1 | import { DialGrid } from '../src/components/Dialer';
2 |
3 | export default {
4 | component: DialGrid,
5 | title: 'Components/DialGrid'
6 | };
7 |
8 | export const Default = args => ;
9 | Default.args = {};
10 |
--------------------------------------------------------------------------------
/packages/008/stories/DialPad.stories.js:
--------------------------------------------------------------------------------
1 | import { DialPad } from '../src/components/Dialer';
2 |
3 | export default {
4 | component: DialPad,
5 | title: 'Components/DialPad'
6 | };
7 |
8 | export const Default = args => ;
9 | Default.args = {
10 | onClick: number => console.log(number)
11 | };
12 |
13 | export const WithValues = args => ;
14 | WithValues.args = {
15 | number: '+34 666 777 888',
16 | onClick: number => console.log(number)
17 | };
18 |
--------------------------------------------------------------------------------
/packages/008/stories/Dialer.stories.js:
--------------------------------------------------------------------------------
1 | import { Dialer } from '../src/components/Dialer';
2 |
3 | export default {
4 | title: 'Components/Dialer',
5 | component: Dialer,
6 | parameters: {
7 | layout: 'fullscreen'
8 | }
9 | };
10 |
11 | export const Default = args => ;
12 | Default.args = {
13 | number: '666666666',
14 | onDialClick: number => console.log(number),
15 |
16 | onContactsFilterChange: filter => console.log(filter),
17 | onContactClick: phones => console.log(phones),
18 | contacts: {
19 | hits: [
20 | { id: 'id1', name: '', phones: ['+34666555444'] },
21 | {
22 | id: 'id2',
23 | name: 'Jennifer Doe',
24 | phones: ['+34666555444', '+34666777888']
25 | }
26 | ],
27 | total: 2
28 | },
29 |
30 | onCdrClick: number => console.log(number),
31 | cdrs: [
32 | {
33 | id: '1',
34 | date: '2023-07-27T18:27:00.708Z',
35 | from: '+34666999999',
36 | to: '+34666555444',
37 | direction: 'inbound',
38 | status: 'answered'
39 | },
40 | {
41 | id: '2',
42 | date: '2023-07-27T18:26:00.708Z',
43 | from: '+34666999999',
44 | to: '+34666555444',
45 | direction: 'inbound',
46 | status: 'missed'
47 | },
48 | {
49 | id: '3',
50 | date: '2023-07-27T18:25:00.708Z',
51 | from: '+34666555444',
52 | to: '+34666999999',
53 | direction: 'outbound',
54 | status: 'missed'
55 | },
56 | {
57 | id: '4',
58 | date: '2023-07-27T18:23:39.708Z',
59 | from: '+34666555444',
60 | to: '+34666777888',
61 | direction: 'outbound',
62 | status: 'answered'
63 | }
64 | ]
65 | };
66 |
--------------------------------------------------------------------------------
/packages/008/stories/Screen.stories.js:
--------------------------------------------------------------------------------
1 | import { useState } from 'react';
2 | import { Button, View } from 'react-native';
3 |
4 | import { Screen } from '../src/screens/Screen';
5 | import { Text } from '../src/components/Basics';
6 |
7 | export default {
8 | title: 'Screens/Screen',
9 | component: Screen,
10 | parameters: {
11 | layout: 'fullscreen'
12 | }
13 | };
14 |
15 | export const Default = () => {
16 | const [isVisible, setIsVisible] = useState(false);
17 |
18 | return (
19 |
26 |
29 | );
30 | };
31 |
32 | export const Closeable = () => {
33 | const [isVisible, setIsVisible] = useState(false);
34 |
35 | return (
36 |
43 |
50 | );
51 | };
52 |
53 | export const OverlayTest = () => {
54 | const [isVisible, setIsVisible] = useState(true);
55 |
56 | return (
57 |
63 |
64 | Im screen one. You found me!
65 |
66 |
67 | setIsVisible(false)}
71 | >
72 | Close me
73 |
74 |
75 | );
76 | };
77 |
--------------------------------------------------------------------------------
/packages/008/stories/SessionScreen.stories.js:
--------------------------------------------------------------------------------
1 | import { View } from 'react-native';
2 | import { SessionScreen } from '../src/screens/SessionScreen';
3 | import { SessionState } from '../src/Sip';
4 |
5 | export default {
6 | title: 'Screens/SessionScreen',
7 | component: SessionScreen,
8 | parameters: {
9 | layout: 'fullscreen'
10 | }
11 | };
12 |
13 | const contact = {
14 | id: 'id1',
15 | name: 'John Doe',
16 | phones: ['+34666555444'],
17 | avatar: 'https://avatars.githubusercontent.com/u/414967'
18 | };
19 | const mockSession = {
20 | unhold: () => console.log('calling unhold'),
21 | hold: () => console.log('calling hold'),
22 | mute: () => console.log('calling mute'),
23 | dtmf: () => console.log('calling dftm'),
24 | setMuted: () => console.log('muting...'),
25 | setMutedVideo: () => console.log('muting video...'),
26 | on: () => console.log('calling event'),
27 | isVideo: () => false,
28 |
29 | isInbound: () => true,
30 | cdr: {
31 | contact,
32 | from: 'agent1',
33 | to: 'agent2',
34 | direction: 'inbound'
35 | }
36 | };
37 |
38 | const sharedArgs = {
39 | visible: true,
40 | onAccept: () => console.log('accepting'),
41 | onCancel: () => console.log('canceling'),
42 | onContactClick: () => console.log('contact click')
43 | };
44 |
45 | const Template = props => (
46 |
47 |
48 |
49 | );
50 |
51 | export const Inbound = args => ;
52 | Inbound.args = {
53 | ...sharedArgs,
54 | session: {
55 | ...mockSession,
56 | isInbound: () => true,
57 | cdr: {
58 | contact,
59 | from: 'agent1',
60 | to: 'agent2',
61 | direction: 'inbound'
62 | }
63 | }
64 | };
65 |
66 | export const InboundAnswered = args => ;
67 | InboundAnswered.args = {
68 | ...sharedArgs,
69 | session: {
70 | ...mockSession,
71 | status: SessionState.Established,
72 | isInbound: () => true,
73 | cdr: {
74 | contact,
75 | from: 'agent1',
76 | to: 'agent2',
77 | direction: 'inbound'
78 | }
79 | }
80 | };
81 |
82 | export const Outbound = args => ;
83 | Outbound.args = {
84 | ...sharedArgs,
85 | session: {
86 | ...mockSession,
87 | status: SessionState.Establishing,
88 | isInbound: () => false,
89 | cdr: {
90 | contact,
91 | from: 'agent1',
92 | to: 'agent2'
93 | }
94 | }
95 | };
96 |
97 | export const OutboundAnswered = args => ;
98 | OutboundAnswered.args = {
99 | ...sharedArgs,
100 | session: {
101 | ...mockSession,
102 | status: SessionState.Established,
103 | isInbound: () => true,
104 | cdr: {
105 | contact,
106 | from: 'agent1',
107 | to: 'agent2'
108 | }
109 | }
110 | };
111 |
112 | export const OutboundVideoAnswered = args => ;
113 | OutboundVideoAnswered.args = {
114 | ...sharedArgs,
115 | session: {
116 | ...mockSession,
117 | status: SessionState.Established,
118 | isInbound: () => true,
119 | isVideo: () => true,
120 | cdr: {
121 | contact,
122 | from: 'agent1',
123 | to: 'agent2'
124 | }
125 | }
126 | };
127 |
128 | export const AttendedTransfer = args => ;
129 | AttendedTransfer.args = {
130 | ...sharedArgs,
131 | isTransfer: true,
132 | session: {
133 | ...mockSession,
134 | status: SessionState.Established,
135 | isInbound: () => false,
136 | cdr: {
137 | contact,
138 | from: 'agent1',
139 | to: 'agent2'
140 | }
141 | }
142 | };
143 |
--------------------------------------------------------------------------------
/packages/008/stories/SettingsScreen.stories.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react';
2 |
3 | import {
4 | SettingsScreen,
5 | SettingsForm,
6 | ConnectionForm,
7 | DevicesForm
8 | } from '../src/screens/SettingsScreen';
9 | import { useStore } from '../src/store/Context';
10 | import { View } from 'react-native';
11 |
12 | export default {
13 | title: 'Screens/SettingsScreen',
14 | component: SettingsScreen,
15 | parameters: {
16 | layout: 'fullscreen'
17 | }
18 | };
19 |
20 | const settingsMock = {
21 | statuses: [
22 | { value: 'online', text: 'Online', color: '#057e74' },
23 | { value: 'offline', text: 'Offline', color: '#A9A9A9' }
24 | ],
25 | devices: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16].map(i => ({
26 | deviceId: `${i}`,
27 | label: `Audio${i}`
28 | })),
29 | status: 'offline',
30 | deviceId: '2',
31 | language: 'es'
32 | };
33 |
34 | const connectionMock = {
35 | settingsUri: 'http://test.com/settings',
36 | sipUri: 'http://test.com/sip',
37 | sipPassword: '1234',
38 | wsUri: 'http://test.com/ws'
39 | };
40 |
41 | export const Default = args => {
42 | const store = useStore();
43 |
44 | useEffect(() => {
45 | store.setSettings({ ...settingsMock, ...connectionMock });
46 | store.toggleShowSettings();
47 | }, []);
48 |
49 | return (
50 |
51 |
52 |
53 | );
54 | };
55 |
56 | Default.args = {
57 | onChange: values => console.log(values)
58 | };
59 |
60 | export const Settingsform = args => ;
61 | Settingsform.args = {
62 | ...settingsMock,
63 | onChange: values => console.log(values)
64 | };
65 |
66 | export const Connectionform = args => ;
67 | Connectionform.args = {
68 | ...connectionMock,
69 | onChange: values => console.log(values)
70 | };
71 |
72 | export const Devicesform = args => (
73 |
74 |
75 |
76 | );
77 | Devicesform.args = {
78 | ...settingsMock,
79 | onChange: values => console.log(values)
80 | };
81 |
--------------------------------------------------------------------------------
/packages/008/web/assets/fonts/Roboto-Flex.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/assets/fonts/Roboto-Flex.ttf
--------------------------------------------------------------------------------
/packages/008/web/assets/icons/008.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
21 |
--------------------------------------------------------------------------------
/packages/008/web/assets/icons/unanchor.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
22 |
--------------------------------------------------------------------------------
/packages/008/web/assets/sounds/busy.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/assets/sounds/busy.mp3
--------------------------------------------------------------------------------
/packages/008/web/assets/sounds/dtmf/dtmf-0.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/assets/sounds/dtmf/dtmf-0.mp3
--------------------------------------------------------------------------------
/packages/008/web/assets/sounds/dtmf/dtmf-1.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/assets/sounds/dtmf/dtmf-1.mp3
--------------------------------------------------------------------------------
/packages/008/web/assets/sounds/dtmf/dtmf-2.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/assets/sounds/dtmf/dtmf-2.mp3
--------------------------------------------------------------------------------
/packages/008/web/assets/sounds/dtmf/dtmf-3.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/assets/sounds/dtmf/dtmf-3.mp3
--------------------------------------------------------------------------------
/packages/008/web/assets/sounds/dtmf/dtmf-4.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/assets/sounds/dtmf/dtmf-4.mp3
--------------------------------------------------------------------------------
/packages/008/web/assets/sounds/dtmf/dtmf-5.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/assets/sounds/dtmf/dtmf-5.mp3
--------------------------------------------------------------------------------
/packages/008/web/assets/sounds/dtmf/dtmf-6.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/assets/sounds/dtmf/dtmf-6.mp3
--------------------------------------------------------------------------------
/packages/008/web/assets/sounds/dtmf/dtmf-7.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/assets/sounds/dtmf/dtmf-7.mp3
--------------------------------------------------------------------------------
/packages/008/web/assets/sounds/dtmf/dtmf-8.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/assets/sounds/dtmf/dtmf-8.mp3
--------------------------------------------------------------------------------
/packages/008/web/assets/sounds/dtmf/dtmf-9.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/assets/sounds/dtmf/dtmf-9.mp3
--------------------------------------------------------------------------------
/packages/008/web/assets/sounds/dtmf/dtmf-hash.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/assets/sounds/dtmf/dtmf-hash.mp3
--------------------------------------------------------------------------------
/packages/008/web/assets/sounds/dtmf/dtmf-star.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/assets/sounds/dtmf/dtmf-star.mp3
--------------------------------------------------------------------------------
/packages/008/web/assets/sounds/ring.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/assets/sounds/ring.mp3
--------------------------------------------------------------------------------
/packages/008/web/assets/sounds/ringback.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/assets/sounds/ringback.mp3
--------------------------------------------------------------------------------
/packages/008/web/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/avatar.png
--------------------------------------------------------------------------------
/packages/008/web/cfgDemo008.json:
--------------------------------------------------------------------------------
1 | {
2 | "sipUri": "sip:demo@demo.008agent.ai",
3 | "sipPassword": "008Demo",
4 | "wsUri": "wss://demo.008agent.ai:8089/ws",
5 | "numbers": [
6 | {
7 | "number": "+1",
8 | "tags": ["Main"]
9 | }
10 | ],
11 | "statuses": [
12 | { "value": "online", "text": "Online", "color": "#057e74" },
13 | { "value": "offline", "text": "Offline", "color": "#A9A9A9" }
14 | ],
15 | "avatar": "https://avatars.githubusercontent.com/u/59776461",
16 | "nickname": "Demo",
17 | "qTts": true,
18 | "qSummarization": true
19 | }
20 |
--------------------------------------------------------------------------------
/packages/008/web/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/favicon.png
--------------------------------------------------------------------------------
/packages/008/web/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008/web/icon.png
--------------------------------------------------------------------------------
/packages/008/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
14 | %WEB_TITLE%
15 |
69 |
70 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/packages/008/webpack.config.js:
--------------------------------------------------------------------------------
1 | const createExpoWebpackConfigAsync = require('@expo/webpack-config');
2 | const isElectron = process.env.IS_ELECTRON === 'yes';
3 |
4 | module.exports = async function (env, argv) {
5 | const config = await createExpoWebpackConfigAsync(
6 | {
7 | ...env
8 | },
9 | argv
10 | );
11 |
12 | if (!isElectron) config.output.publicPath = '/';
13 |
14 | return config;
15 | };
16 |
--------------------------------------------------------------------------------
/packages/008Q/.eslintignore:
--------------------------------------------------------------------------------
1 | dist
2 | node_modules
3 |
--------------------------------------------------------------------------------
/packages/008Q/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | commonjs: true,
5 | es6: true,
6 | jest: true,
7 | },
8 | extends: ["standard", "prettier"],
9 | parserOptions: {
10 | ecmaVersion: 2020,
11 | },
12 | plugins: ["prettier"],
13 | };
14 |
--------------------------------------------------------------------------------
/packages/008Q/index.js:
--------------------------------------------------------------------------------
1 | export * from "./src/Q";
2 |
--------------------------------------------------------------------------------
/packages/008Q/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "008Q",
3 | "version": "2.2.0",
4 | "main": "index.js",
5 | "license": "AGPL-3.0-only",
6 | "private": true,
7 | "author": {
8 | "name": "Kunzite",
9 | "email": "support@kunzite.app",
10 | "url": "https://kunzite.app"
11 | },
12 | "repository": "https://github.com/kunzite-app/008",
13 | "bugs": "https://github.com/kunzite-app/008/issues",
14 | "scripts": {
15 | "build": "webpack",
16 | "watch": "webpack --watch"
17 | },
18 | "dependencies": {
19 | "@mlc-ai/web-llm": "file:../web-llm",
20 | "audiobuffer-to-wav": "^1.0.0",
21 | "onnxruntime-web": "^1.16.3",
22 | "whisper-webgpu": "^0.8.0"
23 | },
24 | "devDependencies": {
25 | "eslint": "^8.23.1",
26 | "eslint-config-prettier": "^8.5.0",
27 | "eslint-config-standard": "^17.0.0",
28 | "eslint-plugin-import": "^2.26.0",
29 | "eslint-plugin-n": "^16.1.0",
30 | "eslint-plugin-node": "^11.0.0",
31 | "eslint-plugin-prettier": "^3.1.2",
32 | "eslint-plugin-promise": "^6.0.1",
33 | "eslint-plugin-standard": "^4.0.1",
34 | "prettier": "^2.7.1",
35 | "webpack": "^5.89.0",
36 | "webpack-cli": "^5.1.4"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/packages/008Q/playground/carrental.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008Q/playground/carrental.mp3
--------------------------------------------------------------------------------
/packages/008Q/playground/carrental.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008Q/playground/carrental.ogg
--------------------------------------------------------------------------------
/packages/008Q/playground/carrental.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008Q/playground/carrental.wav
--------------------------------------------------------------------------------
/packages/008Q/playground/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | or
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/packages/008Q/playground/index.js:
--------------------------------------------------------------------------------
1 | const { transcript, processAudio, summarize } = window.Q008;
2 |
3 | /*
4 | const { vad } = window.Q008;
5 |
6 | const main2 = async () => {
7 | const { audio } = await processAudio({ input: "carrental.wav" });
8 |
9 | const now = new Date();
10 | console.log("Running inference...");
11 | const probs = await vad({ audio });
12 | console.log(probs);
13 | console.log("Finished inference.", new Date() - now);
14 | };
15 | // main2();
16 | */
17 |
18 | const transcribe = async ({ audio }) => {
19 | const transcriptElem = document.getElementById("transcript");
20 | const summaElem = document.getElementById("summa");
21 |
22 | const { wav } = await processAudio({ input: audio });
23 | transcriptElem.innerHTML = "Transcribing...";
24 | let onInitProgress = (report) => {
25 | const { progress } = report;
26 | transcriptElem.innerHTML = `Transcribing...
Loading model (only the first time) ${Math.floor(
27 | progress * 100
28 | )}%`;
29 | };
30 | const transcription = await transcript({ wav, onInitProgress });
31 |
32 | let transcript_ = "";
33 | transcription.forEach(({ text }) => {
34 | transcript_ += `${text}
`;
35 | });
36 | transcriptElem.innerHTML = transcript_;
37 |
38 | summaElem.innerHTML = "Summarizing...";
39 | onInitProgress = (report) => {
40 | const { progress } = report;
41 | summaElem.innerHTML = `Summarizing...
Loading model (only the first time) ${Math.floor(
42 | progress * 100
43 | )}%`;
44 | };
45 |
46 | const summa = await summarize({ transcription, onInitProgress });
47 | summaElem.innerHTML = summa;
48 | };
49 |
50 | document.getElementById("audioFile").addEventListener(
51 | "change",
52 | async (e) => {
53 | const file = e.target.files[0];
54 | const url = URL.createObjectURL(file);
55 | const audioPlayer = document.getElementById("audioPlayer");
56 | audioPlayer.src = url;
57 | },
58 | false
59 | );
60 |
61 | document.getElementById("transcribeBtn").addEventListener("click", async () => {
62 | await transcribe({ audio: document.getElementById("audioPlayer").src });
63 | });
64 |
--------------------------------------------------------------------------------
/packages/008Q/playground/static/ort-wasm-simd-threaded.jsep.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008Q/playground/static/ort-wasm-simd-threaded.jsep.wasm
--------------------------------------------------------------------------------
/packages/008Q/playground/static/ort-wasm-simd-threaded.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008Q/playground/static/ort-wasm-simd-threaded.wasm
--------------------------------------------------------------------------------
/packages/008Q/playground/static/ort-wasm-simd.jsep.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008Q/playground/static/ort-wasm-simd.jsep.wasm
--------------------------------------------------------------------------------
/packages/008Q/playground/static/ort-wasm-simd.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008Q/playground/static/ort-wasm-simd.wasm
--------------------------------------------------------------------------------
/packages/008Q/playground/static/ort-wasm-threaded.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008Q/playground/static/ort-wasm-threaded.wasm
--------------------------------------------------------------------------------
/packages/008Q/playground/static/ort-wasm.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008Q/playground/static/ort-wasm.wasm
--------------------------------------------------------------------------------
/packages/008Q/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 |
3 | module.exports = {
4 | entry: "./index.js",
5 | output: {
6 | path: path.resolve(__dirname, "dist"),
7 | filename: "008Q.global.js",
8 | library: "Q008",
9 | libraryTarget: "var",
10 | },
11 | /*
12 | resolve: {
13 | fallback: {
14 | perf_hooks: false,
15 | },
16 | },
17 | */
18 | mode: "production",
19 | };
20 |
--------------------------------------------------------------------------------
/packages/008desktop/.eslintignore:
--------------------------------------------------------------------------------
1 | app
2 | node_modules
3 | build
4 | assets
5 |
--------------------------------------------------------------------------------
/packages/008desktop/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | commonjs: true,
5 | es6: true,
6 | jest: true
7 | },
8 | extends: ['standard', 'prettier'],
9 | globals: {
10 | Atomics: 'readonly',
11 | SharedArrayBuffer: 'readonly'
12 | },
13 | parserOptions: {
14 | ecmaVersion: 2018
15 | },
16 | ignorePatterns: ['assets/', 'dist/', 'node_modules/', 'public/', 'build/'],
17 | rules: {
18 | camelcase: [1, { properties: 'never' }],
19 | 'prettier/prettier': 'error'
20 | },
21 | plugins: ['prettier']
22 | };
23 |
--------------------------------------------------------------------------------
/packages/008desktop/.prettierignore:
--------------------------------------------------------------------------------
1 | lib
2 | node_modules
3 | build
4 | app
5 |
--------------------------------------------------------------------------------
/packages/008desktop/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "printWidth": 80,
3 | "tabWidth": 2,
4 | "useTabs": false,
5 | "arrowParens": "avoid",
6 | "singleQuote": true,
7 | "trailingComma": "none",
8 | "proseWrap": "always"
9 | }
10 |
--------------------------------------------------------------------------------
/packages/008desktop/assets/logo-round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008desktop/assets/logo-round.png
--------------------------------------------------------------------------------
/packages/008desktop/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008desktop/assets/logo.png
--------------------------------------------------------------------------------
/packages/008desktop/assets/tray.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008desktop/assets/tray.ico
--------------------------------------------------------------------------------
/packages/008desktop/assets/tray@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008desktop/assets/tray@2x.png
--------------------------------------------------------------------------------
/packages/008desktop/assets/trayd@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008desktop/assets/trayd@2x.png
--------------------------------------------------------------------------------
/packages/008desktop/assets/trayl@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008desktop/assets/trayl@2x.png
--------------------------------------------------------------------------------
/packages/008desktop/assets/trayp@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kunzite-app/008/fffdc55112cd93fe2570c7d66f4dd77c3296a633/packages/008desktop/assets/trayp@2x.png
--------------------------------------------------------------------------------
/packages/008desktop/build/entitlements.mac.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.cs.allow-dyld-environment-variables
6 |
7 | com.apple.security.cs.disable-library-validation
8 |
9 | com.apple.security.cs.allow-jit
10 |
11 | com.apple.security.cs.allow-unsigned-executable-memory
12 |
13 | com.apple.security.cs.debugger
14 |
15 | com.apple.security.network.client
16 |
17 | com.apple.security.network.server
18 |
19 | com.apple.security.files.user-selected.read-only
20 |
21 | com.apple.security.inherit
22 |
23 | com.apple.security.automation.apple-events
24 |
25 | com.apple.security.device.audio-input
26 |
27 | com.apple.security.device.camera
28 |
29 |
30 |
--------------------------------------------------------------------------------
/packages/008desktop/loader.js:
--------------------------------------------------------------------------------
1 | const { contextBridge, ipcRenderer } = require('electron');
2 |
3 | const os = require('os');
4 | const path = require('path');
5 |
6 | const express = require('express');
7 | const bodyParser = require('body-parser');
8 | const multer = require('multer');
9 | const PQueue = require('p-queue').default;
10 |
11 | const { Q008_PORT = 1008, Q008_QUEUE_CONCURRENCY = 2 } = process.env;
12 |
13 | const QUEUE = new PQueue({ concurrency: Q008_QUEUE_CONCURRENCY });
14 |
15 | const errorHandler = (err, req, res, next) => {
16 | const { statusCode = 500, message: error } = err;
17 | return res.status(statusCode).json({ error }).end();
18 | };
19 |
20 | const upload = multer({
21 | storage: multer.diskStorage({
22 | limits: { fileSize: 50 * 1024 * 1024 },
23 | destination: (req, file, cb) => {
24 | cb(null, os.tmpdir());
25 | },
26 | filename: (req, file, cb) => {
27 | const { fieldname, originalname } = file;
28 | cb(null, `${req.body.uuid}-${fieldname}${path.extname(originalname)}`);
29 | }
30 | })
31 | });
32 |
33 | const app = express();
34 | app.use(bodyParser.json());
35 |
36 | app.get('/ping', async (req, res) => {
37 | res.send('pong');
38 | });
39 |
40 | app.post('/login', async (req, res, next) => {
41 | try {
42 | document.dispatchEvent(new CustomEvent('Q008:login', { detail: req.body }));
43 | res.send({ acknowledge: true });
44 | } catch (err) {
45 | next(err, req, res);
46 | }
47 | });
48 |
49 | app.post('/q008', upload.single('file'), async (req, res, next) => {
50 | try {
51 | await QUEUE.add(async () => {
52 | const path = `file://${req.file.path}`;
53 | const id = req.body.uuid;
54 | document.dispatchEvent(
55 | new CustomEvent('Q008:audio', { detail: { id, path } })
56 | );
57 |
58 | res.send({ success: true, id });
59 | });
60 | } catch (err) {
61 | next(err, req, res);
62 | }
63 | });
64 |
65 | app.use(errorHandler);
66 | app.listen(Q008_PORT, () => {
67 | console.log(`008Q server running on port ${Q008_PORT}`);
68 | });
69 |
70 | contextBridge.exposeInMainWorld('electron', { ipcRenderer });
71 |
--------------------------------------------------------------------------------
/packages/008desktop/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "008desktop",
3 | "description": "Open-source event-driven AI powered Softphone",
4 | "version": "2.2.0",
5 | "license": "AGPL-3.0-only",
6 | "private": true,
7 | "author": {
8 | "name": "Kunzite",
9 | "email": "support@kunzite.app",
10 | "url": "https://kunzite.app"
11 | },
12 | "repository": "https://github.com/kunzite-app/008",
13 | "bugs": "https://github.com/kunzite-app/008/issues",
14 | "productName": "008",
15 | "main": "index.js",
16 | "scripts": {
17 | "start": "APP_DEBUG_008=yes APP_URL_008=http://localhost:19006/ electron .",
18 | "lint": "eslint ./",
19 | "format": "prettier --write",
20 | "build": "yarn build-icons && electron-builder build -mwl -c.extraMetadata.main=index.js --publish never",
21 | "build-icons": "yarn build-icons-mac && yarn build-icons-win",
22 | "build-icons-mac": "electron-icon-builder --input=assets/logo-round.png --output=./build",
23 | "build-icons-win": "electron-icon-builder --input=assets/logo.png --output=./build/win"
24 | },
25 | "build": {
26 | "appId": "app.kunzite.008",
27 | "artifactName": "008-desktop-${os}.${ext}",
28 | "buildDependenciesFromSource": true,
29 | "extends": null,
30 | "afterSign": "scripts/notarize.js",
31 | "directories": {
32 | "output": "build"
33 | },
34 | "nsis": {
35 | "allowToChangeInstallationDirectory": true,
36 | "oneClick": false
37 | },
38 | "win": {
39 | "icon": "build/win/icons/win/icon.ico",
40 | "target": [
41 | {
42 | "target": "nsis",
43 | "arch": [
44 | "x64"
45 | ]
46 | }
47 | ]
48 | },
49 | "mac": {
50 | "icon": "build/icons/mac/icon.icns",
51 | "extendInfo": {
52 | "NSMicrophoneUsageDescription": "The microphone is needed to be able to talk",
53 | "NSCameraUsageDescription": "The camera is needed in order to make video calls",
54 | "com.apple.security.device.audio-input": true,
55 | "com.apple.security.device.camera": true
56 | },
57 | "target": [
58 | {
59 | "target": "dmg",
60 | "arch": "universal"
61 | }
62 | ],
63 | "hardenedRuntime": true,
64 | "gatekeeperAssess": false,
65 | "entitlements": "build/entitlements.mac.plist",
66 | "entitlementsInherit": "build/entitlements.mac.plist",
67 | "publish": null
68 | },
69 | "linux": {
70 | "target": [
71 | {
72 | "target": "AppImage",
73 | "arch": [
74 | "x64"
75 | ]
76 | }
77 | ]
78 | }
79 | },
80 | "dependencies": {
81 | "008Q": "file:../008Q",
82 | "body-parser": "^1.20.2",
83 | "electron-log": "^4.4.8",
84 | "electron-store": "^8.1.0",
85 | "express": "^4.18.3",
86 | "multer": "^1.4.5-lts.1",
87 | "p-queue": "6.6.2",
88 | "rage-edit": "^1.2.0"
89 | },
90 | "devDependencies": {
91 | "electron": "28.2.0",
92 | "electron-builder": "^24.8.0",
93 | "electron-icon-builder": "^2.0.1",
94 | "electron-notarize": "^1.2.2",
95 | "eslint": "^8.23.1",
96 | "eslint-config-prettier": "^8.5.0",
97 | "eslint-config-standard": "^17.0.0",
98 | "eslint-plugin-import": "^2.26.0",
99 | "eslint-plugin-n": "^16.1.0",
100 | "eslint-plugin-node": "^11.0.0",
101 | "eslint-plugin-prettier": "^3.1.2",
102 | "eslint-plugin-promise": "^6.0.1",
103 | "eslint-plugin-standard": "^4.0.1",
104 | "prettier": "^2.7.1"
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/packages/008desktop/scripts/notarize.js:
--------------------------------------------------------------------------------
1 | const { notarize } = require('electron-notarize');
2 | const { NOT_APPLE_ID, NOT_APPLE_ID_PASS, CI } = process.env;
3 |
4 | exports.default = async function notarizing(context) {
5 | if (!CI) return;
6 |
7 | const { electronPlatformName, appOutDir } = context;
8 | if (electronPlatformName !== 'darwin') return;
9 |
10 | const appName = context.packager.appInfo.productFilename;
11 | const appPath = `${appOutDir}/${appName}.app`;
12 |
13 | return await notarize({
14 | tool: 'notarytool',
15 | appPath,
16 | appBundleId: 'app.kunzite.008',
17 | appleId: NOT_APPLE_ID,
18 | appleIdPassword: NOT_APPLE_ID_PASS,
19 | teamId: '5WA5SSW77L',
20 | ascProvider: '5WA5SSW77L'
21 | });
22 | };
23 |
--------------------------------------------------------------------------------
/packages/008desktop/utils.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 | const path = require('path');
3 |
4 | const fetch = require('node-fetch');
5 |
6 | const download = async ({ url, destination }) => {
7 | const response = await fetch(url);
8 |
9 | // Left to remember that we force the download in every startup to be able to update Q
10 | // if (fs.existsSync(destination)) return;
11 |
12 | const directory = path.dirname(destination);
13 | if (!fs.existsSync(directory)) {
14 | fs.mkdirSync(directory, { recursive: true });
15 | }
16 |
17 | if (!response.ok)
18 | throw new Error(`Error downloading Q: ${response.statusText}`);
19 |
20 | const stream = fs.createWriteStream(destination);
21 |
22 | response.body.pipe(stream);
23 |
24 | return new Promise((resolve, reject) => {
25 | stream.on('finish', resolve);
26 | stream.on('error', reject);
27 | });
28 | };
29 |
30 | exports.download = download;
31 |
--------------------------------------------------------------------------------
/packages/web-llm/cache_util.d.ts:
--------------------------------------------------------------------------------
1 | import { AppConfig } from "./config";
2 | export declare function hasModelInCache(modelId: string, appConfig?: AppConfig): Promise;
3 | export declare function deleteModelAllInfoInCache(modelId: string, appConfig?: AppConfig): Promise;
4 | export declare function deleteModelInCache(modelId: string, appConfig?: AppConfig): Promise;
5 | export declare function deleteChatConfigInCache(modelId: string, appConfig?: AppConfig): Promise;
6 | export declare function deleteModelWasmInCache(modelId: string, appConfig?: AppConfig): Promise;
7 | //# sourceMappingURL=cache_util.d.ts.map
--------------------------------------------------------------------------------
/packages/web-llm/cache_util.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"cache_util.d.ts","sourceRoot":"","sources":["../src/cache_util.ts"],"names":[],"mappings":"AACA,OAAO,EACL,SAAS,EAGV,MAAM,UAAU,CAAC;AAYlB,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ9F;AAED,wBAAsB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,SAAS,iBAWrF;AAGD,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,SAAS,iBAgB9E;AAED,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,SAAS,iBAcnF;AAED,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,SAAS,iBAalF"}
--------------------------------------------------------------------------------
/packages/web-llm/chat_module.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"chat_module.d.ts","sourceRoot":"","sources":["../src/chat_module.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/packages/web-llm/config.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5B,cAAc,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/C,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACxB,uBAAuB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACxC,cAAc,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9B,6BAA6B,CAAC,EAAE,OAAO,CAAC;CACzC;AAED,oBAAY,IAAI;IACd,IAAI,SAAS;IACb,SAAS,cAAc;CACxB;AAED;;;;;;;GAOG;AACH,oBAAY,mBAAmB;IAC7B,MAAM,qBAAqB;IAC3B,IAAI,mBAAmB;IACvB,SAAS,wBAAwB;IACjC,IAAI,mBAAmB;IACvB,QAAQ,sBAAsB;CAC/B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU;IAEzB,eAAe,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC/B,WAAW,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC1C,aAAa,EAAE,MAAM,GAAG,kBAAkB,CAAC;IAG3C,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IAEzB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AAEH,MAAM,WAAW,WAAY,SAAQ,OAAO,CAAC,UAAU,CAAC;CAAI;AAE5D;;;;;;;;;;GAUG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,sBAAsB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;CACrD;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAE/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;CACzC;AAED,wBAAgB,sCAAsC,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAuErF;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,iBAAiB,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACnC;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IAC/B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,YAAY,CAAC;AACtC,eAAO,MAAM,iBAAiB,sFACuD,CAAC;AAEtF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,SA+R/B,CAAA"}
--------------------------------------------------------------------------------
/packages/web-llm/conversation.d.ts:
--------------------------------------------------------------------------------
1 | import { ConvTemplateConfig, Role } from "./config";
2 | /**
3 | * Helper to keep track of history conversations.
4 | */
5 | export declare class Conversation {
6 | messages: Array<[Role, string, string | undefined]>;
7 | readonly config: ConvTemplateConfig;
8 | function_string: string;
9 | use_function_calling: boolean;
10 | override_system_message?: string;
11 | constructor(config: ConvTemplateConfig);
12 | private getPromptArrayInternal;
13 | /**
14 | * Get prompt arrays with the first one as system.
15 | *
16 | * @returns The prompt array.
17 | */
18 | getPromptArray(): Array;
19 | /**
20 | * Get the last round of prompt has not been fed as input.
21 | *
22 | * @note This function needs to be used with the assumption that
23 | * the caller call appendMessage then appendReplyHeader.
24 | *
25 | * @returns The prompt array.
26 | */
27 | getPrompArrayLastRound(): string[];
28 | /**
29 | * Resets all states for this.conversation.
30 | */
31 | reset(): void;
32 | getStopStr(): string[];
33 | getStopTokens(): number[];
34 | appendMessage(role: Role, message: string, role_name?: string): void;
35 | appendReplyHeader(role: Role): void;
36 | finishReply(message: string): void;
37 | }
38 | export declare function getConversation(conv_template: string | ConvTemplateConfig, conv_config?: Partial): Conversation;
39 | /**
40 | * Compare the states of two conversation instances. Equality is defined as their getPromptArray()
41 | * should return the exact same things, which is determined by fields: messages, function_string,
42 | * use_function_calling, and override_system_message.
43 | *
44 | * @returns True if `convA` equals to `convB`
45 | * @note We assume convA and convB has the same `this.config`.
46 | */
47 | export declare function compareConversationObject(convA: Conversation, convB: Conversation): boolean;
48 | //# sourceMappingURL=conversation.d.ts.map
--------------------------------------------------------------------------------
/packages/web-llm/conversation.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"conversation.d.ts","sourceRoot":"","sources":["../src/conversation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAuB,IAAI,EAAE,MAAM,UAAU,CAAC;AAEzE;;GAEG;AACH,qBAAa,YAAY;IAEhB,QAAQ,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAM;IAChE,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IAE7B,eAAe,SAAM;IACrB,oBAAoB,UAAS;IAC7B,uBAAuB,CAAC,EAAE,MAAM,CAAa;gBAKxC,MAAM,EAAE,kBAAkB;IAItC,OAAO,CAAC,sBAAsB;IAiE9B;;;;OAIG;IACH,cAAc,IAAI,KAAK,CAAC,MAAM,CAAC;IAI/B;;;;;;;OAOG;IACH,sBAAsB;IAOtB;;OAEG;IACH,KAAK;IAQL,UAAU,IAAI,MAAM,EAAE;IAOtB,aAAa;IAIb,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM;IAY7D,iBAAiB,CAAC,IAAI,EAAE,IAAI;IAO5B,WAAW,CAAC,OAAO,EAAE,MAAM;CAS5B;AAED,wBAAgB,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,kBAAkB,EAAE,WAAW,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,YAAY,CAwRnI;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAsB3F"}
--------------------------------------------------------------------------------
/packages/web-llm/engine.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/packages/web-llm/grammar.d.ts:
--------------------------------------------------------------------------------
1 | import * as tvmjs from "tvmjs";
2 | export type BNFGrammar = tvmjs.TVMObject;
3 | export type GrammarStateMatcher = tvmjs.TVMObject;
4 | /**
5 | * A factory class for generating and calling GrammarStateMatcher (GrammarSM) and BNFGrammar related
6 | * methods, essentially a wrapper of related global functions in the tvm instance's wasm.
7 | *
8 | * We implement a factory class rather than having classes of GrammarStateMatcher and BNFGrammar
9 | * because factory class allows us to only get/dispose PackedFunc once -- especially when we need
10 | * multiple instances of BNFGrammar or GrammarStateMatcher.
11 | */
12 | export declare class GrammarFactory {
13 | private fBNFGrammarGetGrammarOfJSON;
14 | private fGrammarSMFromTokenTable;
15 | private fGrammarSMAcceptToken;
16 | private fGrammarSMFindNextTokenBitmaskAsNDArray;
17 | private fGrammarSMIsTerminated;
18 | private fGrammarSMResetState;
19 | /**
20 | * Extract TVM global functions from tvm runtime instance.
21 | *
22 | * @param tvm An instantiated tvm runtime instance.
23 | */
24 | constructor(tvm: tvmjs.Instance);
25 | /**
26 | * @returns BNFGrammar of JSON.
27 | * @note Caller needs to handle disposal of returned object.
28 | */
29 | getBNFGrammarOfJSON(): BNFGrammar;
30 | /**
31 | * Creates a Grammar State Matcher from a specified BNFGrammar rule and a token table.
32 | *
33 | * @param grammar A BNFGrammar used to specify the rule for the state matcher.
34 | * @param tokenTable A list of all tokens in the tokenizer in the order of their ids.
35 | * @param maxRollbackSteps Max rollback steps to support. Currently not supported, has to be zero.
36 | * @returns A Grammar state matcher
37 | * @note Caller needs to handle disposal of returned object.
38 | */
39 | getGrammarStateMatcherFromTokenTable(grammar: BNFGrammar, tokenTable: string[], maxRollbackSteps?: number): GrammarStateMatcher;
40 | /**
41 | * Accept a new token to the gramamr state matcher, updating its internal state.
42 | *
43 | * @param grammarStateMatcher The grammar state matcher that will accept a new token and update
44 | * its stsate correspondingly.
45 | * @param tokenID The token to be accepted in its ID.
46 | * @returns Whether the token is accepted.
47 | */
48 | acceptToken(grammarStateMatcher: GrammarStateMatcher, tokenID: number): boolean;
49 | /**
50 | * Returns a bitmask in the form of an NDArray of shape (max_num_token, ceildiv(vocab_size, 32))
51 | * based on what tokens can/cannot be accepted by the current state of the grammar state matcher.
52 | *
53 | * @param grammarStateMatcher The grammar state matcher that will produce the bit mask.
54 | * @returns A bitmask in the form of an NDArray.
55 | */
56 | findNextTokenBitmask(grammarStateMatcher: GrammarStateMatcher): tvmjs.TVMObject;
57 | /**
58 | * @returns Whether the grammar state matcher has reached the end and hence terminated.
59 | */
60 | isTerminated(grammarStateMatcher: GrammarStateMatcher): boolean;
61 | /**
62 | * Reset the state of matcher to the initial state.
63 | */
64 | resetState(grammarStateMatcher: GrammarStateMatcher): void;
65 | /**
66 | * Dispose all tvmjs.PackedFunc this factory is initialized with.
67 | */
68 | dispose(): void;
69 | }
70 | //# sourceMappingURL=grammar.d.ts.map
--------------------------------------------------------------------------------
/packages/web-llm/grammar.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"grammar.d.ts","sourceRoot":"","sources":["../src/grammar.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,MAAM,UAAU,GAAG,KAAK,CAAC,SAAS,CAAC;AACzC,MAAM,MAAM,mBAAmB,GAAG,KAAK,CAAC,SAAS,CAAC;AAElD;;;;;;;GAOG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,2BAA2B,CAAmB;IACtD,OAAO,CAAC,wBAAwB,CAAmB;IACnD,OAAO,CAAC,qBAAqB,CAAmB;IAChD,OAAO,CAAC,uCAAuC,CAAmB;IAClE,OAAO,CAAC,sBAAsB,CAAmB;IACjD,OAAO,CAAC,oBAAoB,CAAmB;IAE/C;;;;OAIG;gBACS,GAAG,EAAE,KAAK,CAAC,QAAQ;IAwB/B;;;OAGG;IACH,mBAAmB,IAAI,UAAU;IAIjC;;;;;;;;OAQG;IACH,oCAAoC,CAClC,OAAO,EAAE,UAAU,EACnB,UAAU,EAAE,MAAM,EAAE,EACpB,gBAAgB,SAAI,GACnB,mBAAmB;IAQtB;;;;;;;OAOG;IACH,WAAW,CACT,mBAAmB,EAAE,mBAAmB,EACxC,OAAO,EAAE,MAAM,GACd,OAAO;IAUV;;;;;;OAMG;IACH,oBAAoB,CAAC,mBAAmB,EAAE,mBAAmB,GAAG,KAAK,CAAC,SAAS;IAI/E;;OAEG;IACH,YAAY,CAAC,mBAAmB,EAAE,mBAAmB,GAAG,OAAO;IAI/D;;OAEG;IACH,UAAU,CAAC,mBAAmB,EAAE,mBAAmB,GAAG,IAAI;IAI1D;;OAEG;IACH,OAAO;CAQR"}
--------------------------------------------------------------------------------
/packages/web-llm/index.d.ts:
--------------------------------------------------------------------------------
1 | export { ModelRecord, AppConfig, ChatOptions, EngineConfig, GenerationConfig, prebuiltAppConfig, modelVersion, modelLibURLPrefix } from "./config";
2 | export { InitProgressCallback, InitProgressReport, EngineInterface, LogitProcessor, } from "./types";
3 | export { Engine, CreateEngine, } from "./engine";
4 | export { hasModelInCache, deleteChatConfigInCache, deleteModelAllInfoInCache, deleteModelWasmInCache, deleteModelInCache, } from "./cache_util";
5 | export { EngineWorkerHandler, WebWorkerEngine, CreateWebWorkerEngine } from "./web_worker";
6 | export { WorkerMessage, CustomRequestParams } from "./message";
7 | export { ServiceWorkerEngineHandler, ServiceWorkerEngine, CreateServiceWorkerEngine, } from "./service_worker";
8 | export * from './openai_api_protocols/index';
9 | //# sourceMappingURL=index.d.ts.map
--------------------------------------------------------------------------------
/packages/web-llm/index.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,SAAS,EACT,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,eAAe,EACf,cAAc,GACf,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,MAAM,EACN,YAAY,GACb,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,eAAe,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,kBAAkB,GAChH,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,qBAAqB,EACtB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,aAAa,EACb,mBAAmB,EACpB,MAAM,WAAW,CAAA;AAElB,OAAO,EACL,0BAA0B,EAC1B,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAE1B,cAAc,8BAA8B,CAAC"}
--------------------------------------------------------------------------------
/packages/web-llm/llm_chat.d.ts:
--------------------------------------------------------------------------------
1 | import * as tvmjs from "tvmjs";
2 | import { Tokenizer } from "@mlc-ai/web-tokenizers";
3 | import { ChatConfig, GenerationConfig } from "./config";
4 | import { Conversation } from "./conversation";
5 | import { LogitProcessor } from "./types";
6 | import { ChatCompletionFinishReason, ChatCompletionTokenLogprob } from "./openai_api_protocols/index";
7 | export declare class LLMChatPipeline {
8 | private config;
9 | private tokenizer;
10 | private tvm;
11 | private device;
12 | private vm;
13 | private prefill;
14 | private decoding;
15 | private embed;
16 | private fapplyBitmask;
17 | private fclearKVCaches;
18 | private fKVCacheAddSequence;
19 | private fKVCacheRemoveSequence;
20 | private fKVCacheBeginForward;
21 | private fKVCacheEndForward;
22 | private fKVCacheEnableSlidingWindowForSeq;
23 | private params;
24 | private kvCache;
25 | private logitsOnCPU?;
26 | private filledKVCacheLength;
27 | private bosTokenId;
28 | private maxWindowLength;
29 | private slidingWindowSize;
30 | private attentionSinkSize;
31 | private prefillChunkSize;
32 | private resetStatsPerPrefill;
33 | private stopStr;
34 | private stopTokens;
35 | private outputMessage;
36 | private outputIds;
37 | private stopTriggered;
38 | private finishReason;
39 | private appearedTokensFreq;
40 | private conversation;
41 | private tokenLogprobArray;
42 | private decodingTotalTime;
43 | private decodingTotalTokens;
44 | private prefillTotalTime;
45 | private prefillTotalTokens;
46 | private curRoundDecodingTotalTokens;
47 | private curRoundPrefillTotalTokens;
48 | private logger;
49 | private logitProcessor?;
50 | private grammarFactory;
51 | private grammarStateMatcher?;
52 | private tokenTable?;
53 | private bitmaskSize;
54 | private vocabSize;
55 | constructor(tvm: tvmjs.Instance, tokenizer: Tokenizer, config: ChatConfig, logitProcessor?: LogitProcessor);
56 | dispose(): void;
57 | /**
58 | * Get the current message.
59 | */
60 | getMessage(): string;
61 | /**
62 | * Reset the runtime statistics
63 | */
64 | resetRuntimeStats(): void;
65 | /**
66 | * Reset the chat history
67 | */
68 | resetChat(keepStats?: boolean): void;
69 | /**
70 | * Reset KV Cache
71 | */
72 | resetKVCache(): void;
73 | /**
74 | * @returns Whether stop is triggered.
75 | */
76 | stopped(): boolean;
77 | /**
78 | * @returns Finish reason; undefined if generation not started/stopped yet.
79 | */
80 | getFinishReason(): ChatCompletionFinishReason | undefined;
81 | /**
82 | * @returns tokenLogprobArray for this current round of autoregressive generation.
83 | * Updated upon each sampled token, cleared upon each prefillStep().
84 | */
85 | getTokenLogprobArray(): Array;
86 | /**
87 | * @returns the number of tokens decoded for a single request or a single choice in the request.
88 | */
89 | getCurRoundDecodingTotalTokens(): number;
90 | /**
91 | * @returns the number of tokens decoded for a single request or a single choice in the request.
92 | */
93 | getCurRoundPrefillTotalTokens(): number;
94 | /**
95 | * @returns Runtime stats information.
96 | */
97 | runtimeStatsText(): string;
98 | /**
99 | * Set the seed for the RNG `this.tvm.rng`.
100 | */
101 | setSeed(seed: number): void;
102 | /**
103 | * @returns The conversation object (not a deep copy).
104 | */
105 | getConversationObject(): Conversation;
106 | /**
107 | * Set this.conversation to a new conversation object.
108 | */
109 | setConversation(newConv: Conversation): void;
110 | asyncLoadWebGPUPipelines(): Promise;
111 | /**
112 | * Generate the first token given input prompt
113 | */
114 | prefillStep(inp: string, inp_role_str?: string, genConfig?: GenerationConfig): Promise;
115 | decodeStep(genConfig?: GenerationConfig): Promise;
116 | /**
117 | * Manually trigger stop if it is not stopped.
118 | */
119 | triggerStop(): void;
120 | /**
121 | * Add a generated token and check for stop.
122 | *
123 | * @param nextToken The next token.
124 | * @param genConfig Configs that override `this.config` for this round of generation.
125 | */
126 | private processNextToken;
127 | private forward;
128 | private updateLogitsOnCPU;
129 | private sampleTokenFromLogits;
130 | private getInputTokens;
131 | forwardTokensAndSample(inputIds: Array, isPrefill: boolean): Promise;
132 | /**
133 | * Based on `sampledToken` and `this.logitsOnCPU`, which becomes a distribution after
134 | * calling `this.tvm.applySoftmaxWithTemperature()`, generate `ChatCompletionTokenLogprob` and
135 | * update `this.tokenLogprobArray`.
136 | *
137 | * @param sampledToken The token ID sampled.
138 | * @param top_logprobs Number of top tokens to include; `top_logprobs` in `ChatCompletionRequest`.
139 | *
140 | * @return The `ChatCompletionTokenLogprob` for this single autoregressive step.
141 | */
142 | private getTokenLogprob;
143 | evaluate(): Promise;
144 | }
145 | //# sourceMappingURL=llm_chat.d.ts.map
--------------------------------------------------------------------------------
/packages/web-llm/llm_chat.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"llm_chat.d.ts","sourceRoot":"","sources":["../src/llm_chat.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/packages/web-llm/message.d.ts:
--------------------------------------------------------------------------------
1 | import { AppConfig, ChatOptions, GenerationConfig } from "./config";
2 | import { InitProgressReport } from "./types";
3 | import { ChatCompletionRequestStreaming, ChatCompletionRequestNonStreaming, ChatCompletion, ChatCompletionChunk } from "./openai_api_protocols/index";
4 | /**
5 | * Message kind used by worker
6 | */
7 | type RequestKind = ("return" | "throw" | "reload" | "generate" | "runtimeStatsText" | "interruptGenerate" | "unload" | "resetChat" | "init" | "initProgressCallback" | "generateProgressCallback" | "getMaxStorageBufferBindingSize" | "getGPUVendor" | "forwardTokensAndSample" | "chatCompletionNonStreaming" | "getMessage" | "chatCompletionStreamInit" | "chatCompletionStreamNextChunk" | "customRequest");
8 | export interface ReloadParams {
9 | modelId: string;
10 | chatOpts?: ChatOptions;
11 | appConfig?: AppConfig;
12 | }
13 | export interface GenerateParams {
14 | input: string | ChatCompletionRequestNonStreaming;
15 | streamInterval?: number;
16 | genConfig?: GenerationConfig;
17 | }
18 | export interface ResetChatParams {
19 | keepStats: boolean;
20 | }
21 | export interface GenerateProgressCallbackParams {
22 | step: number;
23 | currentMessage: string;
24 | }
25 | export interface ForwardTokensAndSampleParams {
26 | inputIds: Array;
27 | isPrefill: boolean;
28 | }
29 | export interface ChatCompletionNonStreamingParams {
30 | request: ChatCompletionRequestNonStreaming;
31 | }
32 | export interface ChatCompletionStreamInitParams {
33 | request: ChatCompletionRequestStreaming;
34 | }
35 | export interface CustomRequestParams {
36 | requestName: string;
37 | requestMessage: string;
38 | }
39 | export type MessageContent = GenerateProgressCallbackParams | ReloadParams | GenerateParams | ResetChatParams | ForwardTokensAndSampleParams | ChatCompletionNonStreamingParams | ChatCompletionStreamInitParams | CustomRequestParams | InitProgressReport | string | null | number | ChatCompletion | ChatCompletionChunk | void;
40 | /**
41 | * The message used in exchange between worker
42 | * and the main thread.
43 | */
44 | export interface WorkerMessage {
45 | kind: RequestKind;
46 | uuid: string;
47 | content: MessageContent;
48 | }
49 | export {};
50 | //# sourceMappingURL=message.d.ts.map
--------------------------------------------------------------------------------
/packages/web-llm/message.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../src/message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EACL,8BAA8B,EAC9B,iCAAiC,EACjC,cAAc,EACd,mBAAmB,EACpB,MAAM,8BAA8B,CAAC;AAEtC;;GAEG;AACH,KAAK,WAAW,GAAG,CACjB,QAAQ,GAAG,OAAO,GAClB,QAAQ,GAAG,UAAU,GAAG,kBAAkB,GAC1C,mBAAmB,GAAG,QAAQ,GAAG,WAAW,GAAG,MAAM,GACrD,sBAAsB,GAAG,0BAA0B,GAAG,gCAAgC,GACtF,cAAc,GAAG,wBAAwB,GAAG,4BAA4B,GAAG,YAAY,GACvF,0BAA0B,GAAG,+BAA+B,GAAG,eAAe,CAAC,CAAC;AAClF,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AACD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,GAAG,iCAAiC,CAAC;IAClD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,gBAAgB,CAAC;CAC9B;AACD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,OAAO,CAAC;CACpB;AACD,MAAM,WAAW,8BAA8B;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;CACxB;AACD,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;CACpB;AACD,MAAM,WAAW,gCAAgC;IAC/C,OAAO,EAAE,iCAAiC,CAAC;CAC5C;AACD,MAAM,WAAW,8BAA8B;IAC7C,OAAO,EAAE,8BAA8B,CAAC;CACzC;AAED,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;CACxB;AACD,MAAM,MAAM,cAAc,GACxB,8BAA8B,GAC9B,YAAY,GACZ,cAAc,GACd,eAAe,GACf,4BAA4B,GAC5B,gCAAgC,GAChC,8BAA8B,GAC9B,mBAAmB,GACnB,kBAAkB,GAClB,MAAM,GACN,IAAI,GACJ,MAAM,GACN,cAAc,GACd,mBAAmB,GACnB,IAAI,CAAC;AACP;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,cAAc,CAAC;CACzB"}
--------------------------------------------------------------------------------
/packages/web-llm/openai_api_protocols/apis.d.ts:
--------------------------------------------------------------------------------
1 | import { EngineInterface } from "../types";
2 | import { Completions } from "./chat_completion";
3 | export declare class Chat {
4 | private engine;
5 | completions: Completions;
6 | constructor(engine: EngineInterface);
7 | }
8 | //# sourceMappingURL=apis.d.ts.map
--------------------------------------------------------------------------------
/packages/web-llm/openai_api_protocols/apis.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"apis.d.ts","sourceRoot":"","sources":["../../src/openai_api_protocols/apis.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,qBAAa,IAAI;IACb,OAAO,CAAC,MAAM,CAAkB;IAChC,WAAW,EAAE,WAAW,CAAC;gBAEb,MAAM,EAAE,eAAe;CAItC"}
--------------------------------------------------------------------------------
/packages/web-llm/openai_api_protocols/index.d.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * The input to OpenAI API, directly adopted from openai-node with small tweaks:
3 | * https://github.com/openai/openai-node/blob/master/src/resources/chat/completions.ts
4 | *
5 | * Copyright 2024 OpenAI
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 | export { ChatCompletionRequestBase, ChatCompletionRequestNonStreaming, ChatCompletionRequestStreaming, ChatCompletionRequest, ChatCompletion, ChatCompletionChunk, ChatCompletionRequestUnsupportedFields, postInitAndCheckFields, ChatCompletionContentPart, ChatCompletionContentPartText, ChatCompletionContentPartImage, ChatCompletionMessageToolCall, ChatCompletionRole, ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam, ChatCompletionAssistantMessageParam, ChatCompletionToolMessageParam, ChatCompletionMessageParam, FunctionParameters, FunctionDefinition, ChatCompletionTool, ChatCompletionNamedToolChoice, ChatCompletionToolChoiceOption, TopLogprob, ChatCompletionTokenLogprob, ChatCompletionMessage, CompletionUsage, ResponseFormat, ChatCompletionFinishReason, } from './chat_completion';
18 | //# sourceMappingURL=index.d.ts.map
--------------------------------------------------------------------------------
/packages/web-llm/openai_api_protocols/index.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/openai_api_protocols/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;EAeE;AAEF,OAAO,EACH,yBAAyB,EACzB,iCAAiC,EACjC,8BAA8B,EAC9B,qBAAqB,EACrB,cAAc,EACd,mBAAmB,EACnB,sCAAsC,EACtC,sBAAsB,EACtB,yBAAyB,EACzB,6BAA6B,EAC7B,8BAA8B,EAC9B,6BAA6B,EAC7B,kBAAkB,EAClB,gCAAgC,EAChC,8BAA8B,EAC9B,mCAAmC,EACnC,8BAA8B,EAC9B,0BAA0B,EAC1B,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,6BAA6B,EAC7B,8BAA8B,EAC9B,UAAU,EACV,0BAA0B,EAC1B,qBAAqB,EACrB,eAAe,EACf,cAAc,EACd,0BAA0B,GAC7B,MAAM,mBAAmB,CAAC"}
--------------------------------------------------------------------------------
/packages/web-llm/service_worker.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | import { AppConfig, ChatOptions, EngineConfig } from "./config";
3 | import { EngineInterface } from "./types";
4 | import { EngineWorkerHandler, WebWorkerEngine, PostMessageHandler } from "./web_worker";
5 | /**
6 | * A post message handler that sends messages to a chrome.runtime.Port.
7 | */
8 | export declare class PortPostMessageHandler implements PostMessageHandler {
9 | port: chrome.runtime.Port;
10 | enabled: boolean;
11 | constructor(port: chrome.runtime.Port);
12 | /**
13 | * Close the PortPostMessageHandler. This will prevent any further messages
14 | */
15 | close(): void;
16 | postMessage(event: any): void;
17 | }
18 | /**
19 | * Worker handler that can be used in a ServiceWorker.
20 | *
21 | * @example
22 | *
23 | * const engine = new Engine();
24 | * let handler;
25 | * chrome.runtime.onConnect.addListener(function (port) {
26 | * if (handler === undefined) {
27 | * handler = new ServiceWorkerEngineHandler(engine, port);
28 | * } else {
29 | * handler.setPort(port);
30 | * }
31 | * port.onMessage.addListener(handler.onmessage.bind(handler));
32 | * });
33 | */
34 | export declare class ServiceWorkerEngineHandler extends EngineWorkerHandler {
35 | modelId?: string;
36 | chatOpts?: ChatOptions;
37 | appConfig?: AppConfig;
38 | constructor(engine: EngineInterface, port: chrome.runtime.Port);
39 | setPort(port: chrome.runtime.Port): void;
40 | onmessage(event: any): void;
41 | }
42 | /**
43 | * Create a ServiceWorkerEngine.
44 | *
45 | * @param modelId The model to load, needs to either be in `webllm.prebuiltAppConfig`, or in
46 | * `engineConfig.appConfig`.
47 | * @param engineConfig Optionally configures the engine, see `webllm.EngineConfig` for more.
48 | * @param keepAliveMs The interval to send keep alive messages to the service worker.
49 | * See [Service worker lifecycle](https://developer.chrome.com/docs/extensions/develop/concepts/service-workers/lifecycle#idle-shutdown)
50 | * The default is 10s.
51 | * @returns An initialized `WebLLM.ServiceWorkerEngine` with `modelId` loaded.
52 | */
53 | export declare function CreateServiceWorkerEngine(modelId: string, engineConfig?: EngineConfig, keepAliveMs?: number): Promise;
54 | /**
55 | * A client of Engine that exposes the same interface
56 | */
57 | export declare class ServiceWorkerEngine extends WebWorkerEngine {
58 | port: chrome.runtime.Port;
59 | constructor();
60 | keepAlive(): void;
61 | /**
62 | * Initialize the chat with a model.
63 | *
64 | * @param modelId model_id of the model to load.
65 | * @param chatOpts Extra options to overide chat behavior.
66 | * @param appConfig Override the app config in this load.
67 | * @returns A promise when reload finishes.
68 | * @note The difference between init and reload is that init
69 | * should be called only once when the engine is created, while reload
70 | * can be called multiple times to switch between models.
71 | */
72 | init(modelId: string, chatOpts?: ChatOptions, appConfig?: AppConfig): Promise;
73 | }
74 | //# sourceMappingURL=service_worker.d.ts.map
--------------------------------------------------------------------------------
/packages/web-llm/service_worker.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"service_worker.d.ts","sourceRoot":"","sources":["../src/service_worker.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAEhE,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAEL,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAEtB;;GAEG;AACH,qBAAa,sBAAuB,YAAW,kBAAkB;IAC/D,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAQ;gBAEZ,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI;IAIrC;;OAEG;IACH,KAAK;IAIL,WAAW,CAAC,KAAK,EAAE,GAAG;CAKvB;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,0BAA2B,SAAQ,mBAAmB;IACjE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,SAAS,CAAC,EAAE,SAAS,CAAC;gBAEV,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI;IAS9D,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI;IAQjC,SAAS,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI;CAgD5B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,YAAY,EAC3B,WAAW,GAAE,MAAc,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAc9B;AAiCD;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,eAAe;IACtD,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;;IAS1B,SAAS;IAIT;;;;;;;;;;OAUG;IACG,IAAI,CACR,OAAO,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,WAAW,EACtB,SAAS,CAAC,EAAE,SAAS,GACpB,OAAO,CAAC,IAAI,CAAC;CAYjB"}
--------------------------------------------------------------------------------
/packages/web-llm/support.d.ts:
--------------------------------------------------------------------------------
1 | /** Util methods. */
2 | import { Tokenizer } from "@mlc-ai/web-tokenizers";
3 | /**
4 | * Based on `p_prob` of size (vocabSize,) which becomes a distribution after calling
5 | * `applySoftmaxWithTemperature()`, sample `top_logprobs` top-probable tokens.
6 | *
7 | * @param num_top_probs: `top_logprobs` from ChatCompletionRequest
8 | * @param p_prob: `logitsOnCPUArray`, being a distribution after `applySoftmaxWithTemperature()`.
9 | *
10 | * Followed implementation of `ComputeTopProbsImpl()` from [https://github.com/mlc-ai/mlc-llm/blob/
11 | * 5b8c529e9704abd09b0432da6dcb4b013fdf43b1/cpp/serve/sampler/cpu_sampler.cc].
12 | *
13 | * @returns Arrays of (tokenID, prob) pairs, ranked from highest prob to least.
14 | */
15 | export declare function getTopProbs(num_top_probs: number, p_prob: Float32Array): Array<[number, number]>;
16 | /**
17 | * Post-process a raw token (which may be a raw byte or contain lower one eights block) to the
18 | * actual token. We do this in order to conform with the tokenizers' setup.
19 | *
20 | * Follow implementation of [https://github.com/mlc-ai/mlc-llm/blob/
21 | * bcb9b6a33a672a70d760c9a8b03234124aab50c4/cpp/tokenizers.cc#L99]
22 | */
23 | export declare function postProcessToken(token: string): string;
24 | /**
25 | * Get the token table in the form of a string list of tokens, ordered by their token id.
26 | * @param tokenizer A loaded tokenizer.
27 | */
28 | export declare function getTokenTableFromTokenizer(tokenizer: Tokenizer): string[];
29 | //# sourceMappingURL=support.d.ts.map
--------------------------------------------------------------------------------
/packages/web-llm/support.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"support.d.ts","sourceRoot":"","sources":["../src/support.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CACvB,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAC5C,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAiCzB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CA4BtD;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,EAAE,CAQzE"}
--------------------------------------------------------------------------------
/packages/web-llm/types.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/packages/web-llm/web_worker.d.ts:
--------------------------------------------------------------------------------
1 | import { AppConfig, ChatOptions, EngineConfig, GenerationConfig } from "./config";
2 | import { EngineInterface, GenerateProgressCallback, InitProgressCallback } from "./types";
3 | import { ChatCompletionRequestBase, ChatCompletionRequestStreaming, ChatCompletionRequestNonStreaming, ChatCompletion, ChatCompletionChunk } from "./openai_api_protocols/index";
4 | import * as API from "./openai_api_protocols/apis";
5 | import { WorkerMessage, MessageContent } from "./message";
6 | export interface PostMessageHandler {
7 | postMessage: (message: any) => void;
8 | }
9 | /**
10 | * Worker handler that can be used in a WebWorker
11 | *
12 | * @example
13 | *
14 | * // setup a chat worker handler that routes
15 | * // requests to the chat
16 | * const engine = new Engine();
17 | * cont handler = new EngineWorkerHandler(engine);
18 | * onmessage = handler.onmessage;
19 | */
20 | export declare class EngineWorkerHandler {
21 | protected engine: EngineInterface;
22 | protected chatCompletionAsyncChunkGenerator?: AsyncGenerator;
23 | protected postMessageHandler?: PostMessageHandler;
24 | /**
25 | * @param engine A concrete implementation of EngineInterface
26 | * @param postMessageHandler Optionally, a handler to communicate with the content script.
27 | * This is only needed in ServiceWorker. In web worker, we can use `postMessage` from
28 | * DOM API directly.
29 | */
30 | constructor(engine: EngineInterface, postMessageHandler?: PostMessageHandler);
31 | postMessageInternal(event: any): void;
32 | setPostMessageHandler(postMessageHandler: PostMessageHandler): void;
33 | handleTask(uuid: string, task: () => Promise): Promise;
34 | onmessage(event: any): void;
35 | }
36 | export interface ChatWorker {
37 | onmessage: any;
38 | postMessage: (message: any) => void;
39 | }
40 | /**
41 | * Creates `WebWorkerEngine`, a client that holds the same interface as `Engine`.
42 | *
43 | * Equivalent to `new webllm.WebWorkerEngine(worker).reload(...)`.
44 | *
45 | * @param worker The worker that holds the actual Engine, intialized with `new Worker()`.
46 | * @param modelId The model to load, needs to either be in `webllm.prebuiltAppConfig`, or in
47 | * `engineConfig.appConfig`.
48 | * @param engineConfig Optionally configures the engine, see `webllm.EngineConfig` for more.
49 | * @returns An initialized `WebLLM.WebWorkerEngine` with `modelId` loaded.
50 | *
51 | * @note engineConfig.logitProcessorRegistry is ignored for `CreateWebWorkEngine()`.
52 | */
53 | export declare function CreateWebWorkerEngine(worker: any, modelId: string, engineConfig?: EngineConfig): Promise;
54 | /**
55 | * A client of Engine that exposes the same interface
56 | *
57 | * @example
58 | *
59 | * const chat = new webllm.WebWorkerEngine(new Worker(
60 | * new URL('./worker.ts', import.meta.url),
61 | * {type: 'module'}
62 | * ));
63 | */
64 | export declare class WebWorkerEngine implements EngineInterface {
65 | worker: ChatWorker;
66 | chat: API.Chat;
67 | private initProgressCallback?;
68 | private generateCallbackRegistry;
69 | private pendingPromise;
70 | constructor(worker: any);
71 | setInitProgressCallback(initProgressCallback?: InitProgressCallback): void;
72 | getInitProgressCallback(): InitProgressCallback | undefined;
73 | protected getPromise(msg: WorkerMessage): Promise;
74 | reload(modelId: string, chatOpts?: ChatOptions, appConfig?: AppConfig): Promise;
75 | getMaxStorageBufferBindingSize(): Promise;
76 | getGPUVendor(): Promise;
77 | getMessage(): Promise;
78 | generate(input: string | ChatCompletionRequestNonStreaming, progressCallback?: GenerateProgressCallback, streamInterval?: number, genConfig?: GenerationConfig): Promise;
79 | runtimeStatsText(): Promise;
80 | interruptGenerate(): void;
81 | unload(): Promise;
82 | resetChat(keepStats?: boolean): Promise;
83 | forwardTokensAndSample(inputIds: Array, isPrefill: boolean): Promise;
84 | /**
85 | * Every time the generator is called, we post a message to the worker asking it to
86 | * decode one step, and we expect to receive a message of `ChatCompletionChunk` from
87 | * the worker which we yield. The last message is `void`, meaning the generator has nothing
88 | * to yield anymore.
89 | */
90 | chatCompletionAsyncChunkGenerator(): AsyncGenerator;
91 | chatCompletion(request: ChatCompletionRequestNonStreaming): Promise;
92 | chatCompletion(request: ChatCompletionRequestStreaming): Promise>;
93 | chatCompletion(request: ChatCompletionRequestBase): Promise | ChatCompletion>;
94 | onmessage(event: any): void;
95 | }
96 | //# sourceMappingURL=web_worker.d.ts.map
--------------------------------------------------------------------------------
/packages/web-llm/web_worker.d.ts.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"web_worker.d.ts","sourceRoot":"","sources":["../src/web_worker.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------