├── .dockerignore ├── .env.example ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml └── workflows │ └── jekyll-gh-pages.yml ├── .gitignore ├── .npmignore ├── .npmrc ├── Dockerfile ├── LICENSE ├── README.md ├── docker ├── docker-compose.yml └── redis.conf ├── docs ├── 00_Start_here │ ├── 00_WTF_is_ECS.md │ ├── 01_Entities.md │ ├── 02_Events.md │ ├── 03_Systems.md │ ├── 04_Components.md │ └── 05_Prompts.md ├── 01_hello_chippr_agi │ ├── 01_introduction.md │ ├── 02_Setting_up.md │ ├── 03_Create_components.md │ ├── 04_creating_Entity.md │ └── 05_Final_steps.md ├── 02_Examples │ ├── 00_hello_system.md │ ├── ECS.md │ ├── WeatherComponent.mjs │ └── WeatherSystem.mjs ├── 20230521_152433_0000.png ├── 20230521_152500_0000.png ├── 20230521_152815_0000.png ├── CNAME ├── Core_Systems │ ├── DemoFlow.md │ └── Message_Bus.md ├── README.md ├── chipprAGI_v1.png ├── dev_updates.md ├── svg_20230521_153500_0000.svg └── svg_20230521_153513_0000.svg ├── examples ├── simple_demo.js └── websocket_demo.js ├── package-lock.json ├── package.json ├── src ├── components │ ├── active │ │ ├── IPFScid.mjs │ │ ├── ObjectiveDescription.mjs │ │ ├── SystemSelection.mjs │ │ ├── TaskDescription.mjs │ │ ├── TaskEmbedding.mjs │ │ ├── TaskExpanded.mjs │ │ └── TaskParent.mjs │ └── inactive │ │ └── foo.mjs ├── core │ ├── ChipprAGI.js │ ├── LangModel │ │ ├── huggingface.js │ │ ├── langModel.js │ │ ├── no-op-client.js │ │ ├── openai.js │ │ └── ratelimits.js │ ├── Logger │ │ └── logger.js │ ├── MessageBus │ │ ├── messageSchema.js │ │ └── msgBus.mjs │ ├── Util │ │ ├── BootScreen.mjs │ │ ├── Util.js │ │ └── noop.js │ ├── Vector-db │ │ └── vector-db.js │ └── lib │ │ ├── chipprAGI.png │ │ ├── splashLogo.png │ │ └── svg_20230521_153513_0000.svg ├── index.js ├── prompts │ ├── GenerateTasksPrompt.js │ ├── SystemSelectorPrompt.js │ ├── TaskExpanderPrompt.js │ └── firstTask.js └── systems │ ├── active │ ├── AmazingSystem.mjs │ ├── CoreSystemLoader.mjs │ ├── DashboardSystem.js │ ├── EntityCreationSystem.mjs │ ├── GenerateTasksSystem.mjs │ ├── SystemSelectorSystem.mjs │ ├── TaskParentSystem.mjs │ ├── TheJudgeSystem.mjs │ └── WebsocketServerSystem.mjs │ └── inactive │ ├── EmptySystem.mjs │ ├── TaskEmbeddingSystem.mjs │ ├── TaskExecutionSystem.mjs │ └── TaskExpanderSystem.mjs ├── test ├── components │ └── index.js ├── core │ ├── index.js │ ├── langModel.testold.js │ └── vector-db.testold.js ├── index.test.js ├── systems │ ├── index.js │ └── taskCreationSystem.testold.js └── testTask.json └── yarn.lock /.dockerignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # TESTING 2 | TESTING=false 3 | # CORE 4 | CHIPPRAGI_SWARM_MODE=1 5 | CHIPPRAGI_DASHBOARD=1 6 | CHIPPAGI_CORE_QUIET_BOOT=0 7 | # LOGS 8 | CHIPPRAGI_LOG_CONSOLE=1 9 | CHIPPRAGI_LOG_DEBUG=1 10 | # VECTORDB 11 | CHIPPRAGI_VECTORDB_TYPE=redis 12 | CHIPPRAGI_VECTORDB_HOST=localhost 13 | CHIPPRAGI_VECTORDB_PORT=6379 14 | # LANGUAGE_MODEL: 15 | CHIPPRAGI_LANGUAGE_MODEL_ID= # < openai, huggingface> 16 | CHIPPRAGI_LANGUAGE_MODEL_API_KEY=null 17 | CHIPPRAGI_LANGUAGE_MODEL_GENERATE_NAME= #< gpt-2, text-davinci-003> 18 | CHIPPRAGI_LANGUAGE_MODEL_EMBEDDING_NAME= # 19 | CHIPPRAGI_LANGUAGE_MODEL_DEFAULT_TEMP=0.5 20 | CHIPPRAGI_LANGUAGE_MODEL_DEFAULT_MAX=500 21 | CHIPPRAGI_LANGUAGE_MODEL_DEFAULT_MATCH_LENGTH=5, 22 | CHIPPRAGI_LANGUAGE_MODEL_RATE_LIMIT_TYPE= 23 | # MESSAGE_BUS: 24 | CHIPPRAGI_MESSAGE_BUS_TYPE=redis 25 | CHIPPRAGI_MESSAGE_BUS_WATCH=1 -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [chippr-robotics] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | # patreon: # Replace with a single Patreon username 5 | # open_collective: # Replace with a single Open Collective username 6 | # ko_fi: # Replace with a single Ko-fi username 7 | #tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | #community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | #liberapay: # Replace with a single Liberapay username 10 | #issuehunt: # Replace with a single IssueHunt username 11 | #otechie: # Replace with a single Otechie username 12 | #lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | #custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | version: 2 6 | updates: 7 | 8 | # Maintain dependencies for GitHub Actions 9 | - package-ecosystem: "github-actions" 10 | directory: "/" 11 | schedule: 12 | interval: "weekly" 13 | 14 | # Maintain dependencies for npm 15 | - package-ecosystem: "npm" 16 | directory: "/" 17 | schedule: 18 | interval: "weekly" 19 | -------------------------------------------------------------------------------- /.github/workflows/jekyll-gh-pages.yml: -------------------------------------------------------------------------------- 1 | # Sample workflow for building and deploying a Jekyll site to GitHub Pages 2 | name: Deploy Jekyll with GitHub Pages dependencies preinstalled 3 | 4 | on: 5 | # Runs on pushes targeting the default branch 6 | push: 7 | branches: ["gh-pages"] 8 | 9 | # Allows you to run this workflow manually from the Actions tab 10 | workflow_dispatch: 11 | 12 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 13 | permissions: 14 | contents: read 15 | pages: write 16 | id-token: write 17 | 18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 20 | concurrency: 21 | group: "pages" 22 | cancel-in-progress: false 23 | 24 | jobs: 25 | # Build job 26 | build: 27 | runs-on: ubuntu-latest 28 | steps: 29 | - name: Checkout 30 | uses: actions/checkout@v3 31 | - name: Setup Pages 32 | uses: actions/configure-pages@v3 33 | - name: Build with Jekyll 34 | uses: actions/jekyll-build-pages@v1 35 | with: 36 | source: ./docs 37 | destination: ./docs/_site 38 | - name: Upload artifact 39 | uses: actions/upload-pages-artifact@v1 40 | 41 | # Deployment job 42 | deploy: 43 | environment: 44 | name: github-pages 45 | url: ${{ steps.deployment.outputs.page_url }} 46 | runs-on: ubuntu-latest 47 | needs: build 48 | steps: 49 | - name: Deploy to GitHub Pages 50 | id: deployment 51 | uses: actions/deploy-pages@v2 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | 10 | # Docs 11 | docs 12 | docker 13 | 14 | # Diagnostic reports (https://nodejs.org/api/report.html) 15 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 16 | 17 | # Runtime data 18 | pids 19 | *.pid 20 | *.seed 21 | *.pid.lock 22 | 23 | # Directory for instrumented libs generated by jscoverage/JSCover 24 | lib-cov 25 | 26 | # Coverage directory used by tools like istanbul 27 | coverage 28 | *.lcov 29 | 30 | # nyc test coverage 31 | .nyc_output 32 | 33 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 34 | .grunt 35 | 36 | # Bower dependency directory (https://bower.io/) 37 | bower_components 38 | 39 | # node-waf configuration 40 | .lock-wscript 41 | 42 | # Compiled binary addons (https://nodejs.org/api/addons.html) 43 | build/Release 44 | 45 | # Dependency directories 46 | node_modules/ 47 | jspm_packages/ 48 | 49 | # TypeScript v1 declaration files 50 | typings/ 51 | 52 | # TypeScript cache 53 | *.tsbuildinfo 54 | 55 | # Optional npm cache directory 56 | .npm 57 | 58 | # Optional eslint cache 59 | .eslintcache 60 | 61 | # Microbundle cache 62 | .rpt2_cache/ 63 | .rts2_cache_cjs/ 64 | .rts2_cache_es/ 65 | .rts2_cache_umd/ 66 | 67 | # Optional REPL history 68 | .node_repl_history 69 | 70 | # Output of 'npm pack' 71 | *.tgz 72 | 73 | # Yarn Integrity file 74 | .yarn-integrity 75 | 76 | # dotenv environment variables file 77 | .env 78 | .env.test 79 | 80 | # parcel-bundler cache (https://parceljs.org/) 81 | .cache 82 | 83 | # Next.js build output 84 | .next 85 | 86 | # Nuxt.js build / generate output 87 | .nuxt 88 | dist 89 | 90 | # Gatsby files 91 | .cache/ 92 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 93 | # https://nextjs.org/blog/next-9-1#public-directory-support 94 | # public 95 | 96 | # vuepress build output 97 | .vuepress/dist 98 | 99 | # Serverless directories 100 | .serverless/ 101 | 102 | # FuseBox cache 103 | .fusebox/ 104 | 105 | # DynamoDB Local files 106 | .dynamodb/ 107 | 108 | # TernJS port file 109 | .tern-port 110 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | @chipprbots:registry = https://registry.npmjs.org 2 | //registry.npmjs.org/:_authToken=${NPM_TOKEN} -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Use the official Node.js LTS (Long Term Support) version as a parent image 2 | FROM node:lts 3 | 4 | # Set the working directory within the container 5 | WORKDIR /usr/src/app 6 | 7 | # Copy package.json and package-lock.json into the working directory 8 | COPY package*.json ./ 9 | 10 | # Install any needed dependencies 11 | RUN npm install 12 | 13 | # Bundle app source by copying the application files into the working directory 14 | COPY . . 15 | 16 | # Define the command to run the application 17 | CMD ["npm", "start"] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | ![Chippr-agi](src/core/lib/svg_20230521_153513_0000.svg) 3 | 4 | [![GitHub release (latest by date including pre-releases)](https://img.shields.io/github/v/release/chippr-robotics/chippr-agi?include_prereleases)](https://github.com/chippr-robotics/chippr-agi/releases) 5 | [![License](https://img.shields.io/badge/license-Apache%202-blue)](LICENSE) 6 | [![Discord](https://img.shields.io/discord/419537554673762306?logo=discord)](https://discord.gg/3jmFYK2QGy) 7 | [![Twitter URL](https://img.shields.io/twitter/url/https/twitter.com/chipprbots.svg?style=social&label=Follow%20%40chipprbots)](https://twitter.com/chipprbots) 8 | 9 | 10 | Chippr-AGI is an open-source event-driven ECS framework that uses AI models to automate task creation and prioritization. This system is designed to run solo or as a swarm of containers. It combines the power of LLM with actor-critic reinforcement learning to optimize the order and allocation of tasks for a given objective. 11 | 12 | 13 | 5/9 - https://docs.chipprbots.com/ is live, needs work 14 | 15 | ##### _This repo is under active development, clone often or use the latest docker image_ 16 | 17 | ## Getting Started 18 | 19 | ### Simple Demo 20 | - Clone the repository:` git clone https://github.com/chippr-robotics/chippr-agi.git` 21 | - Install the dependencies: `yarn` 22 | - Update your API keys docker-compose configuration located in `./docker/docker-compose.yml` 23 | - Update the OBJECTIVE in `./examples/simple_demo.js` 24 | - Start redis (you can use docker-compose for this) 25 | - Start the application: `yarn demo` 26 | - Monitor the vector DB at `http://localhost:8001` 27 | 28 | #### Customize 29 | Add systems and components to meet your needs then `yarn start` 30 | 31 | ### Docker( Easy ) 32 | #### Pull the Image 33 | 34 | First, pull the Chippr-AGI Docker image from Docker Hub: 35 | ``` 36 | docker pull chipprbots/chippr-agi:latest 37 | ``` 38 | 39 | #### Run the Container 40 | 41 | To run the Chippr-AGI container, you'll need to set up environment variables for your OpenAI API key and Redis credentials. Create a `.env` file by copying `.env.example` 42 | 43 | Replace `CHIPPRAGI_LANGUAGE_MODEL_API_KEY`, `CHIPPRAGI_VECTORDB_HOST`, `CHIPPRAGI_VECTORDB_PORT`, and with your actual values. 44 | 45 | Now, run the container with the following command: 46 | ``` 47 | docker run -d --name chippr-agi --env-file .env chipprbots/chippr-agi:latest 48 | ``` 49 | 50 | This will start the Chippr-AGI container in detached mode and load the environment variables from the `.env` file. 51 | 52 | ### Docker-compose (Best) 53 | #### Update the docker-compose.yml 54 | Add the value for `CHIPPRAGI_LANGUAGE_MODEL_API_KEY` to the docker-compose.yml located in `./docker` 55 | #### Create the Vector-DB and CHIPPRAGI services 56 | 57 | ``` 58 | docker-compose up 59 | ``` 60 | 61 | 62 | ## Basic Flow 63 | Chippr-AGI uses a combination of GPT-4 for generating task descriptions and actor-critic reinforcement learning to prioritize the tasks based on their estimated rewards. The framework is built using Node.js and Redis to store embeddings for quick query and update. 64 | 65 | Tasks are generated based on the current context and objective, which are passed into a customizable prompt template. The prompts are stored in a JSON file and can be easily edited to fit specific needs. Once a task is generated, its dependencies are added to the task list and prioritized based on their estimated reward. 66 | 67 | After a task is completed, the system checks if any new tasks need to be generated based on the success of the previous task. The process is repeated until all tasks are completed and the objective is achieved. 68 | 69 | ## System Flow 70 | ```mermaid 71 | graph TD 72 | A(User) -- objective --> B(EntityCreationSystem) 73 | C -- tasks, parent --> B 74 | B -- parent --> C(TaskParentSystem) 75 | B -- entity --> D(System Selection System) 76 | D -- systemselected --> F(task creator) 77 | D -- systemselected --> G(image creator) 78 | D -- systemselected --> H(internet Search) 79 | D -- systemselected --> I(task expander) 80 | F -- tasks --> B 81 | G -- taskCompleted --> J(The Judge) 82 | H -- taskCompleted --> J 83 | I -- taskCompleted --> J 84 | J --> K[task completed] 85 | K -- yes --> L(TaskCompletionSystem_TBD) 86 | K -- no --> D 87 | ``` 88 | In this flowchart: 89 | 90 | 1) The objective is provided to the system by a user (see examples/simple-demo) 91 | 2) Tasks are stored as entities with associated components. 92 | 3) An event is emitted to addSystemSelection to the task, which is handled by the System Selection system. 93 | 4) We add a component to each entity mapping it to its parent objective 94 | 5) An event is emitted to addSystemSelected the task, which is handled by the system selection system. 95 | 6) The system selection system evaulates which loaded systems can best complete the task 96 | 7) An event is emitted identifying which system will process the task 97 | 8) The task is executed based on the relevant components. 98 | 9) The result of the task is stored, and the task is marked as done. 99 | 10) The system checks if the objective is complete. 100 | 11) If the objective is not complete, an event is emitted to generate new tasks, which is handled by the Task Generation system. 101 | 102 | ## ECS events 103 | The ChipprAGI class emits an event using the EventEmitter. 104 | The EventEmitter distributes the event to all registered systems. 105 | Each system handles the event if it's relevant to that system. 106 | The system performs its specific action based on the event and updates the relevant components. 107 | This diagram shows a high-level overview of how events are propagated through the ChipprAGI system and how systems handle and react to events. 108 | 109 | ```mermaid 110 | graph TD 111 | A(ChipprAGI) -->|Emit event| B(EventEmitter) 112 | B -->|Distribute event| C(System 1) 113 | B -->|Distribute event| D(System 2) 114 | B -->|Distribute event| E(System N) 115 | C -->|Handle event| F(Perform System 1 specific action) 116 | D -->|Handle event| G(Perform System 2 specific action) 117 | E -->|Handle event| H(Perform System N specific action) 118 | F --> I(Update relevant components) 119 | G --> J(Update relevant components) 120 | H --> K(Update relevant components) 121 | 122 | ``` 123 | 124 | ## Contributing 125 | We welcome contributions from the community. If you'd like to contribute to Chippr-AGI, please fork the repository and submit a pull request. We recommend discussing your ideas with the community in the issues section before starting any major work. 126 | 127 | ## License 128 | This project is licensed under the APACHE-2.0 License. See the LICENSE file for more details. 129 | -------------------------------------------------------------------------------- /docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.7' 2 | services: 3 | chippr-agi: 4 | image: chipprbots/chippr-agi:latest 5 | deploy: 6 | replicas: 1 7 | ports: 8 | - "8082:8082" 9 | depends_on: 10 | - vector-db 11 | environment: 12 | # CORE 13 | - CHIPPRAGI_DASHBOARD=1 14 | # VECTORDB 15 | - CHIPPRAGI_VECTORDB_TYPE=redis 16 | - CHIPPRAGI_VECTORDB_HOST=vector-db 17 | - CHIPPRAGI_VECTORDB_PORT=6379 18 | # LANGUAGE_MODEL: 19 | - CHIPPRAGI_LANGUAGE_MODEL_ID=openai 20 | - CHIPPRAGI_LANGUAGE_MODEL_RATE_LIMIT_TYPE=openAI_Free 21 | #- CHIPPRAGI_LANGUAGE_MODEL_API_KEY=null 22 | # MESSAGE_BUS: 23 | - CHIPPRAGI_MESSAGE_BUS_TYPE=redis 24 | - CHIPPRAGI_MESSAGE_BUS_WATCH=1 25 | 26 | vector-db: 27 | image: redis/redis-stack 28 | ports: 29 | - "6379:6379" 30 | - "8001:8001" 31 | environment: 32 | - REDISEARCH_ARGS=CONCURRENT_WRITE_MODE 33 | volumes: 34 | - vector-db:/var/lib/redis 35 | - ./redis.conf:/usr/local/etc/redis/redis.conf 36 | healthcheck: 37 | test: ["CMD", "redis-cli", "-h", "localhost", "-p", "6379", "ping"] 38 | interval: 2s 39 | timeout: 1m30s 40 | retries: 5 41 | start_period: 5s 42 | 43 | volumes: 44 | vector-db: 45 | -------------------------------------------------------------------------------- /docker/redis.conf: -------------------------------------------------------------------------------- 1 | port 6379 2 | appendonly no 3 | save "" 4 | protected-mode no 5 | io-threads 2 -------------------------------------------------------------------------------- /docs/00_Start_here/00_WTF_is_ECS.md: -------------------------------------------------------------------------------- 1 | ## What is an Entity Component System (ECS)? 2 | Entity Component System (ECS) is an architectural pattern widely used in game development and other software systems that require managing a large number of objects with varying properties and behaviors. It promotes flexibility, modularity, and separation of concerns by organizing code into three main categories: Entities, Components, and Systems. 3 | 4 | ### Entities 5 | Entities are the basic building blocks of an ECS architecture. They are lightweight, unique identifiers that represent individual objects in your application. Entities have no logic or data attached to them; instead, they act as containers for components. 6 | 7 | ### Components 8 | Components are simple data structures that store the properties and state of an entity. They are decoupled from any logic, making them reusable and interchangeable. Components define the characteristics and attributes of an entity, such as position, velocity, or health. By combining different components, you can create a wide range of entities with varying behaviors and properties. 9 | 10 | ### Systems 11 | Systems contain the logic and functionality of your application. They are responsible for processing and updating entities with specific components. Systems operate on a set of entities that have the required components, performing tasks such as rendering, physics, or AI. By separating logic from data, systems can be modular, reusable, and easily extended. 12 | 13 | ## Why Use an ECS? 14 | ECS offers several benefits that make it an attractive choice for building complex and scalable applications: 15 | 16 | - Modularity: ECS encourages a modular design, where components and systems can be easily added, removed, or modified without affecting other parts of the application. 17 | - Separation of Concerns: By organizing code into entities, components, and systems, ECS promotes a clean separation of concerns, making the codebase easier to understand and maintain. 18 | - Performance: ECS can offer performance benefits by allowing for data-oriented design and cache-friendly memory layouts, enabling efficient processing of large numbers of entities. 19 | - Reusability: Components and systems can be reused across different entities and projects, speeding up development and reducing code duplication. -------------------------------------------------------------------------------- /docs/00_Start_here/01_Entities.md: -------------------------------------------------------------------------------- 1 | # Chippr-AGI Entity Lifecycle 2 | 3 | The lifecycle of an entity in Chippr-AGI consists of several stages, including creation, component addition and removal, updating, and deletion. This document will guide you through each stage, describing the processes involved and the interactions between entities, components, and systems in the Chippr-AGI architecture. 4 | 5 | ## 1. Entity Creation 6 | 7 | Entities are created as lightweight, unique identifiers representing individual objects in the Chippr-AGI system. An entity can *be* anything(a task, an objective, a thought) since everything is an entity; an entities *components* define what it is. To create a new entity, follow these steps: 8 | 9 | 1. Instantiate a new entity by assigning a unique identifier (e.g., UUID) using the `ChipprAGI.createEntity()` method. 10 | 2. Add the necessary components to define the entity's properties and behaviors (see Component Addition below). 11 | 12 | ```javascript 13 | const entityId = ChipprAGI.createEntity(); 14 | ``` 15 | 16 | ## 2. Component Addition 17 | 18 | Components store the properties and state of an entity. To add a component to an entity, use the `ChipprAGI.addComponent(entityId, componentName, componentData)` method, passing the entity ID, the name of the component, and an object containing the component's data. 19 | 20 | ```javascript 21 | ChipprAGI.addComponent(entityId, 'TaskDescription', { task: 'some task description', reward: 5 }); 22 | ``` 23 | 24 | When a component is added to an entity, the following actions occur: 25 | 26 | 1. The component data is attached to the entity. 27 | 2. The `init()` method of the component (if defined) is called, allowing for component-specific initialization. 28 | 3. An event is emitted to notify relevant systems of the component addition (e.g., `componentAdded:TaskDescription`). 29 | 30 | Systems that have registered event listeners for the specific component addition event can react accordingly, updating their internal state or processing the entity as needed. 31 | 32 | ## 3. Updating Entities 33 | 34 | Entities are updated by *systems* that process and modify their *components*. Each *system* operates on a set of *entities* with *specific component requirements*. To update entities, follow these steps: 35 | 36 | 1. Register systems to the main Chippr-AGI class using the `ChipprAGI.registerSystem(systemName, systemDefinition)` method. 37 | 2. Implement the `update()` method in each system, processing entities with the required components. 38 | 39 | ```javascript 40 | ChipprAGI.registerSystem('TaskExecutionSystem', { 41 | update: function () { 42 | // Process entities with the required components 43 | }, 44 | }); 45 | ``` 46 | 47 | Systems are executed in the order they are registered, ensuring that dependencies between systems are properly managed. 48 | 49 | ## 4. Component Removal 50 | 51 | Components can be removed from entities using the `ChipprAGI.removeComponent(entityId, componentName)` method, passing the entity ID and the name of the component to remove. 52 | 53 | ```javascript 54 | ChipprAGI.removeComponent(entityId, 'TaskDescription'); 55 | ``` 56 | 57 | When a component is removed from an entity, the following actions occur: 58 | 59 | 1. The `remove()` method of the component (if defined) is called, allowing for component-specific cleanup. 60 | 2. The component data is detached from the entity. 61 | 3. An event is emitted to notify relevant systems of the component removal (e.g., `componentRemoved:TaskDescription`). 62 | 63 | Systems that have registered event listeners for the specific component removal event can react accordingly, updating their internal state or ceasing to process the entity as needed. 64 | 65 | ## 5. Entity Deletion 66 | 67 | Entities can be deleted using the `ChipprAGI.deleteEntity(entityId)` method, passing the entity ID to delete. 68 | 69 | ```javascript 70 | ChipprAGI.deleteEntity(entityId); 71 | ``` 72 | 73 | When an entity is deleted, the following actions occur: 74 | 75 | 1. All components are removed from the entity (see Component Removal above). 76 | 2. The entity is removed from the Chippr-AGI system. 77 | 3. An event is emitted to3. An event is emitted to notify relevant systems of the entity deletion (e.g., `entityDeleted`). 78 | 79 | Systems that have registered event listeners for the specific entity deletion event can react accordingly, updating their internal state or ceasing to process the entity as needed. 80 | 81 | ## Summary 82 | 83 | In Chippr-AGI, entities have a clear lifecycle that involves creation, component addition and removal, updating, and deletion. By understanding and following these stages, you can effectively manage the interactions between entities, components, and systems within the Chippr-AGI architecture. 84 | 85 | Remember to always update entities through their components and leverage the event-driven nature of the system to ensure that relevant systems are aware of changes in entities and components. This approach will help maintain a flexible and modular architecture, allowing for easy addition and removal of components and systems as needed. -------------------------------------------------------------------------------- /docs/00_Start_here/02_Events.md: -------------------------------------------------------------------------------- 1 | # Event-Driven Architecture in Chippr-AGI 2 | 3 | Event-driven architecture is a design pattern that promotes loose coupling and effective communication between different parts of an application. In Chippr-AGI, this architecture is used to manage interactions between systems and components while maintaining a modular and scalable structure. 4 | 5 | ## The Basics of Event-Driven Architecture 6 | 7 | In an event-driven architecture, events are the primary mechanism for communication between different parts of the application. An event is a message that represents something that has happened, such as a change in state or the completion of a task. Events are produced by one part of the application and consumed by another, often without any direct knowledge of each other's existence. 8 | 9 | Here are the key aspects of event-driven architecture: 10 | 11 | 1. **Event Producers:** Components or systems that create and emit events when a specific action occurs or a state change happens. 12 | 2. **Event Consumers:** Components or systems that listen for and react to events, usually by performing a specific action or updating their internal state. 13 | 3. **Event Bus:** A central communication channel that allows events to be passed between producers and consumers without them needing to be directly connected. 14 | 15 | ## Life Cycle of an Event 16 | 17 | The life cycle of an event in Chippr-AGI consists of the following stages: 18 | 19 | 1. **Event Creation:** An event is created by an event producer when a specific action occurs or a state change happens. The event contains relevant information about what has occurred, such as the entity ID or any additional data needed for processing. 20 | 21 | ```mermaid 22 | graph LR 23 | A(Event Creation) --> B(Event Emission) 24 | ``` 25 | 26 | 2. **Event Emission:** The event producer emits the event, sending it to the event bus. 27 | 28 | ```mermaid 29 | graph LR 30 | B(Event Emission) --> C(Event Distribution) 31 | ``` 32 | 33 | 3. **Event Distribution:** The event bus distributes the event to all registered event consumers that have expressed interest in the specific event type. This allows multiple systems to react to the same event independently. 34 | 35 | ```mermaid 36 | graph LR 37 | C(Event Distribution) --> D1(Event Processing System A) 38 | C --> D2(Event Processing System B) 39 | C --> D3(Event Processing System C) 40 | ``` 41 | 42 | 4. **Event Processing:** Event consumers process the event, performing actions or updating their internal state as needed. The event processing stage is usually asynchronous and can happen in parallel across multiple systems. 43 | 44 | ```mermaid 45 | graph LR 46 | D1(Event Processing System A) --> E1(Update State/System A) 47 | D2(Event Processing System B) --> E2(Update State/System B) 48 | D3(Event Processing System C) --> E3(Update State/System C) 49 | ``` 50 | 51 | 5. **Update State/System:** Once the event has been processed, the event consumer updates its internal state or performs other actions as necessary, completing the life cycle of the event. 52 | 53 | By understanding the life cycle of events in Chippr-AGI, you can effectively manage communication between systems and components, ensuring that your application remains modular, scalable, and easy to maintain. -------------------------------------------------------------------------------- /docs/00_Start_here/03_Systems.md: -------------------------------------------------------------------------------- 1 | # Systems in Chippr-AGI 2 | 3 | Systems in Chippr-AGI are the primary building blocks responsible for handling the logic and processing related to specific tasks or functionalities. They work in tandem with components to define the behavior of the application, forming a crucial part of the Entity-Component-System (ECS) architecture. 4 | 5 | ## Life Cycle of a System 6 | 7 | The life cycle of a system in Chippr-AGI consists of several stages: 8 | 9 | 1. **Initialization:** The system is registered with the Chippr-AGI core using `CHIPPRAGI.registerSystem()`. The `init` function is called, allowing the system to set up event listeners or perform any necessary setup. 10 | 11 | ```mermaid 12 | graph TB 13 | A(Initialization) --> B(Update) 14 | ``` 15 | 16 | 2. **Update:** As the application runs, the system listens for and processes events. When an event is received, the system's `update` function is called, allowing it to handle changes in component data or perform any required actions. 17 | 18 | ```mermaid 19 | graph TB 20 | B(Update) --> C(updateEventHandler) --> D(components Updated) --> B 21 | ``` 22 | 23 | 3. **Remove:** When a component or its associated entity is removed, the system's `remove` function is called, allowing it to clean up any resources or perform necessary actions. 24 | 25 | 4. **Tick:** The system's `tick` function is called on every scene tick or frame, providing an opportunity to perform any continuous or time-dependent actions. 26 | 27 | ## Purpose of Systems 28 | 29 | Systems in Chippr-AGI serve the following purposes: 30 | 31 | 1. **Handle Events:** Systems listen for and process events related to their specific functionality, such as updating component data, performing calculations, or managing interactions between components. 32 | 33 | 2. **Encapsulate Logic:** Systems contain the logic required to perform tasks or manage specific parts of the application, keeping the code modular and easier to maintain. 34 | 35 | 3. **Interact with Components:** Systems work with components to define the behavior of entities, providing a dynamic and flexible way to manage application state. 36 | 37 | ## Differences Between Systems and Components 38 | 39 | Systems and components are both essential parts of the ECS architecture, but they serve distinct roles: 40 | 41 | 1. **Systems** are responsible for processing logic, handling events, and managing interactions between components. They define the behavior and functionality of the application. 42 | 43 | 2. **Components** are data containers that store information about entities, such as properties or attributes. They do not contain any logic and are used to describe the state of an entity. 44 | 45 | In Chippr-AGI, systems and components work together to create a modular and scalable application structure, allowing you to build complex applications with ease. -------------------------------------------------------------------------------- /docs/00_Start_here/04_Components.md: -------------------------------------------------------------------------------- 1 | # Components in Chippr-AGI 2 | 3 | Components in Chippr-AGI are the fundamental data structures that define the properties and attributes of entities within the Entity-Component-System (ECS) architecture. They work in conjunction with systems to create the behavior and functionality of the application. 4 | 5 | ## Life Cycle of a Component 6 | 7 | The life cycle of a component in Chippr-AGI consists of several stages: 8 | 9 | 1. **Initialization:** The component is registered with the Chippr-AGI core using `CHIPPRAGI.registerComponent()`. The `init` function is called, allowing the component to perform any necessary setup or data initialization. 10 | 11 | 12 | 2. **Update:** When the data within the component changes, the `update` function is called. This provides an opportunity to perform any actions or update any internal state based on the new data. 13 | 14 | 15 | 16 | 3. **Remove:** When a component is removed from an entity or the entity itself is removed, the `remove` function is called. This allows the component to clean up any resources or perform any necessary actions. 17 | 18 | ## Purpose of Components 19 | 20 | Components in Chippr-AGI serve the following purposes: 21 | 22 | 1. **Store Data:** Components act as data containers, storing information about entities such as properties or attributes. They do not contain any logic themselves. 23 | 24 | 2. **Describe Entities:** Components are used to define the state and characteristics of entities within the ECS architecture. By attaching components to an entity, you define what the entity represents and how it behaves within the application. 25 | 26 | 3. **Enable Flexibility and Modularity:** Components allow for a flexible and modular application structure. By combining different components, you can create a wide variety of entities with unique behaviors and attributes, without the need for complex inheritance hierarchies. 27 | 28 | ## Relationship Between Components and Entities 29 | 30 | Components and entities have a close relationship within the ECS architecture: 31 | 32 | 1. **Entity Composition:** Entities are composed of one or more components, which define their properties and attributes. By attaching different components to an entity, you can create a wide range of unique entities with varying behaviors and characteristics. 33 | 34 | 2. **Entity Behavior:** The behavior of an entity is determined by the components it is composed of and the systems that interact with those components. Systems use the data stored in components to perform calculations, manage interactions, and update the application state. 35 | 36 | 3. **Entity Identification:** Components can be used to identify and categorize entities based on their properties and attributes. By querying entities based on their components, you can efficiently find and manage specific entities within your application. 37 | 38 | In Chippr-AGI, components play a crucial role in defining the structure and behavior of entities, providing a scalable and modular framework for building complex applications. -------------------------------------------------------------------------------- /docs/00_Start_here/05_Prompts.md: -------------------------------------------------------------------------------- 1 | # Prompts in Chippr-AGI 2 | 3 | Prompts are an essential part of Chippr-AGI, as they provide a way for systems to generate events, components, and entities based on user input or other external sources of information. They act as the bridge between the application and the outside world, allowing systems to adapt and respond to changes in the environment or user requirements. 4 | 5 | ## How Prompts Work 6 | 7 | In Chippr-AGI, prompts are used by systems to request information or actions to be taken. A system will use a prompt to generate a natural language query, which is then sent to a language model such as GPT-4. The language model processes the query and returns a response, which the system can then interpret and use to update the application state or create new events, components, and entities. 8 | 9 | ## Prompts and Events 10 | 11 | Prompts can be used to create events within the application. When a system receives a response from a language model, it can use the information to generate events that will trigger actions or updates within the ECS architecture. For example, a system might use a prompt to request the creation of a new entity, and the language model's response might provide the necessary information to create an event that will initialize the new entity and its components. 12 | 13 | ## Prompts and Components 14 | 15 | Prompts can also be used to create or update components within the application. When a system needs to update the state of a component, it can use a prompt to request the necessary information from a language model. The response can then be used to update the component's data, which might trigger an update in the system that manages the component. This allows systems to adapt and respond to changes in the environment or user requirements dynamically. 16 | 17 | ## Prompts and Entities 18 | 19 | Prompts can play a vital role in the creation and management of entities within the ECS architecture. Systems can use prompts to request information about new entities or updates to existing entities, and the language model's response can be used to create or modify the entities and their components. By using prompts, systems can create a dynamic and adaptable application that can respond to changes in the environment or user requirements in real-time. 20 | 21 | In summary, prompts are a powerful tool within Chippr-AGI that enables systems to interact with the outside world and adapt to changes in the environment or user requirements. By using prompts, systems can create events, components, and entities based on the responses from language models, allowing for a flexible and dynamic application structure. -------------------------------------------------------------------------------- /docs/01_hello_chippr_agi/01_introduction.md: -------------------------------------------------------------------------------- 1 | # Creating a Basic Entity with Two Components in ChipprAGI: A Walkthrough 2 | 3 | ## Introduction 4 | 5 | Welcome to this ChipprAGI walkthrough! In this tutorial, we will demonstrate how to create a basic entity with two components, providing you with a hands-on understanding of ChipprAGI's capabilities. By the end of this tutorial, you will have a solid foundation in creating and managing entities, components, and systems within the ChipprAGI framework. 6 | 7 | In this walkthrough, we will create an entity representing a simple task with a title and description. The entity will have two components: 8 | 9 | 1. **TaskTitleComponent**: This component will store the task's title and provide a method to update it. 10 | 2. **TaskDescriptionComponent**: This component will store the task's description and provide a method to update it. 11 | 12 | Throughout the tutorial, we will guide you through the process of creating the entity and its components, setting up the system to manage the entity, and interacting with the entity to update its properties. By following this step-by-step guide, you will gain valuable experience in using ChipprAGI for your own projects. 13 | 14 | Let's dive in and create our first ChipprAGI entity with two components! 15 | 16 | ## Editors note: Proceed with caution, I have not reviewed this yet. -------------------------------------------------------------------------------- /docs/01_hello_chippr_agi/02_Setting_up.md: -------------------------------------------------------------------------------- 1 | # 2. Setting up the Project 2 | 3 | Before we start creating our entity and its components, let's set up the project by following the steps below. 4 | 5 | ## 2.1. Prerequisites 6 | 7 | Ensure you have the following installed on your machine: 8 | 9 | - Node.js (v14 or higher) 10 | - npm (v6 or higher) 11 | - A code editor (e.g., Visual Studio Code) 12 | 13 | ## 2.2. Create a New Project 14 | 15 | 1. Open your terminal and navigate to the directory where you want to create the project. 16 | 17 | 2. Run the following command to create a new directory called `chippr-agi-tutorial` and navigate to it: 18 | 19 | ``` 20 | mkdir chippr-agi-tutorial && cd chippr-agi-tutorial 21 | ``` 22 | 23 | 3. Initialize the project by running the following command: 24 | 25 | ``` 26 | npm init -y 27 | ``` 28 | 29 | This will create a `package.json` file in the project directory with default values. 30 | 31 | ## 2.3. Install Dependencies 32 | 33 | We need to install ChipprAGI as a dependency for our project. Run the following command in your terminal: 34 | 35 | ``` 36 | npm install chippr-agi 37 | ``` 38 | 39 | ## 2.4. Create Project Structure 40 | 41 | Create the following directory structure for the project: 42 | 43 | ``` 44 | chippr-agi-tutorial/ 45 | │ 46 | ├── src/ 47 | │ ├── components/ 48 | │ ├── entities/ 49 | │ └── systems/ 50 | │ 51 | ├── package.json 52 | └── .gitignore 53 | ``` 54 | 55 | You can create these directories and files manually or use the terminal: 56 | 57 | ``` 58 | mkdir src && mkdir src/components src/entities src/systems 59 | touch .gitignore 60 | ``` 61 | 62 | Add the following to your `.gitignore` file: 63 | 64 | ``` 65 | node_modules/ 66 | ``` 67 | 68 | ## 2.5. ChipprAGI Configuration 69 | 70 | In your `src` directory, create a new file called `main.js`. This file will serve as the entry point for our project and will configure ChipprAGI. 71 | 72 | Paste the following code into `main.js`: 73 | 74 | ```javascript 75 | import { ChipprAGI } from 'chippr-agi'; 76 | 77 | // Initialize ChipprAGI 78 | const chipprAGI = new ChipprAGI(); 79 | 80 | // Load systems and components 81 | chipprAGI.loadSystems('./systems/'); 82 | chipprAGI.loadComponents('./components/'); 83 | 84 | // Start ChipprAGI 85 | chipprAGI.start(); 86 | ``` 87 | 88 | Now that our project is set up, we can proceed to create our entity, components, and systems. 89 | ``` 90 | -------------------------------------------------------------------------------- /docs/01_hello_chippr_agi/03_Create_components.md: -------------------------------------------------------------------------------- 1 | # 3. Creating the Components 2 | 3 | In this section, we will create two components for our entity. Let's assume we are creating an entity that represents a simple task with a title and a status. 4 | 5 | ## 3.1. TaskTitle Component 6 | 7 | Create a new file called `TaskTitle.js` inside the `src/components/` directory and add the following code: 8 | 9 | ```javascript 10 | import { CHIPPRAGI } from 'chippr-agi'; 11 | 12 | CHIPPRAGI.registerComponent('TaskTitle', { 13 | schema: { 14 | title: { type: 'string', default: 'Untitled Task' }, 15 | }, 16 | 17 | init: function() { 18 | // Do something when the component is first attached 19 | }, 20 | 21 | update: function() { 22 | // Do something when the component's data is updated 23 | }, 24 | 25 | remove: function() { 26 | // Do something when the component or its entity is detached 27 | }, 28 | }); 29 | ``` 30 | 31 | This component has a single property called `title` of type `string` with a default value of 'Untitled Task'. 32 | 33 | ## 3.2. TaskStatus Component 34 | 35 | Create a new file called `TaskStatus.js` inside the `src/components/` directory and add the following code: 36 | 37 | ```javascript 38 | import { CHIPPRAGI } from 'chippr-agi'; 39 | 40 | CHIPPRAGI.registerComponent('TaskStatus', { 41 | schema: { 42 | status: { type: 'string', default: 'Incomplete' }, 43 | }, 44 | 45 | init: function() { 46 | // Do something when the component is first attached 47 | }, 48 | 49 | update: function() { 50 | // Do something when the component's data is updated 51 | }, 52 | 53 | remove: function() { 54 | // Do something when the component or its entity is detached 55 | }, 56 | }); 57 | ``` 58 | 59 | This component has a single property called `status` of type `string` with a default value of 'Incomplete'. 60 | 61 | With both components created, we can now proceed to create an entity that uses these components. 62 | ``` 63 | -------------------------------------------------------------------------------- /docs/01_hello_chippr_agi/04_creating_Entity.md: -------------------------------------------------------------------------------- 1 | # 4. Creating an Entity with Components 2 | 3 | Now that we have created our components, let's create an entity that uses the `TaskTitle` and `TaskStatus` components. We will also create a system to manage the task entities. 4 | 5 | ## 4.1. Creating a Task Entity 6 | 7 | In the `src/` directory, create a new file called `createTaskEntity.js` and add the following code: 8 | 9 | ```javascript 10 | import { CHIPPRAGI } from 'chippr-agi'; 11 | 12 | export function createTaskEntity(title, status) { 13 | // Create a new entity 14 | const entity = CHIPPRAGI.createEntity(); 15 | 16 | // Add the TaskTitle component to the entity 17 | CHIPPRAGI.addComponent(entity, 'TaskTitle', { title }); 18 | 19 | // Add the TaskStatus component to the entity 20 | CHIPPRAGI.addComponent(entity, 'TaskStatus', { status }); 21 | 22 | // Return the created entity 23 | return entity; 24 | } 25 | ``` 26 | 27 | This function takes a `title` and `status` as arguments and creates a new entity with the `TaskTitle` and `TaskStatus` components. 28 | 29 | ## 4.2. Creating a Task System 30 | 31 | Create a new file called `TaskSystem.js` inside the `src/systems/` directory and add the following code: 32 | 33 | ```javascript 34 | import { CHIPPRAGI } from 'chippr-agi'; 35 | 36 | CHIPPRAGI.registerSystem('TaskSystem', { 37 | info: { 38 | version: "1.0.0", 39 | license: "Apache-2.0", 40 | developer: "Your Name", 41 | description: "A system to manage task entities", 42 | }, 43 | 44 | init: function() { 45 | // Initialize the system 46 | }, 47 | 48 | update: function(entityId, componentData) { 49 | // Handle updates to the entity's components 50 | }, 51 | 52 | remove: function(entityId) { 53 | // Handle the removal of the entity or its components 54 | }, 55 | 56 | tick: function(entityId, time, timeDelta) { 57 | // Handle tasks on every tick or frame 58 | }, 59 | }); 60 | 61 | ``` 62 | 63 | This system will be responsible for managing task entities and their related components. 64 | 65 | Now you have a working example of creating an entity with two components and a system to manage them. You can further expand this example to add more functionality, such as updating the task status, deleting tasks, or handling task-related events. 66 | ``` -------------------------------------------------------------------------------- /docs/01_hello_chippr_agi/05_Final_steps.md: -------------------------------------------------------------------------------- 1 | # 5. Final Steps and Testing 2 | 3 | After creating the components, entity, and system, we can now test our basic example to ensure everything works as expected. 4 | 5 | ## 5.1. Using the createTaskEntity Function 6 | 7 | In your `src/index.js` file, import the `createTaskEntity` function and create a new task entity with a title and status: 8 | 9 | ```javascript 10 | import { createTaskEntity } from './createTaskEntity'; 11 | 12 | const taskEntity = createTaskEntity('My First Task', 'In Progress'); 13 | console.log(`Created task entity: ${taskEntity}`); 14 | ``` 15 | 16 | ## 5.2. Running the Project 17 | 18 | In your terminal, navigate to your project folder and run the following command: 19 | 20 | ```bash 21 | npm start 22 | ``` 23 | 24 | This command will start your project, and you should see output similar to the following: 25 | 26 | ``` 27 | Created task entity: 1 28 | ``` 29 | 30 | This confirms that your project is set up correctly, and you have successfully created an entity with the `TaskTitle` and `TaskStatus` components. 31 | 32 | ## 5.3. Expanding the Example 33 | 34 | Now that you have a basic understanding of how to create entities, components, and systems in Chippr-AGI, you can expand this example to include more functionality, such as: 35 | 36 | - Adding more components or systems to manage different aspects of the tasks. 37 | - Implementing events to handle task-related actions, such as updating the status or deleting tasks. 38 | - Integrating the example with a storage system, such as a database, to persist task information. 39 | 40 | The possibilities are endless, and the flexible nature of the ECS architecture allows you to easily expand your project as needed. 41 | ``` 42 | 43 | With this walk-through, users will be able to understand the basics of Chippr-AGI, create simple components, entities, and systems, and start exploring the full potential of the ECS architecture. -------------------------------------------------------------------------------- /docs/02_Examples/00_hello_system.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chippr-robotics/chippr-agi/5420cae80d804c905916a1bb151189f25761d709/docs/02_Examples/00_hello_system.md -------------------------------------------------------------------------------- /docs/02_Examples/ECS.md: -------------------------------------------------------------------------------- 1 | ```mermaid 2 | graph TB 3 | A[Objective] 4 | A --> B[Generate Initial Tasks] 5 | B --> C[Store Tasks as Entities with Components] 6 | C --> D[Emit Event to Prioritize Tasks] 7 | D -->|Event| E[System: Task Prioritization] 8 | E --> F[Update Task Priorities] 9 | F --> G[Emit Event to Execute Next Task] 10 | G -->|Event| H[System: Task Execution] 11 | H --> I[Execute Task based on Components] 12 | I --> J[Store Task Result] 13 | J --> K[Mark Task as Done] 14 | K --> L[Check if Objective is Complete] 15 | L -->|No| M[Emit Event to Generate New Tasks] 16 | M -->|Event| N[System: Task Generation] 17 | N --> O[Generate New Tasks based on Components] 18 | O --> P[Store New Tasks as Entities with Components] 19 | P --> D 20 | L -->|Yes| Q[Objective Complete] 21 | 22 | ``` 23 | In this flowchart: 24 | 25 | The objective is used to generate the initial tasks. 26 | Tasks are stored as entities with associated components. 27 | An event is emitted to prioritize tasks, which is handled by the Task Prioritization system. 28 | Task priorities are updated based on the system's logic. 29 | An event is emitted to execute the next task, which is handled by the Task Execution system. 30 | The task is executed based on the relevant components. 31 | The result of the task is stored, and the task is marked as done. 32 | The system checks if the objective is complete. 33 | If the objective is not complete, an event is emitted to generate new tasks, which is handled by the Task Generation system. 34 | New tasks are generated based on the components and the previous task's result. 35 | The new tasks are stored as entities with components, and the process repeats from step 3. -------------------------------------------------------------------------------- /docs/02_Examples/WeatherComponent.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../index.js"; 2 | 3 | CHIPPRAGI.registerComponent('WeatherComponent', { 4 | schema: { 5 | locationName: { type: 'string', default: '' }, 6 | weatherDescription: { type: 'string', default: '' }, 7 | temperature: { type: 'number', default: null }, 8 | }, 9 | }); 10 | -------------------------------------------------------------------------------- /docs/02_Examples/WeatherSystem.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../index.js"; 2 | import axios from 'axios'; 3 | 4 | CHIPPRAGI.registerSystem('WeatherCheckSystem', { 5 | info: { 6 | version : "0.1.0", 7 | license : "APACHE_2", 8 | developer: "Chippr", 9 | description : "This system makes an external call to get the weather and updates one or all entities", 10 | }, 11 | 12 | init: function (_eventEmitter) { 13 | _eventEmitter.on('checkWeather', (data) => { 14 | this.handleCheckWeather(data); 15 | }); 16 | _eventEmitter.on('updateAllWeatherComponents', (data) => { 17 | this.updateAllWeatherComponents(data); 18 | }); 19 | }, 20 | 21 | handleCheckWeather: async function (entityId, zipCode) { 22 | const apiKey = process.env.OPENWEATHERMAP_API_KEY; 23 | const url = `http://api.openweathermap.org/data/2.5/weather?zip=${zipCode}&appid=${apiKey}&units=imperial`; 24 | 25 | try { 26 | const response = await axios.get(url); 27 | const weatherData = response.data; 28 | 29 | // Update the WeatherComponent of the specified entity 30 | CHIPPRAGI.updateComponent(entityId, 'WeatherComponent', { 31 | locationName: weatherData.name, 32 | weatherDescription: weatherData.weather[0].description, 33 | temperature: weatherData.main.temp, 34 | }); 35 | } catch (error) { 36 | console.error('Error fetching weather data:', error); 37 | } 38 | }, 39 | 40 | updateAllWeatherComponents: async function () { 41 | // Get all entities with a WeatherComponent 42 | const entitiesWithWeather = CHIPPRAGI.queryEntities({ hasComponent: 'WeatherComponent' }); // need list function in the vectordb 43 | 44 | // Update the weather data for each entity 45 | for (const entityId of entitiesWithWeather) { 46 | const entity = CHIPPRAGI.getComponent(entityId, 'WeatherComponent'); 47 | const weatherComponent = entity.WeatherComponent; 48 | 49 | if (weatherComponent && weatherComponent.zipCode) { 50 | await this.handleCheckWeather(entityId, weatherComponent.zipCode); 51 | } 52 | } 53 | }, 54 | }); 55 | -------------------------------------------------------------------------------- /docs/20230521_152433_0000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chippr-robotics/chippr-agi/5420cae80d804c905916a1bb151189f25761d709/docs/20230521_152433_0000.png -------------------------------------------------------------------------------- /docs/20230521_152500_0000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chippr-robotics/chippr-agi/5420cae80d804c905916a1bb151189f25761d709/docs/20230521_152500_0000.png -------------------------------------------------------------------------------- /docs/20230521_152815_0000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chippr-robotics/chippr-agi/5420cae80d804c905916a1bb151189f25761d709/docs/20230521_152815_0000.png -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | docs.chipprbots.com -------------------------------------------------------------------------------- /docs/Core_Systems/DemoFlow.md: -------------------------------------------------------------------------------- 1 | ## System Flow 2 | ```mermaid 3 | graph TD 4 | A(User) -- objective --> B(EntityCreationSystem) 5 | C -- tasks, parent --> B 6 | B -- parent --> C(TaskParentSystem) 7 | B -- entity --> D(System Selection System) 8 | D -- systemselected --> F(task creator) 9 | D -- systemselected --> G(image creator) 10 | D -- systemselected --> H(internet Search) 11 | D -- systemselected --> I(task expander) 12 | F -- tasks --> B 13 | G -- taskCompleted --> J(The Judge) 14 | H -- taskCompleted --> J 15 | I -- taskCompleted --> J 16 | J --> K[task completed] 17 | K -- yes --> L(TaskCompletionSystem_TBD) 18 | K -- no --> D 19 | 20 | -------------------------------------------------------------------------------- /docs/Core_Systems/Message_Bus.md: -------------------------------------------------------------------------------- 1 | ## The Message bus 2 | 3 | ChipprAGI uses a pubsub system 4 | 5 | The system topics are: 6 | 7 | | SYSTEM | topics from systems 8 | | UPDATE | Used to update components and systems with update functions 9 | | REMOVE | used to remove systems and components 10 | | TICK | system generated tick events 11 | | PAUSE | system generated pause events 12 | 13 | 14 | Schema for message objects 15 | 16 | ``` 17 | { 18 | "version": "1.0.0", 19 | "eventType": "taskExecution", 20 | "payload": { 21 | "entityId": "123", 22 | "componentName": "TaskDescription", 23 | "data": {} 24 | }, 25 | "metadata": { 26 | "timestamp": "1633028743789" 27 | } 28 | } 29 | ``` 30 | 31 | To use the message Schema in a system, import the following: 32 | 33 | ``` 34 | 35 | // Use the message schema to create a new message 36 | let newMessage = { ...CHIPPRAGI.MessageBus.MessageSchema }; 37 | 38 | // Update the relevant fields for the new message 39 | newMessage.eventType = 'newEntity'; 40 | newMessage.payload.entityID = _entityID; 41 | newMessage.payload.component = 'SomeComponent'; 42 | // ... and so on 43 | CHIPPRAGI.publish('SYSTEM', [newMessage]); 44 | ``` -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | ### Entities: 2 | Continue using tasks as entities in your system. Each task will have a unique task_id, which you already generate using the first 10 bytes of the SHA256 hash of the task string. 3 | 4 | ### Components: 5 | Break down the data related to tasks into components. Based on the provided prompts, you can have components like: 6 | 7 | - TaskDescription 8 | - TaskReward 9 | - TaskStatus (done) 10 | - TaskDependencies 11 | - TaskState 12 | - TaskAction 13 | - TaskActionProbability 14 | - TaskNextState 15 | - TaskRewardForAction 16 | 17 | ### Systems: 18 | Create systems to handle the logic for your tasks. Based on the current workflow, we can create the following systems: 19 | 20 | - TaskExecutionSystem: Handles the execution of the task based on the current state and active task. You can utilize the execution_prompt to generate the AI response and update the task state accordingly. 21 | - TaskCreationSystem: Handles the creation of new tasks using the task_prompt. This system can generate new tasks based on the objective, last completed task, and incomplete tasks. It will also estimate rewards and probabilities for the new tasks. 22 | - TaskDependencySystem: Manages the dependencies between tasks to ensure that they are completed in the correct order. 23 | - TaskPrioritySystem: Prioritizes tasks based on their estimated rewards and other factors, like dependencies. 24 | - Storing Components: You mentioned that you're using Redis to store tasks and their embeddings. You can continue to do so, but you'll need to adapt your storage to accommodate the new component-based structure. Each component should be stored independently in Redis, using a unique key that combines the task_id and the component type, e.g., taskid:TaskDescription. This will allow you to efficiently access and update specific components as needed. 25 | 26 | ### Updating Prompts: 27 | Modify the YAML prompts to reflect the changes in the architecture. When you use a prompt, replace the variables with the corresponding components, e.g., {{ activeTask }} should be replaced with the TaskDescription component for the current task. -------------------------------------------------------------------------------- /docs/chipprAGI_v1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chippr-robotics/chippr-agi/5420cae80d804c905916a1bb151189f25761d709/docs/chipprAGI_v1.png -------------------------------------------------------------------------------- /docs/dev_updates.md: -------------------------------------------------------------------------------- 1 | 2 | 5/4 - Added huggingface api support. use with caution for now. 3 | 4 | 5/2 - 5 | Working to the next release. The system is stable. Core functions like logging, language model, pubsub are all working. The websocket system works for frontend integration. Everything can be run using yarn commands now also. 6 | 7 | Haven't had time to work on front end much, @chippr-robotics repo has a template for a vr frontend when I get some cycles... 8 | 9 | Updates: 10 | - Add "build" to package.json 11 | - ch default messageBus to to redis 12 | - add task expander 13 | - sss is now generating lists 14 | - Created a ratelimiting queue for language model requests 15 | - add Rate limits type to splash screen 16 | - add error logging to generate calls 17 | 18 | 4/28 19 | - working logging system 20 | - working docker image 21 | - working docker-compose 22 | 23 | 4/21 24 | cleaned up a lot of the formating and schemas 25 | core functionality of ecs is working with redis 26 | need distrubuted message bus 27 | add quick start to readme 28 | 29 | 30 | 4/20 31 | - [x] v1 >> ecs 32 | - [x] add testing framework (mocha) 33 | - [x] allow distrubuted task handeling(swarm mode) 34 | - [x] functional core system loader 35 | - [ ] All core systems and componens 36 | - [x] Docker container. 37 | - [x] Docker compose w/ redis 38 | - [x] Jenkins pipelines 39 | - [x] Distrubuted message bus system 40 | - [ ] Better Documentation *I am working on updating documentation friday and saturday. 41 | 42 | -------------------------------------------------------------------------------- /examples/simple_demo.js: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../src/index.js"; 2 | import * as dotenv from 'dotenv'; 3 | dotenv.config(); 4 | 5 | const OBJECTIVE = "Write the worlds greatest robot detective novel." 6 | 7 | setTimeout(()=> { 8 | //_eventType, _entityID, _componentName, _sourceSystem, _data 9 | CHIPPRAGI.MessageBus.updateMessage( 'createEntity', '0000000000', 'ObjectiveDescription', {}, { 10 | task : OBJECTIVE, 11 | }); 12 | CHIPPRAGI.Logger.info({ log : "Creating test objective", system: "Simple-Demo"}); 13 | },10000); 14 | -------------------------------------------------------------------------------- /examples/websocket_demo.js: -------------------------------------------------------------------------------- 1 | import { WebSocket } from "ws"; 2 | 3 | var socket = new WebSocket("ws://localhost:8082"); 4 | const entities = []; 5 | const components = []; 6 | 7 | 8 | socket.onmessage = (event) => { 9 | const message = JSON.parse(event.data); 10 | console.log(message); 11 | switch(message.type){ 12 | case "allEntities": 13 | console.log("Received all entities with components:", message.data); 14 | message.data.forEach(element => { 15 | components.forEach( component => { 16 | socket.send(JSON.stringify({ type: "getComponent", entityID : element, componentName : component })); 17 | }); 18 | }); 19 | break; 20 | case "allComponents": 21 | //console.log("Received all components:", message.data); 22 | for (var i in message.data[0]){ 23 | if (components.includes(i) != true) components.push(i); 24 | }; 25 | console.log(`component list: ${components}`); 26 | break; 27 | case "entityDetail": 28 | console.log("Received entity detail:", message.data); 29 | } 30 | }; 31 | 32 | setInterval(()=> { 33 | socket.send(JSON.stringify({ type: "getAllEntities" })); 34 | }, 5000); 35 | 36 | setInterval(()=> { 37 | socket.send(JSON.stringify({ type: "getAllComponents" })); 38 | }, 5000); 39 | 40 | 41 | setInterval(()=> { 42 | socket.send(JSON.stringify({ type: "saveData" , componentName: 'IPFScid', data: "this is a test!" })); 43 | }, 3000); 44 | 45 | //lazy reload of websocket if I crash the server 46 | setInterval(()=> { 47 | //console.log(socket.State); 48 | try { 49 | //if (socket.State == WebSocketState.Close) {socket = new WebSocket("ws://localhost:8082")} 50 | //console.log(socket.State); 51 | } catch (error) { 52 | console.log(error) 53 | } 54 | }, 5000) 55 | /* 56 | setTimeout(()=> { 57 | socket.send(JSON.stringify({ type: "createObjective", data: "Write the worlds greatest robot detective novel!" })); 58 | }, 2000); 59 | //> const WebSocket = require('ws') 60 | */ -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chippr-agi", 3 | "version": "1.1.50", 4 | "description": "Happy helpful autoGPT ", 5 | "main": "index.js", 6 | "private": false, 7 | "scripts": { 8 | "git": "git checkout main && git pull", 9 | "start": "node src/index.js", 10 | "test": "TESTING=true mocha test/**/*.test.js", 11 | "demo": "node examples/simple_demo.js", 12 | "build": "docker build -t chipprbots/chippr-agi:latest ." 13 | }, 14 | "type": "module", 15 | "keywords": [ 16 | "agi", 17 | "gpt4", 18 | "autogpt" 19 | ], 20 | "author": "Cody Burns", 21 | "license": "Apache-2.0", 22 | "dependencies": { 23 | "crypto-js": "^4.1.1", 24 | "dotenv": "^16.0.3", 25 | "ipfs": "^0.66.0", 26 | "ipfs-core": "^0.18.0", 27 | "natural": "^6.2.0", 28 | "node-fetch": "^3.3.1", 29 | "openai": "^3.2.1", 30 | "os": "^0.1.2", 31 | "pubsub-js": "^1.9.4", 32 | "redis": "^4.6.5", 33 | "url": "^0.11.0", 34 | "winston": "^3.8.2", 35 | "ws": "^8.13.0" 36 | }, 37 | "devDependencies": { 38 | "chai": "^4.3.7", 39 | "mocha": "^10.2.0" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/components/active/IPFScid.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | import { SchemaFieldTypes } from "redis"; 3 | 4 | CHIPPRAGI.registerComponent('IPFScid', { 5 | schema:{ 6 | '$.fileCID': { 7 | type: SchemaFieldTypes.TEXT, 8 | AS: 'cid' 9 | }, 10 | }, 11 | 12 | info: { 13 | version : "0.1.0", 14 | license : "APACHE-2.0", 15 | developer: "CHIPPRBOTS", 16 | multi: true, 17 | description : "This component stores a files cid on the ipfs network", 18 | }, 19 | }); -------------------------------------------------------------------------------- /src/components/active/ObjectiveDescription.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | import { SchemaFieldTypes } from "redis"; 3 | 4 | CHIPPRAGI.registerComponent('ObjectiveDescription',{ 5 | schema: { 6 | '$.objective': { 7 | type: SchemaFieldTypes.TEXT, 8 | AS: 'objective' 9 | }, 10 | '$.complete': { 11 | type: SchemaFieldTypes.TAG, 12 | AS: 'complete' 13 | }, 14 | }, 15 | info: { 16 | version : "0.1.0", 17 | license : "APACHE-2.0", 18 | developer: "CHIPPRBOTS", 19 | description : "This component shows the objective description of an entity.", 20 | }, 21 | }); 22 | -------------------------------------------------------------------------------- /src/components/active/SystemSelection.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | import { SchemaFieldTypes } from "redis"; 3 | 4 | CHIPPRAGI.registerComponent('SystemSelection', { 5 | schema:{ 6 | '$.recommendedSystem': { 7 | type: SchemaFieldTypes.TEXT, 8 | AS: 'recommendedSystem' 9 | }, 10 | }, 11 | 12 | info: { 13 | version : "0.1.0", 14 | license : "APACHE-2.0", 15 | developer: "CHIPPRBOTS", 16 | description : "This component shows whic system is recommend next", 17 | }, 18 | }); -------------------------------------------------------------------------------- /src/components/active/TaskDescription.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | 3 | import { SchemaFieldTypes } from "redis"; 4 | 5 | CHIPPRAGI.registerComponent('TaskDescription', { 6 | schema: { 7 | '$.task': { 8 | type: SchemaFieldTypes.TEXT, 9 | AS: 'task' 10 | }, 11 | '$.complete': { 12 | type: SchemaFieldTypes.TAG, 13 | AS: 'complete' 14 | }, 15 | }, 16 | 17 | info: { 18 | version : "0.1.0", 19 | license : "APACHE-2.0", 20 | developer: "CHIPPRBOTS", 21 | description : "This component is used to display a task description", 22 | }, 23 | }); -------------------------------------------------------------------------------- /src/components/active/TaskEmbedding.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | 3 | import { SchemaFieldTypes, VectorAlgorithms } from "redis"; 4 | 5 | CHIPPRAGI.registerComponent('TaskEmbedding', { 6 | schema:{ 7 | '$.clean' : { 8 | type: SchemaFieldTypes.VECTOR, 9 | AS: 'clean', 10 | ALGORITHM: VectorAlgorithms.HNSW, 11 | COUNT: '7', 12 | TYPE: 'FLOAT32', 13 | DIM: '1536', 14 | DISTANCE_METRIC: 'COSINE' 15 | }, 16 | '$.floatbuffer' : { 17 | type: SchemaFieldTypes.VECTOR, 18 | AS: 'floatbuffer', 19 | ALGORITHM: VectorAlgorithms.HNSW, 20 | COUNT: '7', 21 | TYPE: 'FLOAT32', 22 | DIM: '1536', 23 | DISTANCE_METRIC: 'COSINE' 24 | }, 25 | }, 26 | 27 | info: { 28 | version : "0.1.0", 29 | license : "APACHE-2.0", 30 | developer: "CHIPPRBOTS", 31 | description : "This component shows the embedding of a task", 32 | }, 33 | }); -------------------------------------------------------------------------------- /src/components/active/TaskExpanded.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | 3 | import { SchemaFieldTypes } from "redis"; 4 | 5 | CHIPPRAGI.registerComponent('TaskExpanded', { 6 | schema: { 7 | '$.expandedTask': { 8 | type: SchemaFieldTypes.TEXT, 9 | AS: 'expandedTask' 10 | }, 11 | '$.justification': { 12 | type: SchemaFieldTypes.TAG, 13 | AS: 'justification' 14 | }, 15 | }, 16 | 17 | info: { 18 | version : "0.1.0", 19 | license : "APACHE-2.0", 20 | developer: "CHIPPRBOTS", 21 | description : "This component is used to display a tasks expanded description", 22 | }, 23 | }); -------------------------------------------------------------------------------- /src/components/active/TaskParent.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | import { SchemaFieldTypes } from "redis"; 3 | 4 | CHIPPRAGI.registerComponent('TaskParent', { 5 | schema:{ 6 | '$.parentID': { 7 | type: SchemaFieldTypes.TEXT, 8 | AS: 'parentID' 9 | }, 10 | }, 11 | 12 | info: { 13 | version : "0.1.0", 14 | license : "APACHE-2.0", 15 | developer: "CHIPPRBOTS", 16 | description : "This component shows the parent of an entity .", 17 | }, 18 | }); -------------------------------------------------------------------------------- /src/components/inactive/foo.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | import { SchemaFieldTypes, VectorAlgorithms } from "redis"; 3 | 4 | 5 | CHIPPRAGI.registerComponent('foo', { 6 | //redis schema for the component 7 | schema: { 8 | '$.entityID': { 9 | type: SchemaFieldTypes.TEXT, 10 | AS: 'entityID' 11 | }, 12 | }, 13 | 14 | info: { 15 | version : "0.1.0", 16 | license : "APACHE-2.0", 17 | developer: "CHIPPRBOTS", 18 | description : "This component shows an example.", 19 | }, 20 | }); -------------------------------------------------------------------------------- /src/core/ChipprAGI.js: -------------------------------------------------------------------------------- 1 | import * as dotenv from 'dotenv'; 2 | dotenv.config(); 3 | 4 | import 'fs'; 5 | 6 | //add the core systems 7 | //import { CHIPPRAGI } from '../index.js'; 8 | import { LanguageModel } from './LangModel/langModel.js'; 9 | import { Logger } from './Logger/logger.js'; 10 | import { MessageBus } from './MessageBus/msgBus.mjs'; 11 | import { Utility } from './Util/Util.js'; 12 | import { VectorDB } from './Vector-db/vector-db.js' 13 | 14 | 15 | export class ChipprAGI { 16 | constructor(chipprConfig) { 17 | this.SWARM_MODE = chipprConfig.CORE.SWARM_MODE; 18 | this.DASHBOARD = chipprConfig.CORE.DASHBOARD; 19 | this.TESTING = chipprConfig.TESTING; 20 | this.LangModel = new LanguageModel(chipprConfig); 21 | this.Logger = new Logger(chipprConfig); 22 | this.MessageBus = new MessageBus(chipprConfig); 23 | this.Util = new Utility(chipprConfig); 24 | this.vectorDb = new VectorDB(chipprConfig); // Initialize vector database 25 | //local cache 26 | this.entities = {}; 27 | this.components = {}; 28 | this.systems ={}; 29 | if(chipprConfig.MESSAGE_BUS.MESSAGE_BUS_WATCH == true) this.Util.watcher(this.MessageBus, this.Logger, chipprConfig); 30 | this.init(); 31 | } 32 | 33 | async init() { 34 | if(this.TESTING != true){ 35 | //this.langModel.init(); 36 | //this.vectorDb.init(); 37 | //this.eventEmitter.init(); 38 | }; 39 | //load the core systems 40 | this.Logger.debug({ system : 'ChipprAGI', log : 'Loading core systems'}); 41 | await import ('../systems/active/CoreSystemLoader.mjs'); 42 | this.systems['CoreSystemLoader'].init();//import ('../systems/active/.mjs'); 43 | } 44 | async createEntity(_entityID) { 45 | this.Logger.debug( 'creating entity'); 46 | if(this.SWARM_MODE != true){ 47 | this.Logger.debug('creating entity in swarm mode'); 48 | this.entities[_entityID] = {}; 49 | } else { 50 | await this.vectorDb.save( `idx:entities:${_entityID}`, '$', {}); 51 | } 52 | } 53 | 54 | async getAllEntities(){ 55 | return await this.vectorDb.query(`idx:entities:*`); 56 | } 57 | 58 | async getEntitiesByComponent(componentName){ 59 | return await this.vectorDb.query(`idx:${componentName}:*`); 60 | } 61 | 62 | addComponent 63 | 64 | addComponent(entityId, componentName, componentData) { 65 | //check if we store components in the db or not 66 | if(this.SWARM_MODE != true){ 67 | this.entities[entityId][componentName] = componentData; 68 | return true; 69 | } else { 70 | this.vectorDb.save( `idx:${componentName}:${entityId}`, '$', componentData); 71 | } 72 | } 73 | 74 | getComponentData(entityId, componentName) { 75 | //check if we store components in the db or not 76 | try { 77 | if(this.SWARM_MODE != true){ 78 | return this.entities[entityId][componentName]; 79 | } else { 80 | return this.vectorDb.get(`idx:${componentName}:${entityId}`); 81 | } 82 | } catch (error) { 83 | this.Logger.log('error',`CHIPPRAGI : getcomponentdata error: ${error}`); 84 | return null; 85 | } 86 | } 87 | 88 | setComponentData(entityId, componentName, componentData) { 89 | try { 90 | if(this.SWARM_MODE != true){ 91 | this.entities[entityId][componentName] = componentData; 92 | return true; 93 | } else { 94 | this.vectorDb.save( `idx:${componentName}:${entityId}`, '$', componentData); 95 | return true; 96 | } 97 | } catch (error) { 98 | this.Logger.log('error',`CHIPPRAGI : setcomponentdata error: ${error}`); 99 | return false; 100 | } 101 | } 102 | 103 | async registerComponent(componentName, component) { 104 | this.Logger.debug(`swarmmode:${this.SWARM_MODE}`); 105 | this.Logger.debug( componentName); 106 | if(this.SWARM_MODE != true){ 107 | this.Logger.debug('swarm is not really on'); 108 | this.components[componentName] = component; 109 | return true; 110 | } else { 111 | //console.log('swarm is on'); 112 | await this.vectorDb.create( `idx:${componentName}`, component.schema , { 113 | ON: 'JSON', 114 | PREFIX: `idx:${componentName}:`, 115 | }); 116 | //save for local use 117 | this.components[componentName] = component; 118 | } 119 | } 120 | 121 | registerSystem(systemName, system) { 122 | //console.log(systemName); 123 | //all systems are local so store it at its name 124 | this.systems[systemName]= system; 125 | } 126 | 127 | subscribe(eventType, listener){ 128 | this.MessageBus.subscribe(eventType, listener); 129 | } 130 | 131 | publish(eventType, eventData) { 132 | this.MessageBus.publish(eventType, eventData); 133 | } 134 | } 135 | 136 | 137 | -------------------------------------------------------------------------------- /src/core/LangModel/huggingface.js: -------------------------------------------------------------------------------- 1 | import fetch from "node-fetch"; 2 | 3 | export class HuggingFaceApi { 4 | constructor(chipprConfig){ 5 | this.API_TOKEN = chipprConfig.LANGUAGE_MODEL.LANGUAGE_MODEL_API_KEY; 6 | this.GENERATE_NAME = chipprConfig.LANGUAGE_MODEL.LANGUAGE_MODEL_GENERATE_NAME; 7 | this.DEFAULT_TEMP = chipprConfig.LANGUAGE_MODEL.LANGUAGE_MODEL_DEFAULT_TEMP; 8 | this.DEFAULT_MAX_TOKENS = chipprConfig.LANGUAGE_MODEL.LANGUAGE_MODEL_DEFAULT_MAX_TOKENS; 9 | this.DEFAULT_MATCH_LENGTH = chipprConfig.LANGUAGE_MODEL.LANGUAGE_MODEL_DEFAULT_MATCH_LENGTH; 10 | } 11 | 12 | async query( data, model ) { 13 | const response = await fetch( 14 | `https://api-inference.huggingface.co/models/${model}`, 15 | { 16 | headers: { Authorization: `Bearer ${this.API_TOKEN}` }, 17 | method: "POST", 18 | body: JSON.stringify(data), 19 | } 20 | ); 21 | const result = await response.json(); 22 | return result; 23 | } 24 | 25 | async createCompletion( prompt ) { 26 | let data ={ 27 | inputs : prompt.prompt, 28 | parameters : { 29 | temperature : prompt.temp || this.DEFAULT_TEMP, 30 | max_new_tokens : prompt.max_tokens || this.DEFAULT_MAX_TOKENS, 31 | return_full_text : false, 32 | }, 33 | options : { 34 | use_cache : false, 35 | wait_for_model : true, 36 | } 37 | }; 38 | 39 | let results = await this.query( data , this.GENERATE_NAME ); 40 | //should return a string 41 | return results.generated_text; 42 | 43 | }; 44 | /* 45 | createEmbedding() { return Promise.resolve(this.tests)}; 46 | createChat(){return Promise.resolve(this.tests)}; 47 | createCodex(){return Promise.resolve(this.tests)}; 48 | createEdit(){return Promise.resolve(this.tests)}; 49 | createImage(){return Promise.resolve(this.tests)}; 50 | createAudio(){return Promise.resolve(this.tests)}; 51 | // Add any other methods that you need to mock during testing 52 | */ 53 | }; -------------------------------------------------------------------------------- /src/core/LangModel/langModel.js: -------------------------------------------------------------------------------- 1 | import { rateLimitsConfig } from "./ratelimits.js"; 2 | import { OpenAIApi }from "./openai.js"; 3 | import { HuggingFaceApi } from "./huggingface.js"; 4 | import { NoOpClient } from "./no-op-client.js"; 5 | 6 | export class LanguageModel { 7 | constructor(chipprConfig) { 8 | this.rateLimit = rateLimitsConfig[chipprConfig.LANGUAGE_MODEL.LANGUAGE_MODEL_RATE_LIMIT_TYPE] || rateLimitsConfig['default']; 9 | this.requestQueue = {}; 10 | this.init(); 11 | switch(chipprConfig.LANGUAGE_MODEL.LANGUAGE_MODEL_ID){ 12 | case 'openai': 13 | this.model = new OpenAIApi(chipprConfig); 14 | break; 15 | case 'huggingface': 16 | this.model = new HuggingFaceApi(chipprConfig); 17 | break; 18 | default: 19 | this.model = new NoOpClient(chipprConfig); 20 | } 21 | } 22 | 23 | init() { 24 | for (const type in this.rateLimit) { 25 | // Initialize an empty array for each request type 26 | this.requestQueue[type] = []; 27 | //console.log(type); 28 | this.startRateLimitedInterval(type, this.rateLimit[type]); 29 | } 30 | } 31 | 32 | async processRequestQueue(callType) { 33 | if (this.requestQueue[callType].length > 0) { 34 | let response; 35 | const request = this.requestQueue[callType].shift(); 36 | // Execute the request 37 | switch (callType) { 38 | //send to model these are separated incase anything special needs to happen before sending 39 | case 'completion': 40 | response = await this.model.createCompletion(request.data); 41 | break; 42 | case 'chat': 43 | response = await this.model.createChat(request.data); 44 | break; 45 | case 'codex': 46 | response = await this.model.createCodex(request.data); 47 | break; 48 | case 'edit': 49 | response = await this.model.createEdit(request.data); 50 | break; 51 | case 'image': 52 | response = await this.model.createImage(request.data); 53 | break; 54 | case 'audio': 55 | response = await this.model.createEmbedding(request.data); 56 | break; 57 | default: 58 | console.error(`Invalid request type: ${request.callType}`); 59 | }; 60 | request.resolve(response); 61 | } 62 | }; 63 | 64 | startRateLimitedInterval(type, rateLimitPerMinute) { 65 | const intervalTime = Math.floor(60000 / rateLimitPerMinute); 66 | setInterval(() => { 67 | this.processRequestQueue(type); 68 | }, intervalTime); 69 | } 70 | 71 | addRequest(callType, data) { 72 | return new Promise((resolve) => { 73 | this.requestQueue[callType].push({ data, resolve }); 74 | }); 75 | } 76 | 77 | async generate(_prompt) { 78 | let response = await this.addRequest( 79 | 'completion',{ 80 | prompt: _prompt, 81 | }); 82 | //response should return a string 83 | //console.log(`Lang Model: ${response}`); 84 | return response; 85 | } 86 | } 87 | 88 | -------------------------------------------------------------------------------- /src/core/LangModel/no-op-client.js: -------------------------------------------------------------------------------- 1 | export class NoOpClient { 2 | constructor(chipprConfig){ 3 | this.tests = 4 | { 5 | data:{ 6 | choices: [{ 7 | text: 'TESTING', 8 | }], 9 | data: [{ 10 | embedding: 'TESTING', 11 | }], 12 | }, 13 | }; 14 | } 15 | 16 | createCompletion() { return Promise.resolve(this.tests)}; 17 | createEmbedding() { return Promise.resolve(this.tests)}; 18 | createChat(){return Promise.resolve(this.tests)}; 19 | createCodex(){return Promise.resolve(this.tests)}; 20 | createEdit(){return Promise.resolve(this.tests)}; 21 | createImage(){return Promise.resolve(this.tests)}; 22 | createAudio(){return Promise.resolve(this.tests)}; 23 | // Add any other methods that you need to mock during testing 24 | }; -------------------------------------------------------------------------------- /src/core/LangModel/openai.js: -------------------------------------------------------------------------------- 1 | 2 | export class OpenAIApi { 3 | constructor(chipprConfig) { 4 | this.API_TOKEN = chipprConfig.LANGUAGE_MODEL.LANGUAGE_MODEL_API_KEY; 5 | this.GENERATE_NAME = chipprConfig.LANGUAGE_MODEL.LANGUAGE_MODEL_GENERATE_NAME; 6 | this.DEFAULT_TEMP = chipprConfig.LANGUAGE_MODEL.LANGUAGE_MODEL_DEFAULT_TEMP; 7 | this.DEFAULT_MAX_TOKENS = chipprConfig.LANGUAGE_MODEL.LANGUAGE_MODEL_DEFAULT_MAX_TOKENS; 8 | this.DEFAULT_MATCH_LENGTH = chipprConfig.LANGUAGE_MODEL.LANGUAGE_MODEL_DEFAULT_MATCH_LENGTH; 9 | } 10 | 11 | async query( data ) { 12 | const response = await fetch( 13 | `https://api.openai.com/v1/completions`, 14 | { 15 | headers: { 16 | Authorization: `Bearer ${this.API_TOKEN}` , 17 | 'Content-Type': "application/json", 18 | }, 19 | method: "POST", 20 | body: JSON.stringify(data), 21 | } 22 | ); 23 | const result = await response.json(); 24 | return result; 25 | } 26 | async createCompletion( prompt ) { 27 | let data ={ 28 | model : this.GENERATE_NAME, 29 | prompt : prompt.prompt, 30 | temperature : prompt.temp || this.DEFAULT_TEMP, 31 | max_tokens : prompt.max_tokens || this.DEFAULT_MAX_TOKENS, 32 | }; 33 | console.log(`this is the data ${JSON.stringify(data)}`); 34 | let results = await this.query( data ); 35 | console.log("this is the results", results); 36 | //should return a string 37 | return results.generated_text; 38 | }; 39 | } -------------------------------------------------------------------------------- /src/core/LangModel/ratelimits.js: -------------------------------------------------------------------------------- 1 | export const rateLimitsConfig = { 2 | huggingface_free: { 3 | embeddings: 3000, 4 | completion: 3000, 5 | chat: 3000, 6 | codex: 3000, 7 | edit: 3000, 8 | image: 3000, 9 | audio: 3000, 10 | }, 11 | openai_free: { 12 | embeddings: 3, 13 | completion: 3, 14 | chat: 3, 15 | codex: 3, 16 | edit: 3, 17 | image: 5, 18 | audio: 3, 19 | }, 20 | openai_pay: { 21 | embeddings: 3500, 22 | completion: 3500, 23 | chat: 3500, 24 | codex: 20, 25 | edit: 20, 26 | image: 50, 27 | audio: 50, 28 | }, 29 | default: { 30 | embeddings: 3, 31 | completion: 3, 32 | chat: 3, 33 | codex: 3, 34 | edit: 3, 35 | image: 5, 36 | audio: 3, 37 | }, 38 | } -------------------------------------------------------------------------------- /src/core/Logger/logger.js: -------------------------------------------------------------------------------- 1 | import * as winston from 'winston'; 2 | 3 | export function Logger(chipprConfig){ 4 | let consoleLogger; 5 | let debugLogger; 6 | let transports = []; 7 | let dir = './logs/'; 8 | //log to console if enabled 9 | if(chipprConfig.LOGS.LOG_CONSOLE == true) { 10 | consoleLogger = new (winston.transports.Console)({ 11 | level: 'info' 12 | }); 13 | transports.push(consoleLogger); 14 | }; 15 | 16 | if(chipprConfig.LOGS.DEBUG == true) { 17 | debugLogger = new (winston.transports.File)({ 18 | name: 'debug-logs', 19 | filename: dir + 'debug.log', 20 | level: 'debug' 21 | }); 22 | transports.push(debugLogger); 23 | }; 24 | 25 | transports.push(new (winston.transports.File)({ 26 | name: 'info-logs', 27 | filename: dir + 'info.log', 28 | level: 'info' 29 | }) 30 | ); 31 | 32 | transports.push(new (winston.transports.File)({ 33 | name: 'error-logs', 34 | filename: dir + 'errors.log', 35 | level: 'error' 36 | }), 37 | ); 38 | return winston.createLogger({ 39 | format: winston.format.json(), 40 | transports: transports 41 | }); 42 | } -------------------------------------------------------------------------------- /src/core/MessageBus/messageSchema.js: -------------------------------------------------------------------------------- 1 | export const messageSchema = { 2 | "version": "1.0.0", 3 | "eventType": "", 4 | "payload": { 5 | "entityID": "123", 6 | "componentName": "", 7 | "data": {} 8 | }, 9 | "metadata": { 10 | "timestamp": "1633028743789", 11 | "sourceSystem": "" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/core/MessageBus/msgBus.mjs: -------------------------------------------------------------------------------- 1 | //import { EventEmitter } from 'events'; 2 | import PubSub from 'pubsub-js'; 3 | import { messageSchema } from './messageSchema.js'; 4 | import * as redis from 'redis'; 5 | 6 | export class MessageBus { 7 | constructor(chipprConfig) { 8 | //decide if needed 9 | this.MessageSchema = messageSchema; 10 | this.PubSub = PubSub; 11 | this.sanity = []; 12 | switch (chipprConfig.MESSAGE_BUS.MESSAGE_BUS_TYPE) { 13 | case'redis'://do not use yet 14 | this.publisher = redis.createClient({url : `redis://${chipprConfig.VECTORDB.VECTORDB_HOST}:${chipprConfig.VECTORDB.VECTORDB_PORT}`}); 15 | this.subscriber = redis.createClient({url : `redis://${chipprConfig.VECTORDB.VECTORDB_HOST}:${chipprConfig.VECTORDB.VECTORDB_PORT}`}); 16 | this.publisher.connect(); 17 | this.subscriber.connect(); 18 | break; 19 | default: 20 | //update in messagebus updates 21 | this.publisher = this.PubSub; 22 | this.subscriber = this.PubSub; 23 | } 24 | 25 | //more buses to come after mvp... 26 | } 27 | 28 | subscribe(eventType, listener){ 29 | //console.log(`subscribe ${JSON.parse(this.subscriber)}`); 30 | this.subscriber.subscribe(eventType, listener); 31 | } 32 | 33 | publish(eventType, eventData) { 34 | this.publisher.publish(eventType, eventData); 35 | } 36 | 37 | systemMessage( _eventType, _entityID, _componentName, _sourceSystem, _data ) { 38 | let newMessage = { ...this.MessageSchema }; 39 | newMessage.eventType = _eventType; 40 | newMessage.payload.entityID = _entityID; 41 | newMessage.payload.componentName = _componentName || null; 42 | newMessage.payload.data = _data || {}; 43 | //metadata management 44 | newMessage.metadata.timestamp = Math.floor(Date.now()); 45 | newMessage.metadata.sourceSystem = _sourceSystem; 46 | //if(this.Watch ==true ) console.log(`Sending message system ${JSON.stringify(newMessage)}`); 47 | this.publish('SYSTEM', JSON.stringify(newMessage) ); 48 | } 49 | 50 | updateMessage( _eventType, _entityID, _componentName, _sourceSystem, _data ) { 51 | //console.log(`type: ${_eventType} entityID: ${_entityID} componentName: ${_componentName}, data: ${_data}`); 52 | let newMessage = { ...this.MessageSchema }; 53 | newMessage.eventType = _eventType; 54 | newMessage.payload.entityID = _entityID; 55 | newMessage.payload.componentName = _componentName || null; 56 | newMessage.payload.data = _data || {}; 57 | //metadata management 58 | newMessage.metadata.timestamp = Math.floor(Date.now()); 59 | newMessage.metadata.sourceSystem = _sourceSystem; 60 | //console.log(`Sending update message ${newMessage}`); 61 | this.publish('UPDATE', JSON.stringify(newMessage)); 62 | } 63 | pubOnce (callback, dependencies) { 64 | // Calling it first time since there are no dependency 65 | if (dependencies === undefined) { 66 | return callback(); 67 | } 68 | 69 | // Creating proxy for setters 70 | return new Proxy(dependencies, { 71 | set: function (target, key, value) { 72 | Reflect.set(target, key, value); 73 | callback(); 74 | }, 75 | }); 76 | }; 77 | } 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /src/core/Util/BootScreen.mjs: -------------------------------------------------------------------------------- 1 | import fs from 'fs/promises'; 2 | import path from 'path'; 3 | import os from 'os'; 4 | 5 | export async function getPackageVersion() { 6 | const packageJsonPath = path.resolve(process.cwd(), 'package.json'); 7 | try { 8 | const data = await fs.readFile(packageJsonPath, 'utf-8'); 9 | const packageJson = JSON.parse(data); 10 | return packageJson.version; 11 | } catch (error) { 12 | console.error('Error reading package.json:', error); 13 | return 'unknown'; 14 | } 15 | } 16 | 17 | export function displayBootScreen(version, config) { 18 | if (config.CORE.QUIET_BOOT === '1') { 19 | return; 20 | } 21 | 22 | const asciiArt = ` 23 | ________ _ ___ __________ 24 | / ____/ /_ (_)___ ____ _____/ | / ____/ _/ 25 | / / / __ \\/ / __ \\/ __ \\/ ___/ /| |/ / __ / / 26 | / /___/ / / / / /_/ / /_/ / / / ___ / /_/ // / 27 | \\____/_/ /_/_/ .___/ .___/_/ /_/ |_\\____/___/ 28 | /_/ /_/ 29 | `; 30 | console.log(asciiArt); 31 | console.log(`Version: ${version}`); 32 | console.log(`Selected Systems:`); 33 | console.log(` VectorDB: ${config.VECTORDB.VECTORDB_TYPE}`); 34 | console.log(` LanguageModel: ${config.LANGUAGE_MODEL.LANGUAGE_MODEL_ID}`) 35 | console.log(` LanguageModel Rate: ${config.LANGUAGE_MODEL.LANGUAGE_MODEL_RATE_LIMIT_TYPE}`); 36 | console.log(` Message Bus: ${config.MESSAGE_BUS.MESSAGE_BUS_TYPE}`); 37 | console.log(` Console Logs: ${config.LOGS.LOG_CONSOLE == true}`); 38 | console.log(` Debug mode: ${config.LOGS.DEBUG == true}`); 39 | console.log(os.EOL); 40 | }; 41 | 42 | -------------------------------------------------------------------------------- /src/core/Util/Util.js: -------------------------------------------------------------------------------- 1 | import CryptoJS from 'crypto-js'; 2 | import * as ipfs from 'ipfs'; 3 | 4 | export class Utility { 5 | constructor(chipprConfig) { 6 | this.node; 7 | this.init(); 8 | } 9 | 10 | async init() { 11 | this.node = await ipfs.create(); 12 | //console.log(this.node) 13 | } 14 | 15 | getHashId( _dataToHash ){ 16 | //console.log(`hashing date: ${_dataToHash}`); 17 | let hash = CryptoJS.SHA256(_dataToHash); 18 | //use the first 10 bytes of the hash as the hashID 19 | let hashID = hash.toString(CryptoJS.enc.Hex).slice(0,10); 20 | //console.log(`returning hash: ${hashID}`) 21 | return hashID; 22 | } 23 | 24 | async delay(ms) {new Promise(resolve => setTimeout(resolve, ms))} 25 | 26 | 27 | watcher (msgBus, logger){ 28 | //cant be configured until after init 29 | let watch = (m) => { 30 | logger.info( {log: JSON.parse(m), system: 'WatcherService' }); 31 | }; 32 | msgBus.subscriber.subscribe('SYSTEM', watch); 33 | msgBus.subscriber.subscribe('UPDATE', watch); 34 | msgBus.subscriber.subscribe('REMOVE', watch); 35 | }; 36 | 37 | useEffect (callback, dependencies) { 38 | // Calling it first time since there are no dependency 39 | if (dependencies === undefined) { 40 | return callback(); 41 | } 42 | 43 | // Creating proxy for setters 44 | return new Proxy(dependencies, { 45 | set: function (target, key, value) { 46 | Reflect.set(target, key, value); 47 | callback(); 48 | }, 49 | }); 50 | }; 51 | 52 | async storeData( data ){ 53 | // takes a data object in and returns a cid string 54 | const results = await this.node.add(data) 55 | //do something with results maybe 56 | return results; 57 | } 58 | 59 | async getData( cid ){ 60 | for await (const buf of this.node.get(cid)) { 61 | return buf; 62 | } 63 | } 64 | 65 | async readData( cid ){ 66 | for await (const ary of this.node.cat(cid)) { 67 | return ary; 68 | } 69 | } 70 | } 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /src/core/Util/noop.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chippr-robotics/chippr-agi/5420cae80d804c905916a1bb151189f25761d709/src/core/Util/noop.js -------------------------------------------------------------------------------- /src/core/Vector-db/vector-db.js: -------------------------------------------------------------------------------- 1 | import * as redis from 'redis'; 2 | 3 | 4 | export class VectorDB { 5 | constructor( chipprConfig ) { 6 | if (chipprConfig.TESTING != true) { 7 | switch (chipprConfig.VECTORDB.VECTORDB_TYPE) { 8 | case 'redis': 9 | this.client = redis.createClient({url : `redis://${chipprConfig.VECTORDB.VECTORDB_HOST}:${chipprConfig.VECTORDB.VECTORDB_PORT}`}); 10 | this.client.connect(); 11 | this.client.on('error', (error) => { 12 | console.error('Redis error:', error); 13 | }); 14 | break; 15 | 16 | default: 17 | this.client = null; 18 | } 19 | } else { 20 | this.client = null; 21 | } 22 | } 23 | 24 | async create(index, schema, options) { 25 | //get a list of index in the DB 26 | //console.log(this.client); 27 | let list = await this.client.ft._list(); 28 | // escape if the index exists 29 | //console.log(index); 30 | if(list.indexOf(index) > -1){ 31 | return false; 32 | } else { 33 | //create a new index if none exists 34 | try { 35 | //console.log(this.client); 36 | await this.client.ft.create(index, schema, options); 37 | //console.log(createIndex); 38 | } catch (error) { 39 | console.error(error); 40 | }; 41 | 42 | } 43 | } 44 | 45 | async save(_index, _string, _data) { 46 | //console.log('saving task'); 47 | try { 48 | //save to the db 49 | await this.client.json.set(_index, _string, _data); 50 | return true; 51 | } catch (e) { 52 | if (e.message === 'Index already exists') { 53 | console.log('Index exists already, skipped creation.'); 54 | } else { 55 | // Something went wrong, perhaps RediSearch isn't installed... 56 | console.error(e); 57 | process.exit(1); 58 | } 59 | } 60 | } 61 | 62 | async get(_index) { 63 | try { 64 | let task = await this.client.json.get(_index); 65 | return task; 66 | } catch (error) { 67 | console.error(error); 68 | return error; 69 | } 70 | } 71 | //@dev done is a bool to fetch either tasks that are done or not 72 | async getNeighbors(_embedding, done) { 73 | //console.log('getting neighbors') 74 | //console.log(_embedding) 75 | try { 76 | let knn = await this.client.ft.search( 77 | this.indexName , 78 | `@done:{${done}}=>[KNN 4 @vector $BLOB AS dist]`,{ 79 | PARAMS: { 80 | BLOB: _embedding 81 | }, 82 | SORTBY: 'dist', 83 | DIALECT: 2, 84 | RETURN: ['dist'] 85 | }); 86 | //console.debug(knn); 87 | return knn; 88 | } catch (error) { 89 | console.error(error); 90 | } 91 | } 92 | 93 | async query(componentIndex){ 94 | try { 95 | let task = await this.client.KEYS(componentIndex); 96 | return task; 97 | } catch (error) { 98 | console.error(error); 99 | } 100 | } 101 | 102 | createNoOpClient() { 103 | return { 104 | on: () => {}, 105 | publish: () => {}, 106 | ft : { 107 | search: () => {}, 108 | create: () => {}, 109 | }, 110 | json:{ 111 | get: ()=>{}, 112 | set: ()=>{}, 113 | }, 114 | // Add any other methods that you need to mock during testing 115 | }; 116 | } 117 | 118 | } 119 | 120 | 121 | -------------------------------------------------------------------------------- /src/core/lib/chipprAGI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chippr-robotics/chippr-agi/5420cae80d804c905916a1bb151189f25761d709/src/core/lib/chipprAGI.png -------------------------------------------------------------------------------- /src/core/lib/splashLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chippr-robotics/chippr-agi/5420cae80d804c905916a1bb151189f25761d709/src/core/lib/splashLogo.png -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { ChipprAGI } from './core/ChipprAGI.js'; 2 | import { displayBootScreen, getPackageVersion } from './core/Util/BootScreen.mjs'; 3 | 4 | const config = { 5 | //will try process.env then apply defaults 6 | //defaults will be applied if not found in process.env 7 | //defaults shopuld make the mvp system runable 8 | //core systems 9 | TESTING : process.env.CHIPPRAGI_TESTING || false, 10 | CORE:{ 11 | SWARM_MODE: process.env.CHIPPRAGI_SWARM_MODE || true, 12 | DASHBOARD : process.env.CHIPPRAGI_DASHBOARD || false, 13 | QUIET_BOOT : process.env.CHIPPAGI_CORE_QUIET_BOOT || false, 14 | }, 15 | LOGS:{ 16 | LOG_CONSOLE: process.env.CHIPPRAGI_LOG_CONSOLE || true, 17 | DEBUG: process.env.CHIPPRAGI_LOG_DEBUG || false, 18 | }, 19 | LANGUAGE_MODEL:{ 20 | LANGUAGE_MODEL_API_KEY: process.env.CHIPPRAGI_LANGUAGE_MODEL_API_KEY || null, 21 | LANGUAGE_MODEL_API_URL: process.env.CHIPPRAGI_LANGUAGE_MODEL_API_URL || null, 22 | LANGUAGE_MODEL_ID: process.env.CHIPPRAGI_LANGUAGE_MODEL_ID || 'openai', 23 | LANGUAGE_MODEL_GENERATE_NAME: process.env.CHIPPRAGI_LANGUAGE_MODEL_GENERATE_NAME || 'text-davinci-003', 24 | LANGUAGE_MODEL_DEFAULT_TEMP: process.env.CHIPPRAGI_LANGUAGE_MODEL_DEFAULT_TEMP || 0.5, 25 | LANGUAGE_MODEL_DEFAULT_MAX_TOKENS: process.env.CHIPPRAGI_LANGUAGE_MODEL_DEFAULT_MAX || 500, 26 | LANGUAGE_MODEL_DEFAULT_MATCH_LENGTH: process.env.CHIPPRAGI_LANGUAGE_MODEL_DEFAULT_MATCH_LENGTH || 5, 27 | LANGUAGE_MODEL_RATE_LIMIT_TYPE: process.env.CHIPPRAGI_LANGUAGE_MODEL_RATE_LIMIT_TYPE || 'openAI_Free', 28 | }, 29 | MESSAGE_BUS:{ 30 | MESSAGE_BUS_TYPE: process.env.CHIPPRAGI_MESSAGE_BUS_TYPE || 'redis', 31 | MESSAGE_BUS_WATCH : process.env.CHIPPRAGI_MESSAGE_BUS_WATCH || true, 32 | }, 33 | VECTORDB:{ 34 | VECTORDB_TYPE: process.env.CHIPPRAGI_VECTORDB_TYPE || 'redis', 35 | VECTORDB_HOST: process.env.CHIPPRAGI_VECTORDB_HOST || 'localhost', 36 | VECTORDB_PORT: process.env.CHIPPRAGI_VECTORDB_PORT || '6379', 37 | }, 38 | }; 39 | 40 | const version = await getPackageVersion(); 41 | 42 | displayBootScreen(version, config); 43 | 44 | export const CHIPPRAGI = new ChipprAGI(config); 45 | -------------------------------------------------------------------------------- /src/prompts/GenerateTasksPrompt.js: -------------------------------------------------------------------------------- 1 | export const GenerateTasksPrompt = { 2 | info : { 3 | "name" : "AI Agent", 4 | "author" : "", 5 | "version" : "1.0.0", 6 | "description" : "", 7 | "website" : "" 8 | }, 9 | 10 | task_prompt : [ 11 | "You are an AI agent that creates lists of tasks to complete objectives.", 12 | "Your objective is {{ objective }}.", 13 | "", 14 | "Return a properly formated JSON list of objects having the following format:", 15 | "```", 16 | "[", 17 | " {", 18 | " \"task\": \"string\",", 19 | " \"done\": \"bool\",", 20 | " },", 21 | " ...", 22 | "]", 23 | "```", 24 | "where:", 25 | "'task' is the description of the task", 26 | "'done' is a boolean indicating whether the task is completed", 27 | "", 28 | " Response:" 29 | ] 30 | } -------------------------------------------------------------------------------- /src/prompts/SystemSelectorPrompt.js: -------------------------------------------------------------------------------- 1 | export const SystemSelectorPrompt = { 2 | info : { 3 | "name" : "AI Agent", 4 | "author" : "", 5 | "version" : "1.0.0", 6 | "description" : "", 7 | "website" : "" 8 | }, 9 | 10 | task_prompt : [ 11 | "Given the task description \" {{ taskDescription }} \",", 12 | "Which of the following systems would be the best to handle it:", 13 | "{{ systemDescriptions }}", 14 | "", 15 | "Return a properly formated JSON object having the following format:", 16 | "```", 17 | "[", 18 | " {", 19 | " \"recommendedSystem\": \"string\",", 20 | " \"justification\": \"string\"", 21 | " }", 22 | "]", 23 | "```", 24 | "where:", 25 | "'recommendedSystem' is the name of the system selected", 26 | "'justification' is why the system is the best fit", 27 | "", 28 | " Response:" 29 | ] 30 | } -------------------------------------------------------------------------------- /src/prompts/TaskExpanderPrompt.js: -------------------------------------------------------------------------------- 1 | export const TaskExpanderPrompt = { 2 | info : { 3 | "name" : "AI Agent", 4 | "author" : "", 5 | "version" : "1.0.0", 6 | "description" : "", 7 | "website" : "" 8 | }, 9 | 10 | task_prompt : [ 11 | "Given the task description \" {{ taskDescription }} \",", 12 | "provide a narative explaining the concept of the task. If possible your response should complete the task. ", 13 | "", 14 | "Return a properly formated JSON object having the following format:", 15 | "```", 16 | "[", 17 | " {", 18 | " \"taskDescription\": \"string\",", 19 | " \"taskDetails\": \"string\",", 20 | " \"justification\": \"string\",", 21 | " },", 22 | " ...", 23 | "]", 24 | "```", 25 | "where:", 26 | "'taskDescription' is the expanded text for the task", 27 | "'taskDetails' is the details of the task in narative form as you would explain the task", 28 | "'justification' is why the text helps complete the task", 29 | "", 30 | " Response:" 31 | ] 32 | } -------------------------------------------------------------------------------- /src/prompts/firstTask.js: -------------------------------------------------------------------------------- 1 | { 2 | "taskid": "9f86d08188", 3 | "task": "Create a list of 5 tasks to accomplish the objective.", 4 | "reward": 10, 5 | "done": false, 6 | "dependencies": [], 7 | "state": {}, 8 | "action": "Read the objective and provide a list of steps to take next.", 9 | "actionProbability": 1, 10 | "nextState": {}, 11 | "rewardForAction": 1 12 | } -------------------------------------------------------------------------------- /src/systems/active/AmazingSystem.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | 3 | CHIPPRAGI.registerSystem('AmazingSystem', { 4 | info: { 5 | version : "0.1.0", 6 | license : "APACHE-2.0", 7 | developer: "CHIPPRBOTS", 8 | type: "core", 9 | description : "This is an system that can solve any problem.", 10 | }, 11 | 12 | init: function () { 13 | //NOTE THIS IS FOR TESTING THE SYSTEM ONLY 14 | CHIPPRAGI.subscribe('UPDATE', (eventData) => {this.update(eventData)}); 15 | }, 16 | 17 | update: async function (message) { 18 | // Do something when the component's data is updated, if needed. 19 | // entityId is the ID of the entity this component is attached to. 20 | // componentData contains the updated data for the component. 21 | let eventData = JSON.parse(message); 22 | if (eventData.eventType === 'saveData') { 23 | let cid = await CHIPPRAGI.Util.storeData(eventData.payload.data); 24 | CHIPPRAGI.Logger.error({ systemName: 'awesome system', log: cid}); 25 | let file = await CHIPPRAGI.Util.readData(cid.path); 26 | CHIPPRAGI.Logger.error({ systemName: 'awesome system', log: file.toString('utf8')}); 27 | } 28 | }, 29 | 30 | remove: function (eventData) { 31 | // Do something when the component or its entity is detached, if needed. 32 | }, 33 | 34 | tick: function (eventData) { 35 | // Do something on every scene tick or frame, if needed. 36 | // entityId is the ID of the entity this component is attached to. 37 | // time is the current time in milliseconds. 38 | // timeDelta is the time in milliseconds since the last tick. 39 | }, 40 | 41 | //methods go here 42 | handleEmptySystem: async function (){ 43 | //magic happens here 44 | }, 45 | 46 | }); 47 | -------------------------------------------------------------------------------- /src/systems/active/CoreSystemLoader.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | import * as fs from 'fs'; 3 | 4 | CHIPPRAGI.registerSystem('CoreSystemLoader', { 5 | info: { 6 | version : "0.1.1", 7 | license : "Apache-2.0", 8 | developer: "CHIPPRBOTS", 9 | type: "core", 10 | description : "Auto load and unload systems and components!", 11 | }, 12 | 13 | init: function () { 14 | // do something when the system is first loaded 15 | CHIPPRAGI.subscribe('UPDATE', (type, eventData) => {this.update(eventData)}); 16 | CHIPPRAGI.subscribe('REMOVE', (type,eventData) => {this.remove(eventData)}); 17 | CHIPPRAGI.subscribe('TICK', (type,eventData) => {this.tick(eventData)}); 18 | this.handleLoadSystem(); 19 | }, 20 | 21 | update: function (eventData) { 22 | // Do something when the component's data is updated, if needed. 23 | // entityId is the ID of the entity this component is attached to. 24 | // componentData contains the updated data for the component. 25 | }, 26 | 27 | remove: function (eventData) { 28 | // Do something when the component or its entity is detached, if needed. 29 | }, 30 | 31 | tick: function (eventData) { 32 | // Do something on every scene tick or frame, if needed. 33 | // entityId is the ID of the entity this component is attached to. 34 | // time is the current time in milliseconds. 35 | // timeDelta is the time in milliseconds since the last tick. 36 | }, 37 | 38 | handleLoadSystem : function () { 39 | CHIPPRAGI.Logger.info({system: 'CoreSystemLoader', log:`Systems Loading:`}); 40 | let systems = './src/systems/active/'; 41 | let components = './src/components/active/'; 42 | setInterval(() => { 43 | const systemFiles = fs.readdirSync(systems); 44 | const componentFiles = fs.readdirSync(components); 45 | 46 | // Load systems 47 | systemFiles.forEach(file => { 48 | if(CHIPPRAGI.systems[file.split(".")[0]] == undefined) { 49 | import ('./' + file); 50 | setTimeout(() => { 51 | CHIPPRAGI.Logger.info({system: 'CoreSystemLoader', log:`Loading: ${file}`}); 52 | CHIPPRAGI.systems[file.split(".")[0]].init(); 53 | }, 3000, file); 54 | } 55 | }); 56 | 57 | // Remove systems not present in the directory 58 | for (const systemName in CHIPPRAGI.systems) { 59 | if (!systemFiles.includes(systemName + '.mjs')) { 60 | // CHIPPRAGI.removeSystem(systemName); 61 | } 62 | } 63 | 64 | // Load components 65 | componentFiles.forEach(file => { 66 | if(CHIPPRAGI.components[file.split(".")[0]] == undefined) { 67 | import ('../../components/active/'+file); 68 | } 69 | }); 70 | 71 | // Remove components not present in the directory 72 | for (const componentName in CHIPPRAGI.components) { 73 | if (!componentFiles.includes(componentName + '.mjs')) { 74 | //CHIPPRAGI.removeComponent(componentName); 75 | } 76 | } 77 | 78 | }, 5000); 79 | } 80 | }); 81 | -------------------------------------------------------------------------------- /src/systems/active/DashboardSystem.js: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | 3 | CHIPPRAGI.registerSystem('DashboardSystem', { 4 | info: { 5 | version : "0.1.0", 6 | license : "APACHE-2.0", 7 | developer: "CHIPPRBOTS", 8 | type: 'core', 9 | description : "This system displays a cli dashboard for system testing purposes", 10 | }, 11 | 12 | init: function () { 13 | CHIPPRAGI.Logger.info({system: 'DashBoardSystem', log:`Dashboard test ${CHIPPRAGI.DASHBOARD }`}); 14 | if (CHIPPRAGI.DASHBOARD == true){ 15 | console.clear; 16 | this.dashboard(); 17 | } 18 | }, 19 | 20 | dashboard: function (){ 21 | //display a basic dash board 22 | setInterval(() => { 23 | console.clear(); 24 | console.log('|--- stats --|'); 25 | console.log(`Entities: ${JSON.stringify(Object.keys(CHIPPRAGI.entities).length)}`); 26 | console.log(`Components: ${JSON.stringify(CHIPPRAGI.components)}`); 27 | console.log(`Systems: ${JSON.stringify(CHIPPRAGI.systems)}`); 28 | console.log(`core loader: ${JSON.stringify(CHIPPRAGI.systems['CoreSystemLoader'])}`) 29 | }, 1000); 30 | }, 31 | }); 32 | 33 | 34 | /* 35 | 36 | 37 | 38 | */ -------------------------------------------------------------------------------- /src/systems/active/EntityCreationSystem.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | 3 | CHIPPRAGI.registerSystem('EntityCreationSystem', { 4 | info: { 5 | version : "0.1.0", 6 | license : "APACHE-2.0", 7 | developer: "CHIPPRBOTS", 8 | type: 'core', 9 | description : "This system listens a new objective from a user creates an entityID for the objective.", 10 | }, 11 | 12 | init: function () { 13 | CHIPPRAGI.subscribe('UPDATE', (eventData) => {this.update(eventData)}); 14 | CHIPPRAGI.subscribe('REMOVE', (type, eventData) => {this.remove(eventData)}); 15 | CHIPPRAGI.subscribe('TICK', (type, eventData) => {this.tick(eventData)}); 16 | CHIPPRAGI.subscribe('SYSTEM', (message) => {}); 17 | }, 18 | 19 | update: function (message) { 20 | // Do something when the component's data is updated, if needed. 21 | // entityId is the ID of the entity this component is attached to. 22 | // componentData contains the updated data for the component. 23 | let eventData = JSON.parse(message); 24 | if (eventData.eventType === 'createEntity') { 25 | //CHIPPRAGI.Logger.debug({system: 'EntityCreationSystem', log:`createObjective ${eventData}`}); 26 | this.handleCreateEntity(eventData); 27 | } 28 | }, 29 | 30 | remove: function (eventData) { 31 | // Do something when the component or its entity is detached, if needed. 32 | }, 33 | 34 | tick: function (eventData) { 35 | // Do something on every scene tick or frame, if needed. 36 | // entityId is the ID of the entity this component is attached to. 37 | // time is the current time in milliseconds. 38 | // timeDelta is the time in milliseconds since the last tick. 39 | }, 40 | 41 | handleCreateEntity: async function (event) { 42 | // create the task associated with the given taskId 43 | let data = event.payload.data; 44 | //CHIPPRAGI.Logger.debug({system: 'EntityCreationSystem', log:'createObjective triggered'}); 45 | let entityID = CHIPPRAGI.Util.getHashId(data.task); 46 | // 1) store the task in the AGI Entity list 47 | CHIPPRAGI.createEntity(entityID); 48 | // 2) add a objectiveDescription component 49 | let entityData; 50 | switch (event.payload.componentName){ 51 | case 'ObjectiveDescription' : 52 | entityData = { 53 | objective : data.task, 54 | complete : false, 55 | }; 56 | CHIPPRAGI.addComponent( entityID, 'ObjectiveDescription', entityData); 57 | break; 58 | case 'TaskDescription' : 59 | entityData = { 60 | task : data.task, 61 | complete : false, 62 | }; 63 | CHIPPRAGI.MessageBus.updateMessage('addTaskParent', entityID, 'TaskParent', this.info, { 64 | parentID : data.parentID 65 | }); 66 | CHIPPRAGI.addComponent( entityID, 'TaskDescription', entityData); 67 | break; 68 | } 69 | CHIPPRAGI.MessageBus.updateMessage( 'addSystemSelection', entityID, 'TaskDescription', this.info, entityData); 70 | 71 | 72 | //_eventType, _entityID, _componentName, _sourceSystem, data 73 | 74 | } 75 | 76 | }); -------------------------------------------------------------------------------- /src/systems/active/GenerateTasksSystem.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | import { GenerateTasksPrompt } from '../../prompts/GenerateTasksPrompt.js' 3 | 4 | 5 | CHIPPRAGI.registerSystem('GenerateTasksSystem', { 6 | info: { 7 | version : "0.1.0", 8 | license : "APACHE-2.0", 9 | developer: "CHIPPRBOTS", 10 | type: 'system', 11 | description : "This system listens for new objectives and creates a list of tasks. It then creates entities for those tasks", 12 | }, 13 | 14 | init: function () { 15 | CHIPPRAGI.subscribe('UPDATE', (eventData) => {this.update(eventData)}); 16 | CHIPPRAGI.subscribe('REMOVE', (type, eventData) => {this.remove(eventData)}); 17 | CHIPPRAGI.subscribe('TICK', (type, eventData) => {this.tick(eventData)}); 18 | CHIPPRAGI.subscribe('UPDATE', (message) => {this.update(message)}); 19 | }, 20 | 21 | update: function (message) { 22 | // Do something when the component's data is updated, if needed. 23 | // entityId is the ID of the entity this component is attached to. 24 | // componentData contains the updated data for the component. 25 | let eventData = JSON.parse(message); 26 | switch(eventData.eventType){ 27 | case 'systemSelected' : 28 | this.handleNewObjective(eventData); 29 | break; 30 | default: 31 | } 32 | }, 33 | 34 | remove: function (eventData) { 35 | // Do something when the component or its entity is detached, if needed. 36 | // add logic to remove an entity arrivesent arrives 37 | }, 38 | 39 | handleNewObjective : async function (eventData) { 40 | //3) replace varaible with context 41 | let entityDescription = await CHIPPRAGI.getComponentData(eventData.payload.entityID, eventData.payload.componentName); 42 | 43 | let prompt = []; 44 | (GenerateTasksPrompt.task_prompt).forEach( t => { 45 | // console.log(objectiveDescription.objective); 46 | prompt.push(t.replace('{{ objective }}', entityDescription.objective || entityDescription.task)); 47 | },prompt); 48 | 49 | //4) generate tasks 50 | //todo loop until a valid object is returned 51 | let success = false; 52 | //throw error; 53 | let newTasks = await CHIPPRAGI.LangModel.generate(prompt.join('\n')); 54 | 55 | while (!success){ 56 | //5) generate event to create for each tasks 57 | 58 | try { 59 | JSON.parse(newTasks).forEach( task => { 60 | let newTask = { ...task}; 61 | newTask.parentID = eventData.payload.entityID; 62 | CHIPPRAGI.MessageBus.updateMessage('createEntity', newTask.taskID, 'TaskDescription', this.info, newTask); 63 | }); 64 | success = true; 65 | } catch(error) { 66 | // the response was not json so we need to try again console.logging for trouble shoooting 67 | CHIPPRAGI.Logger.error({system: 'GenerateTasksSystem', log: newTasks, error: JSON.stringify(error)}); 68 | newTasks = await CHIPPRAGI.LangModel.generate(prompt.join('\n')); 69 | } 70 | // 71 | 72 | } 73 | }, 74 | }); 75 | -------------------------------------------------------------------------------- /src/systems/active/SystemSelectorSystem.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | import { SystemSelectorPrompt } from '../../prompts/SystemSelectorPrompt.js' 3 | 4 | CHIPPRAGI.registerSystem('SystemSelectorSystem', { 5 | info: { 6 | version: "0.1.0", 7 | license: "Apache-2.0", 8 | developer: "CHIPPRBOTS", 9 | type: "core", 10 | description: "A system that selects the most appropriate system for a given task description.", 11 | }, 12 | 13 | init: function () { 14 | //should trigger only if a entity has a description 15 | CHIPPRAGI.subscribe('UPDATE', (message) => {this.update(message)}); 16 | CHIPPRAGI.subscribe('REMOVE', (type, eventData) => {this.remove(eventData)}); 17 | CHIPPRAGI.subscribe('TICK', (type, eventData) => {this.tick(eventData)}); 18 | }, 19 | 20 | 21 | update: function (message) { 22 | let eventData = JSON.parse(message); 23 | // Do something when the component or its entity is detached, if needed. 24 | if (eventData.eventType === 'addSystemSelection') { this.handleSelectSystem(eventData)} 25 | }, 26 | 27 | handleSelectSystem: async function (data) { 28 | let systemDescriptions = []; 29 | let taskDescription; 30 | let entityID = data.payload.entityID; 31 | let prompt = []; 32 | // Iterate through all registered systems and extract the description 33 | for (const systemName in CHIPPRAGI.systems) { 34 | if ( CHIPPRAGI.systems[systemName].info.type != 'core') { 35 | const system = CHIPPRAGI.systems[systemName]; 36 | systemDescriptions.push({ 37 | systemName: systemName, 38 | description: system.info.description, 39 | }); 40 | } 41 | } 42 | 43 | //3) replace varaible with context 44 | let taskFinder = await CHIPPRAGI.getComponentData(entityID, 'TaskDescription'); 45 | if (taskFinder == null) { taskFinder = await CHIPPRAGI.getComponentData(entityID, 'ObjectiveDescription') }; 46 | 47 | taskDescription = taskFinder.task || taskFinder.objective; 48 | 49 | (SystemSelectorPrompt.task_prompt).forEach( t => { 50 | t = t.replace('{{ taskDescription }}', taskDescription); 51 | t = t.replace('{{ systemDescriptions }}', JSON.stringify(systemDescriptions)); 52 | prompt.push(t); 53 | },prompt); 54 | // Send the prompt to the language model 55 | //CHIPPRAGI.Logger.error({system: 'SystemSelector.prompt', error: prompt}); 56 | 57 | let success = false; 58 | //throw error; 59 | 60 | while (!success){ 61 | try { 62 | let systemName = await CHIPPRAGI.LangModel.generate(prompt.join('\n')); 63 | CHIPPRAGI.Logger.error({system: 'SystemSelector.sysName', error: systemName}); 64 | let payloadData = { 65 | recommendedSystem : systemName, 66 | }; 67 | //_eventType, _entityID, _componentName, _sourceSystem, _data 68 | JSON.parse(systemName).forEach(system => { 69 | //console.log(system) 70 | CHIPPRAGI.MessageBus.updateMessage( 'systemSelected', entityID, 'SystemSelection', this.info, system.recommendedSystem); 71 | }) 72 | //add a system selector component 73 | CHIPPRAGI.addComponent( entityID, 'SystemSelection', payloadData); 74 | success = true; 75 | } catch(error) { 76 | //console.log(error); 77 | CHIPPRAGI.Logger.error({system: 'SystemSelectorSystem', error: JSON.stringify(error)}); 78 | }; 79 | 80 | } 81 | } 82 | }); 83 | -------------------------------------------------------------------------------- /src/systems/active/TaskParentSystem.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | 3 | CHIPPRAGI.registerSystem('TaskParentSystem', { 4 | info: { 5 | version : "0.1.0", 6 | license : "APACHE-2.0", 7 | developer: "CHIPPRBOTS", 8 | type: "core", 9 | description : "This system listens a new objective from a user creates an entityID for the objective.", 10 | }, 11 | 12 | init: function () { 13 | CHIPPRAGI.subscribe('UPDATE', (eventData) => {this.update(eventData)}); 14 | CHIPPRAGI.subscribe('REMOVE', (type, eventData) => {this.remove(eventData)}); 15 | CHIPPRAGI.subscribe('TICK', (type, eventData) => {this.tick(eventData)}); 16 | CHIPPRAGI.subscribe('SYSTEM', (message) => {}); 17 | }, 18 | 19 | update: function (message) { 20 | // Do something when the component's data is updated, if needed. 21 | // entityId is the ID of the entity this component is attached to. 22 | // componentData contains the updated data for the component. 23 | let eventData = JSON.parse(message); 24 | if (eventData.eventType === 'addTaskParent') { 25 | this.handleCreateEntity(eventData); 26 | } 27 | }, 28 | 29 | remove: function (eventData) { 30 | // Do something when the component or its entity is detached, if needed. 31 | }, 32 | 33 | tick: function (eventData) { 34 | // Do something on every scene tick or frame, if needed. 35 | // entityId is the ID of the entity this component is attached to. 36 | // time is the current time in milliseconds. 37 | // timeDelta is the time in milliseconds since the last tick. 38 | }, 39 | 40 | handleCreateEntity: async function (data) { 41 | let parentData = { 42 | parentId : data.payload.data.parentID 43 | }; 44 | CHIPPRAGI.addComponent( data.payload.entityID, 'TaskParent', parentData ); 45 | CHIPPRAGI.MessageBus.updateMessage( 'addedParent', data.payload.entityID, 'TaskParent', this.info, parentData); 46 | 47 | 48 | 49 | } 50 | }); -------------------------------------------------------------------------------- /src/systems/active/TheJudgeSystem.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | 3 | CHIPPRAGI.registerSystem('TheJudgeSystem', { 4 | info: { 5 | version : "0.1.0", 6 | license : "APACHE-2.0", 7 | developer: "CHIPPRBOTS", 8 | type: "core", 9 | description : "This system evaluates tasks and marks them complete.", 10 | }, 11 | 12 | init: function () { 13 | CHIPPRAGI.subscribe('UPDATE', (eventData) => {this.update(eventData)}); 14 | CHIPPRAGI.subscribe('REMOVE', (type, eventData) => {this.remove(eventData)}); 15 | CHIPPRAGI.subscribe('TICK', (type, eventData) => {this.tick(eventData)}); 16 | CHIPPRAGI.subscribe('SYSTEM', (message) => {}); 17 | }, 18 | 19 | update: function (message) { 20 | // Do something when the component's data is updated, if needed. 21 | // entityId is the ID of the entity this component is attached to. 22 | // componentData contains the updated data for the component. 23 | let eventData = JSON.parse(message); 24 | if (eventData.eventType === 'taskCompleted') { 25 | this.handleCompleteTask(eventData); 26 | } 27 | }, 28 | 29 | remove: function (eventData) { 30 | // Do something when the component or its entity is detached, if needed. 31 | }, 32 | 33 | tick: function (eventData) { 34 | // Do something on every scene tick or frame, if needed. 35 | // entityId is the ID of the entity this component is attached to. 36 | // time is the current time in milliseconds. 37 | // timeDelta is the time in milliseconds since the last tick. 38 | }, 39 | 40 | handleCompleteTask: async function (data) { 41 | 42 | let taskDescription = CHIPPRAGI.getComponentData(data.payload.entityID, 'TaskDescription'); 43 | taskDescription = { ...taskDescription}; 44 | taskDescription.completed = true; 45 | CHIPPRAGI.setComponentData(data.payload.entityID, 'TaskDescription', taskDescription); 46 | CHIPPRAGI.MessageBus.updateMessage( 'taskIsComplete', data.payload.entityID, 'TaskDescription', this.info, parentData); 47 | } 48 | }); -------------------------------------------------------------------------------- /src/systems/active/WebsocketServerSystem.mjs: -------------------------------------------------------------------------------- 1 | import WebSocket, { WebSocketServer } from 'ws'; 2 | import { CHIPPRAGI } from "../../index.js"; 3 | 4 | CHIPPRAGI.registerSystem("WebsocketServerSystem", { 5 | info: { 6 | version: "0.1.0", 7 | license: "Apache-2.0", 8 | developer: "CHIPPRBOTS", 9 | type: "connector", 10 | description: "A system that manages WebSocket communication.", 11 | }, 12 | 13 | init: function () { 14 | this.webSocketServer = new WebSocketServer({ port: 8082 }); 15 | 16 | this.webSocketServer.on("connection", (socket) => { 17 | CHIPPRAGI.Logger.info( { system : "WebSocketSystem", log : " WS Client connected"}); 18 | socket.on("message", (message) => { 19 | //console.log(`Received message: ${message}`); 20 | CHIPPRAGI.Logger.info( { system : "WebSocketSystem", log : `newMessage: ${message}`}); 21 | this.handleClientMessage(message, socket); 22 | }); 23 | 24 | socket.on("close", () => { 25 | CHIPPRAGI.Logger.info( { system : "WebSocketSystem", log : "Client disconnected"}); 26 | }); 27 | }); 28 | 29 | // Subscribe to a specific event from other systems 30 | CHIPPRAGI.subscribe("UPDATE", (data) => { 31 | this.handleUpdateMessage(data); 32 | }); 33 | }, 34 | 35 | handleClientMessage: async function (message, socket) { 36 | // Handle the incoming message from the browser 37 | // You can use pubsub-js to communicate the message to other systems if needed 38 | const parsedMessage = JSON.parse(message); 39 | 40 | switch(parsedMessage.type){ 41 | case "getAllEntities": 42 | // get a list of all entities 43 | let allEntities = await CHIPPRAGI.getAllEntities('TaskParent'); 44 | let cleanEntities = []; 45 | allEntities.forEach( element => { 46 | cleanEntities.push(element.split('idx:entities:')[1]); 47 | }) 48 | socket.send(JSON.stringify({ type: "allEntities", data: cleanEntities })); 49 | break; 50 | case "getAllComponents": 51 | //get a list of all components 52 | let allComponents = CHIPPRAGI.components; 53 | CHIPPRAGI.Logger.info( { system : "WebSocketSystem", log : `allComponents: ${allComponents}`}); 54 | socket.send(JSON.stringify({ type: "allComponents", data : [allComponents]})); 55 | break; 56 | case "getComponent": 57 | let detail = await CHIPPRAGI.getComponentData( parsedMessage.entityID, parsedMessage.componentName); 58 | console.log(detail); 59 | socket.send(JSON.stringify({ type: "entityDetail", data : detail})); 60 | break; 61 | case "createObjective": 62 | CHIPPRAGI.MessageBus.updateMessage( 'createEntity', '0000000000', 'ObjectiveDescription', {}, { 63 | task : parsedMessage.data, 64 | }); 65 | break; 66 | default: 67 | //dump on the message bus 68 | let entityID = parsedMessage.entityID || null; 69 | let componentName = parsedMessage.componentName || 'websocket'; 70 | let sourceSystem = parsedMessage.sourceSystem || 'WebsocketServerSystem'; 71 | let data = parsedMessage.data || {}; 72 | CHIPPRAGI.MessageBus.updateMessage( parsedMessage.type, entityID, componentName, sourceSystem, data ); 73 | } 74 | }, 75 | 76 | handleUpdateMessage: function (data) { 77 | // Handle the message received from other systems via pubsub-js 78 | // If needed, you can send the message to the connected client(s) 79 | this.webSocketServer.clients.forEach((client) => { 80 | if (client.readyState === WebSocket.OPEN) { 81 | client.send(JSON.stringify(data)); 82 | } 83 | }); 84 | }, 85 | 86 | sendMessageToClient: function (socket, message) { 87 | // Send a message to the connected client 88 | socket.send(message); 89 | }, 90 | }); 91 | -------------------------------------------------------------------------------- /src/systems/inactive/EmptySystem.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | 3 | CHIPPRAGI.registerSystem('EmptySystem', { 4 | info: { 5 | version : "0.1.0", 6 | license : "APACHE-2.0", 7 | developer: "CHIPPRBOTS", 8 | description : "This is an empty example system.", 9 | }, 10 | 11 | init: function () { 12 | CHIPPRAGI.subscribe('UPDATE', (type, eventData) => {this.update(eventData)}); 13 | CHIPPRAGI.subscribe('REMOVE', (type, eventData) => {this.remove(eventData)}); 14 | CHIPPRAGI.subscribe('TICK', (type, eventData) => {this.tick(eventData)}); 15 | CHIPPRAGI.subscribe('SYSTEM', (type, eventData) => { 16 | this.handleEmptySystem(eventData.payload.data); 17 | }); 18 | }, 19 | 20 | update: function (eventData) { 21 | // Do something when the component's data is updated, if needed. 22 | // entityId is the ID of the entity this component is attached to. 23 | // componentData contains the updated data for the component. 24 | }, 25 | 26 | remove: function (eventData) { 27 | // Do something when the component or its entity is detached, if needed. 28 | }, 29 | 30 | tick: function (eventData) { 31 | // Do something on every scene tick or frame, if needed. 32 | // entityId is the ID of the entity this component is attached to. 33 | // time is the current time in milliseconds. 34 | // timeDelta is the time in milliseconds since the last tick. 35 | }, 36 | 37 | //methods go here 38 | handleEmptySystem: async function (){ 39 | //magic happens here 40 | }, 41 | 42 | }); 43 | -------------------------------------------------------------------------------- /src/systems/inactive/TaskEmbeddingSystem.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | 3 | CHIPPRAGI.registerSystem('TaskEmbeddingSystem', { 4 | info: { 5 | version : "0.1.0", 6 | license : "APACHE-2.0", 7 | developer: "CHIPPRBOTS", 8 | description : "This system creates an embedding for a task description that can be used for next neighbor lookup", 9 | }, 10 | 11 | init: function () { 12 | CHIPPRAGI.subscribe('UPDATE', (type, eventData) => {this.update(eventData)}); 13 | CHIPPRAGI.subscribe('REMOVE', (type, eventData) => {this.remove(eventData)}); 14 | CHIPPRAGI.subscribe('TICK', (type, eventData) => {this.tick(eventData)}); 15 | CHIPPRAGI.subscribe('SYSTEM', (type, eventData) => { 16 | if (eventData.eventType == 'newEntity') { 17 | setTimeout(async () => { 18 | this.handleNewEntity(eventData[0].payload.data) 19 | }, 20 | 5000) 21 | }; 22 | }); 23 | }, 24 | 25 | remove: function () { 26 | // Do something when the component or its entity is detached, if needed. 27 | }, 28 | 29 | //methods go here 30 | handleNewEntity: async function (data){ 31 | //look at how to do this with db 32 | let taskDescription = await CHIPPRAGI.getComponentData(data.entityID,'TaskDescription'); 33 | console.log(taskDescription); 34 | let clean_text = taskDescription.task.replace("\n", " ") 35 | //console.log(clean_text); 36 | let response= await CHIPPRAGI.langModel.createEmbedding({ 37 | model : "text-embedding-ada-002", 38 | input : clean_text 39 | }); 40 | //console.log(response.data.data[0].embedding); 41 | let floatbuffer = this.float32Buffer(response.data.data[0].embedding); 42 | let clean = response.data.data[0].embedding; 43 | //keep until everything is moved to db 44 | CHIPPRAGI.addComponent(data.entityID, 'TaskEmbedding', { 45 | entityID: data.entityID, 46 | clean: clean, 47 | floatbuffer: floatbuffer, 48 | }) 49 | }, 50 | 51 | float32Buffer(arr) { 52 | return Buffer.from(new Float32Array(arr).buffer) 53 | } 54 | 55 | }); 56 | 57 | -------------------------------------------------------------------------------- /src/systems/inactive/TaskExecutionSystem.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | 3 | CHIPPRAGI.registerSystem('TaskExecutionSystem', { 4 | info: { 5 | version : "0.1.0", 6 | license : "APACHE-2.0", 7 | developer: "CHIPPRBOTS", 8 | description : "This system listens for execute task message and sends the task along with context to get longer text ", 9 | }, 10 | 11 | init: function (eventData) { 12 | CHIPPRAGI.subscribe('UPDATE', (type, eventData) => {this.update(eventData)}); 13 | CHIPPRAGI.subscribe('REMOVE', (type, eventData) => {this.remove(eventData)}); 14 | CHIPPRAGI.subscribe('TICK', (type, eventData) => {this.tick(eventData)}); 15 | CHIPPRAGI.subscribe('SYSTEM', (type, eventData) => { 16 | this.handleExecuteTask(eventData[0].payload.data) 17 | }, 18 | 5000); 19 | }, 20 | 21 | remove: function (eventData) { 22 | // Do something when the component or its entity is detached, if needed. 23 | }, 24 | 25 | 26 | handleExecuteTask(data) { 27 | // Execute the task associated with the given taskId 28 | // You can access the components associated with the taskId to perform the task execution 29 | // 1) get embedding which should be stored in the db 30 | // 2) get neighbors using knn from vectorDB 31 | // 3) get the execution prompt 32 | // 4) generate using the prompt 33 | // 5) emit storeTask( taskID, response,) 34 | // 6) emit taskCheck( taskID ) 35 | } 36 | }); -------------------------------------------------------------------------------- /src/systems/inactive/TaskExpanderSystem.mjs: -------------------------------------------------------------------------------- 1 | import { CHIPPRAGI } from "../../index.js"; 2 | import { TaskExpanderPrompt } from '../../prompts/TaskExpanderPrompt.js' 3 | 4 | 5 | CHIPPRAGI.registerSystem('TaskExpanderSystem', { 6 | info: { 7 | version : "0.1.0", 8 | license : "APACHE-2.0", 9 | developer: "CHIPPRBOTS", 10 | type: 'system', 11 | description : "This system expands the details of the a task so that it is well explained", 12 | }, 13 | 14 | init: function () { 15 | CHIPPRAGI.subscribe('UPDATE', (eventData) => {this.update(eventData)}); 16 | CHIPPRAGI.subscribe('REMOVE', (type, eventData) => {this.remove(eventData)}); 17 | CHIPPRAGI.subscribe('TICK', (type, eventData) => {this.tick(eventData)}); 18 | CHIPPRAGI.subscribe('UPDATE', (message) => {this.update(message)}); 19 | }, 20 | 21 | update: function (message) { 22 | // Do something when the component's data is updated, if needed. 23 | // entityId is the ID of the entity this component is attached to. 24 | // componentData contains the updated data for the component. 25 | let eventData = JSON.parse(message); 26 | switch(eventData.eventType){ 27 | case 'systemSelected' : 28 | //CHIPPRAGI.Logger.error({system: 'TaskExpanderSystem.update', log: eventData}); 29 | //make sure the system is selected 30 | if(eventData.payload.data == "TaskExpanderSystem") { 31 | this.handleExpandTask(eventData); 32 | } 33 | break; 34 | default: 35 | } 36 | }, 37 | 38 | remove: function (eventData) { 39 | // Do something when the component or its entity is detached, if needed. 40 | // add logic to remove an entity arrivesent arrives 41 | }, 42 | 43 | handleExpandTask : async function (eventData) { 44 | //3) replace varaible with context 45 | let entityDescription = await CHIPPRAGI.getComponentData(eventData.payload.entityID, 'TaskDescription'); 46 | //CHIPPRAGI.Logger.error({system: 'TaskExpanderSystem.entityDescription', log: null , task: entityDescription} ); 47 | let prompt = []; 48 | (TaskExpanderPrompt.task_prompt).forEach( t => { 49 | // console.log(objectiveDescription.objective); 50 | prompt.push(t.replace('{{ taskDescription }}', entityDescription.objective || entityDescription.task)); 51 | },prompt); 52 | //CHIPPRAGI.Logger.error({system: 'TaskExpanderSystem.prompt', log: null , task: prompt} ); 53 | //4) generate tasks 54 | //todo loop until a valid object is returned 55 | let success = false; 56 | //throw error; 57 | let expandedTask; 58 | //CHIPPRAGI.Logger.error({system: 'TaskExpanderSystem.expandedTask', log: null , task: expandedTask} ); 59 | while (!success){ 60 | //5) generate event to create for each tasks 61 | try { 62 | expandedTask = await CHIPPRAGI.LangModel.generate(prompt.join('\n')); 63 | //console.error(expandedTask) 64 | //CHIPPRAGI.Logger.error({system: 'TaskExpanderSystem.newTask', log: null, task: expandedTask.join('\n')} ); 65 | expandedTask.forEach( async task => { 66 | console.log(task); 67 | let newTask = { ...task}; 68 | newTask.expandedTask = expandedTask.taskDetails; 69 | newTask.justification = expandedTask.justification; 70 | //CHIPPRAGI.Logger.error({system: 'TaskExpanderSystem.newTask', log: null, task: newTask} ); 71 | await CHIPPRAGI.addComponent( data.payload.entityID, 'TaskExpanded', newTask ); 72 | //send it to the judge 73 | //CHIPPRAGI.MessageBus.updateMessage('taskCompleted', data.payload.entityID, 'TaskExpanded', this.info, newTask); 74 | }); 75 | success = true; 76 | } catch(error) { 77 | // the response was not json so we need to try again console.logging for trouble shoooting 78 | CHIPPRAGI.Logger.error({system: 'TaskExpanderSystem.error', log: JSON.stringify(expandedTask), error: error}); 79 | 80 | } 81 | } 82 | }, 83 | }); 84 | 85 | -------------------------------------------------------------------------------- /test/components/index.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chippr-robotics/chippr-agi/5420cae80d804c905916a1bb151189f25761d709/test/components/index.js -------------------------------------------------------------------------------- /test/core/index.js: -------------------------------------------------------------------------------- 1 | //test all core functions 2 | 3 | //test langmodel - no dependencies 4 | require('./langModel.test'); 5 | //test vectorDB - no dependencies 6 | require('./vector-db.test'); -------------------------------------------------------------------------------- /test/core/langModel.testold.js: -------------------------------------------------------------------------------- 1 | var expect = require("chai").expect; 2 | var { LangModel } = require('../../core'); 3 | 4 | //tests the core system class 5 | describe("Core: LangModel Class function testing", function() { 6 | //setup the system for testing 7 | before(() => { 8 | require('dotenv').config(); 9 | }); 10 | describe("Class testing", function() { 11 | it("should allow new LangModel to be created", function() { 12 | let test = LangModel; 13 | //validate that test created a new system 14 | expect(test).to.not.be.undefined; 15 | }); 16 | }); 17 | }); -------------------------------------------------------------------------------- /test/core/vector-db.testold.js: -------------------------------------------------------------------------------- 1 | var expect = require("chai").expect; 2 | var { VectorDb } = require('../../core'); 3 | require('dotenv').config(); 4 | 5 | 6 | describe("VectorDB function testing", function() { 7 | let redisURL = process.env.REDIS_URL; 8 | let indexName = process.env.INDEX_NAME; 9 | const testTask = require('../testTask.json'); 10 | 11 | describe("Basic class testing", function() { 12 | it("should allow new vectorDB given agentID and redis url", function() { 13 | //this step should create an new index as well for the index name. 14 | let test = new VectorDb( indexName, {url: redisURL} ); // Initialize vector database 15 | expect(test.indexName).to.equal(indexName); 16 | expect(test.redisClient).to.not.be.undefined; 17 | test.redisClient.quit(); 18 | }); 19 | }); 20 | describe("Class functions", function() { 21 | let vectorDb; 22 | beforeEach(() => { 23 | //this step should create an new index as well for the index name. 24 | vectorDb = new VectorDb( indexName, {url: redisURL} ); // Initialize vector database 25 | }); 26 | //close the db connection 27 | afterEach(async () => await vectorDb.redisClient.disconnect()); 28 | 29 | describe("Create DB index", function() { 30 | it("should create an index if the index does not exist", async function() { 31 | let list = await vectorDb.redisClient.ft._list(); 32 | //drop index if it exists already 33 | if(list.indexOf(indexName) > -1) await vectorDb.redisClient.ft.DROPINDEX( indexName, 'DD' ); 34 | let test = await vectorDb.create(); 35 | list = await vectorDb.redisClient.ft._list(); 36 | let test2 = list.indexOf(indexName) > -1; 37 | expect(test).to.equal(true); 38 | expect(test2).to.equal(true); 39 | }); 40 | it("should not create an index if the index does exist", async function() { 41 | //get a list of indexes 42 | let list = await vectorDb.redisClient.ft._list(); 43 | //create index if it doesnt exist already 44 | if(!(list.indexOf(indexName) > -1)) await vectorDb.create(); 45 | let test = await vectorDb.create(); 46 | let test2 = list.indexOf(indexName) > -1; 47 | expect(test).to.equal(false); 48 | expect(test2).to.equal(true); 49 | }) 50 | }); 51 | describe("Write/Read testing ", function(){ 52 | it("should write to the db ", async function() { 53 | let test = await vectorDb.save( 'TEST', testTask.taskid, testTask); 54 | expect(test).to.equal(true); 55 | }); 56 | it("should read from the db ", async function() { 57 | let task = await vectorDb.get('TEST', testTask.taskid); 58 | expect(task.taskid).to.equal(testTask.taskid); 59 | }); 60 | }); 61 | }); 62 | }); -------------------------------------------------------------------------------- /test/index.test.js: -------------------------------------------------------------------------------- 1 | //set the environmental variables 2 | //(todo) have a test env config 3 | //require('dotenv').config(); 4 | import {expect} from 'chai'; 5 | //test core functions 6 | //require('./core'); 7 | describe('core Testing', () => {}); 8 | //tests for systems 9 | //require('./systems'); 10 | 11 | //test for components 12 | //require('./components'); -------------------------------------------------------------------------------- /test/systems/index.js: -------------------------------------------------------------------------------- 1 | //test files for systems 2 | // each system should have its own test file that matches the system name 3 | // to add a test require it here 4 | 5 | //require('./taskCreationSystem.test'); 6 | -------------------------------------------------------------------------------- /test/systems/taskCreationSystem.testold.js: -------------------------------------------------------------------------------- 1 | var expect = require("chai").expect; 2 | const EventEmitter = require('events'); 3 | //create a test agi 4 | const { ChipprAGI } = require('../../index.js'); 5 | var system = require('../../systems/TaskCreationSystem'); 6 | 7 | // get any components the system uses 8 | //var TaskDescriptionComponent = require('../../components/TaskDescription'); 9 | //tests 10 | 11 | describe("TaskCreationSystem function testing", function() { 12 | 13 | before(() => { 14 | require('dotenv').config(); 15 | }); 16 | //setup the system for testing 17 | describe("Basic class testing", function() { 18 | it("should allow new TaskCreationSystem to be created", function() { 19 | let testEventEmitter = new EventEmitter(); 20 | system.init(testEventEmitter); 21 | }); 22 | }); 23 | 24 | }); 25 | -------------------------------------------------------------------------------- /test/testTask.json: -------------------------------------------------------------------------------- 1 | { 2 | "taskid": "9f8a4b8df3", 3 | "task": "This is a task to test the system", 4 | "done": false, 5 | "dependencies": [] 6 | } --------------------------------------------------------------------------------