├── .eslintrc.json ├── .github ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── deploy-website.yml │ ├── labs-prototypes-ci.yml │ └── publish.yml ├── .gitignore ├── .prettierrc ├── .vscode └── launch.json ├── DEVELOPING.md ├── LICENSE ├── README.md ├── core └── tsconfig │ ├── base.json │ └── package.json ├── docs ├── code-of-conduct.md └── contributing.md ├── graphs.code-workspace ├── package-lock.json ├── package.json ├── seeds ├── README.md ├── breadboard │ └── README.md ├── chunker-python │ ├── LICENSE │ ├── README.md │ ├── pyproject.toml │ ├── src │ │ ├── google_labs_html_chunker │ │ │ ├── __init__.py │ │ │ └── html_chunker.py │ │ └── main.py │ └── tests │ │ └── test_html_chunker.py ├── chunker │ ├── .gitignore │ ├── .npmignore │ ├── README.md │ ├── cli.js │ ├── package.json │ ├── src │ │ ├── basic.ts │ │ └── index.ts │ ├── tests │ │ ├── chunker-all.ts │ │ └── data │ │ │ ├── makers-1-greedy.json │ │ │ ├── makers-1.json │ │ │ ├── non-peers-to-chunk-1.json │ │ │ ├── simple-one-chunk.json │ │ │ ├── simple-one-non-peers.json │ │ │ └── simplest.json │ └── tsconfig.json ├── discovery-types │ ├── .npmignore │ ├── README.md │ ├── docs │ │ └── api │ │ │ ├── .nojekyll │ │ │ ├── README.md │ │ │ └── modules.md │ ├── package.json │ ├── src │ │ ├── converter.ts │ │ └── index.ts │ ├── tests │ │ └── index.ts │ └── tsconfig.json ├── gemini-guide │ ├── eleventy.config.cjs │ ├── package.json │ ├── src │ │ ├── _includes │ │ │ ├── footer.njk │ │ │ ├── gallery.njk │ │ │ ├── head.njk │ │ │ ├── header.njk │ │ │ └── pattern.njk │ │ ├── index.html │ │ ├── js │ │ │ └── placeholder.ts │ │ ├── patterns │ │ │ ├── bar │ │ │ │ └── index.md │ │ │ ├── baz │ │ │ │ └── index.md │ │ │ ├── foo │ │ │ │ └── index.md │ │ │ └── qux │ │ │ │ └── index.md │ │ └── static │ │ │ ├── common.css │ │ │ ├── gallery.css │ │ │ ├── images │ │ │ └── gemini-logo.svg │ │ │ ├── pattern.css │ │ │ ├── styles │ │ │ └── prism-syntax-highlight.css │ │ │ └── third_party │ │ │ ├── github │ │ │ └── github-mark.svg │ │ │ └── icons │ │ │ ├── check-circle.svg │ │ │ ├── copy-to-clipboard.svg │ │ │ ├── lightbulb.svg │ │ │ ├── link.svg │ │ │ ├── menu.svg │ │ │ ├── note.svg │ │ │ └── warning.svg │ └── tsconfig.json ├── gems │ ├── text_classification │ │ ├── 20_newsgroups │ │ │ └── train_text_classifier_embeddings.ipynb │ │ └── README.md │ └── tokenizer │ │ └── (public_version)_Tokenization_Playground.ipynb ├── palm-lite │ ├── .npmignore │ ├── CHANGELOG.md │ ├── README.md │ ├── docs │ │ └── api │ │ │ ├── .nojekyll │ │ │ ├── README.md │ │ │ ├── classes │ │ │ ├── Chat.md │ │ │ └── Text.md │ │ │ ├── enums │ │ │ └── PalmModelMethod.md │ │ │ ├── interfaces │ │ │ ├── CitationMetadata.md │ │ │ ├── CitationSource.md │ │ │ ├── ContentFilter.md │ │ │ ├── CountMessageTokensRequest.md │ │ │ ├── CountMessageTokensResponse.md │ │ │ ├── EmbedTextRequest.md │ │ │ ├── EmbedTextResponse.md │ │ │ ├── Embedding.md │ │ │ ├── Example.md │ │ │ ├── GenerateMessageRequest.md │ │ │ ├── GenerateMessageResponse.md │ │ │ ├── GenerateTextRequest.md │ │ │ ├── GenerateTextResponse.md │ │ │ ├── ListModelsResponse.md │ │ │ ├── Message.md │ │ │ ├── MessagePrompt.md │ │ │ ├── Model.md │ │ │ ├── PartialGenerateMessageRequest.md │ │ │ ├── PartialGenerateTextRequest.md │ │ │ ├── SafetyFeedback.md │ │ │ ├── SafetyRating.md │ │ │ ├── SafetySetting.md │ │ │ ├── TextCompletion.md │ │ │ └── TextPrompt.md │ │ │ └── modules.md │ ├── package.json │ ├── scripts │ │ ├── make-models.js │ │ └── make-types.js │ ├── src │ │ ├── chat.ts │ │ ├── index.ts │ │ ├── models.ts │ │ ├── text.ts │ │ └── types.ts │ ├── tests │ │ ├── chat.ts │ │ ├── index.ts │ │ └── text.ts │ └── tsconfig.json └── team-experiments │ ├── .gitignore │ ├── README.md │ ├── api │ ├── proxy.ts │ └── secrets.ts │ ├── graphs │ └── boards │ │ ├── ad-writer-best-of-n.json │ │ ├── blank.json │ │ ├── collector-loop.json │ │ ├── collector.json │ │ ├── subgraph-example-map.json │ │ └── subgraph-example.json │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── public │ ├── bgl │ │ ├── book │ │ │ ├── outline-critic.json │ │ │ ├── outline-editor.bgl.json │ │ │ ├── outline-exampe.bgl.json │ │ │ ├── outline-writer.bgl.json │ │ │ └── writing-team.bgl.json │ │ ├── insta │ │ │ ├── chat-and-research.bgl.json │ │ │ ├── chat-with-tools-prompted.json │ │ │ ├── chat-with-tools.bgl.json │ │ │ ├── generate-post.json │ │ │ ├── get-page.json │ │ │ ├── loop-example.json │ │ │ ├── mock-conversation.bgl.json │ │ │ ├── mock-get-page.json │ │ │ ├── onboard-for-social.json │ │ │ ├── simple-chat.bgl.json │ │ │ ├── specialist-tools.bgl.json │ │ │ ├── tool-get-web-page.bgl.json │ │ │ ├── tool-page-screenshot-content.json │ │ │ ├── tool-page-screenshot.json │ │ │ └── tool-search.bgl.json │ │ ├── json-schema-wizard.json │ │ ├── test-invokes.bgl.json │ │ ├── today.bgl.json │ │ └── use-tools.bgl.json │ ├── styles │ │ └── global.css │ └── third_party │ │ └── icons │ │ ├── README.md │ │ ├── add-blue.svg │ │ ├── add-circle.svg │ │ ├── add-note.svg │ │ ├── add-photo.svg │ │ ├── add.svg │ │ ├── arrow-back-white.svg │ │ ├── arrow-back.svg │ │ ├── assets │ │ ├── application-pdf.svg │ │ ├── generic.svg │ │ └── image-png.svg │ │ ├── before.svg │ │ ├── close.svg │ │ ├── collapse.svg │ │ ├── copy-to-clipboard.svg │ │ ├── delete.svg │ │ ├── download.svg │ │ ├── edit.svg │ │ ├── error.svg │ │ ├── expand.svg │ │ ├── history.svg │ │ ├── info.svg │ │ ├── menu.svg │ │ ├── next.svg │ │ ├── preview.svg │ │ ├── quick-jump.svg │ │ ├── refresh.svg │ │ ├── reset-alt.svg │ │ ├── reset-image.svg │ │ ├── reset.svg │ │ ├── resume-blue.svg │ │ ├── roles │ │ ├── historian.svg │ │ └── team-lead.svg │ │ ├── save.svg │ │ ├── search.svg │ │ ├── send-blue.svg │ │ ├── settings.svg │ │ ├── start.svg │ │ └── warning.svg │ ├── src │ ├── boards │ │ ├── ad-writer-best-of-n.ts │ │ ├── blank.ts │ │ ├── collector-loop.ts │ │ ├── collector.ts │ │ ├── subgraph-example-map.ts │ │ └── subgraph-example.ts │ ├── breadboard │ │ ├── README.md │ │ ├── events.ts │ │ ├── index.ts │ │ ├── runner.ts │ │ └── types.ts │ ├── constants │ │ └── constants.ts │ ├── events │ │ └── events.ts │ ├── mock │ │ ├── activity.ts │ │ ├── assets.ts │ │ ├── conversation.ts │ │ └── team-list.ts │ ├── router │ │ └── router.ts │ ├── server │ │ ├── api.ts │ │ ├── browse.ts │ │ ├── common.ts │ │ ├── errors.ts │ │ ├── index.ts │ │ └── static.ts │ ├── types │ │ └── types.ts │ └── ui │ │ ├── directives │ │ └── markdown.ts │ │ ├── elements │ │ ├── assets-list │ │ │ └── assets-list.ts │ │ ├── conversation │ │ │ ├── conversation.ts │ │ │ └── multi-part-input.ts │ │ ├── elements.ts │ │ ├── switcher │ │ │ └── switcher.ts │ │ ├── team-activity │ │ │ └── team-activity.ts │ │ ├── team-job │ │ │ └── team-job.ts │ │ └── team-list │ │ │ └── team-list.ts │ │ ├── index.ts │ │ ├── secrets.ts │ │ └── utils │ │ ├── asBase64.ts │ │ ├── clamp.ts │ │ └── toRelativeTime.ts │ ├── tsconfig.json │ └── vite.config.ts ├── templates └── blank │ ├── .npmignore │ ├── README.md │ ├── package.json │ ├── src │ └── index.ts │ └── tsconfig.json └── tsconfig.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": [ 7 | "eslint:recommended", 8 | "plugin:@typescript-eslint/recommended" 9 | ], 10 | "overrides": [ 11 | ], 12 | "parser": "@typescript-eslint/parser", 13 | "parserOptions": { 14 | "ecmaVersion": "latest", 15 | "sourceType": "module" 16 | }, 17 | "plugins": [ 18 | "@typescript-eslint" 19 | ], 20 | "rules": { 21 | "@typescript-eslint/no-unused-vars": ["warn", {"argsIgnorePattern": "_.*"}] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Expected Behavior 2 | 3 | 4 | ## Actual Behavior 5 | 6 | 7 | ## Steps to Reproduce the Problem 8 | 9 | 1. 10 | 1. 11 | 1. 12 | 13 | ## Specifications 14 | 15 | - Version: 16 | - Platform: -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Fixes # 2 | 3 | > It's a good idea to open an issue first for discussion. 4 | 5 | - [ ] Tests pass 6 | - [ ] Appropriate changes to documentation are included in the PR 7 | -------------------------------------------------------------------------------- /.github/workflows/deploy-website.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Website 2 | on: 3 | # Deploy whenever we merge to main. 4 | push: 5 | branches: ["main"] 6 | 7 | # Allows deploying manually from the Actions tab 8 | workflow_dispatch: 9 | 10 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages 11 | permissions: 12 | contents: read 13 | pages: write 14 | id-token: write 15 | 16 | # Allow only one concurrent deployment, skipping runs queued between the run 17 | # in-progress and latest queued. However, do NOT cancel in-progress runs as we 18 | # want to allow these production deployments to complete. 19 | concurrency: 20 | group: deploy-website 21 | cancel-in-progress: false 22 | 23 | jobs: 24 | deploy-website: 25 | environment: 26 | name: github-pages 27 | url: ${{ steps.deployment.outputs.page_url }} 28 | 29 | runs-on: ubuntu-latest 30 | 31 | steps: 32 | - uses: actions/checkout@v4 33 | - uses: actions/setup-node@v4 34 | with: 35 | node-version: 20 36 | cache: npm 37 | - uses: google/wireit@setup-github-actions-caching/v1 38 | - uses: actions/configure-pages@v4 39 | 40 | - run: npm ci 41 | 42 | - name: Build production website 43 | working-directory: seeds/gemini-guide 44 | run: npm run build:prod 45 | 46 | - name: Upload website artifact 47 | uses: actions/upload-pages-artifact@v3 48 | with: 49 | name: labs-prototypes-website 50 | path: seeds/gemini-guide/dist/prod/labs-prototypes 51 | 52 | - name: Deploy to GitHub Pages 53 | uses: actions/deploy-pages@v4 54 | with: 55 | artifact_name: labs-prototypes-website 56 | -------------------------------------------------------------------------------- /.github/workflows/labs-prototypes-ci.yml: -------------------------------------------------------------------------------- 1 | name: Labs Prototypes CI 2 | 3 | on: 4 | push: 5 | branches: ["main"] 6 | pull_request: 7 | branches: ["main"] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | node-version: [20.x] 15 | 16 | steps: 17 | - uses: actions/checkout@v3 18 | - name: Use Node.js ${{ matrix.node-version }} 19 | uses: actions/setup-node@v3 20 | with: 21 | node-version: ${{ matrix.node-version }} 22 | cache: "npm" 23 | - uses: google/wireit@setup-github-actions-caching/v1 24 | 25 | - name: Clean Installing dependencies 26 | run: npm run ci 27 | 28 | - name: Generating the build 29 | run: npm run build 30 | 31 | - name: Checking the code quality 32 | run: npm run lint 33 | 34 | - name: Checking the code formatting 35 | run: npm run check:format 36 | 37 | - name: Running tests 38 | run: npm run test 39 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | # Publish to npm when we run a workflow manually. 2 | on: [workflow_dispatch] 3 | name: publish-to-npm 4 | permissions: {} 5 | jobs: 6 | release-please: 7 | # TODO: read GitHub actions docs and lock down correct permissions. 8 | permissions: 9 | contents: read 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v3 13 | - uses: actions/setup-node@v3 14 | with: 15 | node-version: 18 16 | - uses: google/wireit@setup-github-actions-caching/v1 17 | - run: npm install 18 | - run: npm run build 19 | - uses: actions/setup-node@v3 20 | with: 21 | node-version: 18 22 | registry-url: "https://wombat-dressing-room.appspot.com/" 23 | - name: npm publish 24 | run: | 25 | cd seeds/palm-lite/ 26 | npm publish --access=public 27 | env: 28 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} 29 | -------------------------------------------------------------------------------- /.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 | 106 | .gitpod.yml 107 | 108 | # Ignore .devcontainer bits for now 109 | .devcontainer 110 | 111 | .DS_Store 112 | 113 | 114 | */__pycache__/ 115 | *.py[cod] 116 | 117 | .firebase/ 118 | .firebaserc 119 | 120 | *.local.ts 121 | *.local.json 122 | *.local.md 123 | 124 | .wireit 125 | settings.json 126 | .vercel 127 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "always", 3 | "printWidth": 80, 4 | "semi": true, 5 | "tabWidth": 2, 6 | "trailingComma": "es5", 7 | "useTabs": false 8 | } 9 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Attach", 9 | "port": 9229, 10 | "request": "attach", 11 | "skipFiles": ["/**"], 12 | "type": "node" 13 | }, 14 | { 15 | "name": "Python: Current File", 16 | "type": "python", 17 | "request": "launch", 18 | "program": "${file}", 19 | "console": "integratedTerminal", 20 | "args": ["seeds/graph-playground/graphs/accumulating-context.json"], 21 | "justMyCode": true 22 | }, 23 | { 24 | "name": "Launch Program", 25 | "request": "launch", 26 | "skipFiles": ["/**"], 27 | "cwd": "${workspaceFolder}", 28 | "console": "integratedTerminal", 29 | "program": "${workspaceFolder}/seeds/graph-playground/src/index.ts", 30 | "args": ["seeds/graph-playground/graphs/math.json"], 31 | "outFiles": ["${workspaceFolder}/**/*.js"], 32 | "runtimeVersion": "20.4.0", 33 | "type": "node" 34 | }, 35 | { 36 | "type": "node", 37 | "request": "launch", 38 | "name": "Launch Program", 39 | "skipFiles": ["/**"], 40 | "program": "${workspaceFolder}/seeds/graph-playground/src/index.ts", 41 | "runtimeArgs": [ 42 | "seeds/graph-playground/graphs/accumulating-context.json" 43 | ], 44 | "outFiles": ["${workspaceFolder}/**/*.js"] 45 | }, 46 | { 47 | "type": "node", 48 | "request": "launch", 49 | "name": "Debug AVA test file", 50 | "program": "${workspaceFolder}/node_modules/ava/entrypoints/cli.mjs", 51 | "args": [ 52 | "${file}" 53 | ], 54 | "cwd": "${fileDirname}", 55 | "outputCapture": "std", 56 | "console": "integratedTerminal", 57 | "skipFiles": [ 58 | "/**/*.js" 59 | ] 60 | } 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > [!NOTE] 2 | > The Breadboard project has recently graduated to a new dedicated home at https://github.com/breadboard-ai/breadboard/. Please update your links! 3 | 4 | # Labs Prototyping Project 5 | 6 | This is a repository for rapid prototyping and lightweight experiments. 7 | -------------------------------------------------------------------------------- /core/tsconfig/base.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "compilerOptions": { 4 | "composite": false, 5 | "declaration": true, 6 | "declarationMap": true, 7 | "incremental": true, 8 | "esModuleInterop": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "inlineSources": false, 11 | "lib": ["ES2022", "DOM"], 12 | "module": "NodeNext", 13 | "target": "ES2022", 14 | "isolatedModules": true, 15 | "allowJs": true, 16 | "noUnusedLocals": false, 17 | "noUnusedParameters": false, 18 | "preserveWatchOutput": true, 19 | "skipLibCheck": true, 20 | "sourceMap": true, 21 | "strict": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /core/tsconfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@google-labs/tsconfig", 3 | "description": "Repo-specific configuration for all TypeScript projects", 4 | "version": "0.0.1", 5 | "private": true 6 | } 7 | -------------------------------------------------------------------------------- /docs/contributing.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We would love to accept your patches and contributions to this project. 4 | 5 | ## Before you begin 6 | 7 | ### Sign our Contributor License Agreement 8 | 9 | Contributions to this project must be accompanied by a 10 | [Contributor License Agreement](https://cla.developers.google.com/about) (CLA). 11 | You (or your employer) retain the copyright to your contribution; this simply 12 | gives us permission to use and redistribute your contributions as part of the 13 | project. 14 | 15 | If you or your current employer have already signed the Google CLA (even if it 16 | was for a different project), you probably don't need to do it again. 17 | 18 | Visit to see your current agreements or to 19 | sign a new one. 20 | 21 | ### Review our Community Guidelines 22 | 23 | This project follows [Google's Open Source Community 24 | Guidelines](https://opensource.google/conduct/). 25 | 26 | ## Contribution process 27 | 28 | Since this is a repository for rapid prototyping and lightweight experiments, there are high chances for any of us to find issues on the code, test case failures etc at any time. In order to maintain the pace of the contribution rate we are employing two different strategies to tackle these problems. 29 | 30 | - ### Fix-Forward stance 31 | - ### Rollback stance 32 | 33 | ### Fix-Forward stance 34 | 35 | We will follow Fix-Forward stance when we find issues on the committed code which doesn't block the development of the team in our codebase we will keep moving forward with our current development and we will fix that issues on the upcoming commits. 36 | In some cases when there is a major breaking change introduced to the code which blocks the team's progress, we will share the responsibility (we can also split the work among other team members if needed) and fix the issue together as a team. 37 | 38 | ### Rollback stance 39 | 40 | We will follow Rollback stance when we start to work on the core functionalities. Whenever there is some issue on the code, we will reject the commit from the branch and the person who worked on the commit will fix the problem. 41 | 42 | ## Code Reviews 43 | 44 | Here code reviews are optional* with some exceptions i.e once you complete your work and if you are confident enough that your commit will not cause any problems, you can merge the pull request to the main . Otherwise All submissions, including submissions by project members, require review. We use [GitHub pull requests](https://docs.github.com/articles/about-pull-requests) for this purpose. 45 | -------------------------------------------------------------------------------- /graphs.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "name": "graph-playground", 5 | "path": "seeds/graph-playground" 6 | }, 7 | { 8 | "name": "breadboard", 9 | "path": "seeds/breadboard" 10 | }, 11 | { 12 | "name": "llm-starter", 13 | "path": "seeds/llm-starter" 14 | }, 15 | { 16 | "name": "graph-integrity", 17 | "path": "seeds/graph-integrity" 18 | }, 19 | { 20 | "name": "palm-lite", 21 | "path": "seeds/palm-lite" 22 | }, 23 | { 24 | "name": "node-nursery", 25 | "path": "seeds/node-nursery" 26 | }, 27 | { 28 | "name": "node-nursery-web", 29 | "path": "seeds/node-nursery-web" 30 | }, 31 | { 32 | "name": "coffee-bot-board", 33 | "path": "seeds/coffee-bot-board" 34 | }, 35 | { 36 | "name": "cloud-function", 37 | "path": "seeds/cloud-function" 38 | }, 39 | { 40 | "name": "breadboard-server", 41 | "path": "seeds/breadboard-server" 42 | }, 43 | { 44 | "name": "pinecone-kit", 45 | "path": "seeds/pinecone-kit" 46 | }, 47 | { 48 | "name": "breadboard-web", 49 | "path": "seeds/breadboard-web" 50 | }, 51 | { 52 | "name": "chunker", 53 | "path": "seeds/chunker" 54 | }, 55 | { 56 | "name": "core-kit", 57 | "path": "seeds/core-kit" 58 | }, 59 | { 60 | "path": "seeds/palm-kit" 61 | }, 62 | { 63 | "path": "seeds/node-proxy-server" 64 | }, 65 | { 66 | "path": "seeds/json-kit" 67 | }, 68 | { 69 | "path": "seeds/breadboard-ui" 70 | } 71 | ], 72 | "settings": {} 73 | } 74 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "version": "0.0.1", 4 | "description": "Google Labs repo for rapid prototyping", 5 | "type": "module", 6 | "scripts": { 7 | "sync": "npm i && npm run clean:build && npm run build", 8 | "test": "wireit", 9 | "build": "wireit", 10 | "lint": "wireit", 11 | "deep-clean:build": "rm -rf node_modules seeds/*/node_modules package-lock.json && npm run sync", 12 | "clean:build": "rimraf -g seeds/*/dist seeds/*/.wireit", 13 | "ci": "npm ci", 14 | "check:format": "prettier --check --config .prettierrc seeds/*/src/**/*.ts", 15 | "ci:local": "wireit" 16 | }, 17 | "wireit": { 18 | "build": { 19 | "dependencies": [ 20 | "./seeds/chunker:build", 21 | "./seeds/discovery-types:build", 22 | "./seeds/gemini-guide:build", 23 | "./seeds/palm-lite:build" 24 | ] 25 | }, 26 | "test": { 27 | "dependencies": [ 28 | "./seeds/chunker:test", 29 | "./seeds/discovery-types:test", 30 | "./seeds/palm-lite:test" 31 | ] 32 | }, 33 | "lint": { 34 | "dependencies": [ 35 | "./seeds/chunker:lint", 36 | "./seeds/discovery-types:lint", 37 | "./seeds/palm-lite:lint" 38 | ] 39 | }, 40 | "ci:local": { 41 | "dependencies": [ 42 | "build", 43 | "check:format", 44 | "lint", 45 | "test" 46 | ] 47 | } 48 | }, 49 | "keywords": [], 50 | "author": "Google Labs Team", 51 | "license": "Apache-2.0", 52 | "devDependencies": { 53 | "@types/node": "^18.19.31", 54 | "@typescript-eslint/eslint-plugin": "^5.62.0", 55 | "@typescript-eslint/parser": "^5.62.0", 56 | "ava": "^5.3.1", 57 | "eslint": "^8.57.0", 58 | "npm-ci": "^0.0.2", 59 | "rimraf": "^5.0.5", 60 | "typescript": "^5.4.5", 61 | "wireit": "^0.14.4" 62 | }, 63 | "workspaces": [ 64 | "./core/*", 65 | "./seeds/*" 66 | ] 67 | } 68 | -------------------------------------------------------------------------------- /seeds/README.md: -------------------------------------------------------------------------------- 1 | A directory for projects that are early experiments and things that aren't fully fleshed out. -------------------------------------------------------------------------------- /seeds/breadboard/README.md: -------------------------------------------------------------------------------- 1 | > [!CAUTION] 2 | > The Breadboard project has recently graduated to a new dedicated home at https://github.com/breadboard-ai/breadboard/. Please update your links! 3 | -------------------------------------------------------------------------------- /seeds/chunker-python/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2023 Google LLC 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /seeds/chunker-python/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["hatchling"] 3 | build-backend = "hatchling.build" 4 | 5 | [project] 6 | name = "google_labs_html_chunker" 7 | version = "0.0.5" 8 | authors = [ 9 | { name="Google Labs", email="labs-pypi@google.com" }, 10 | ] 11 | description = "A library to chunk HTML web pages into plain text passages." 12 | readme = "README.md" 13 | requires-python = ">=3.6" 14 | dependencies = [ 15 | "beautifulsoup4>=4.12.2", 16 | "html5lib>=1.1" 17 | ] 18 | classifiers = [ 19 | "Programming Language :: Python :: 3", 20 | "License :: OSI Approved :: Apache Software License", 21 | "Operating System :: OS Independent", 22 | ] -------------------------------------------------------------------------------- /seeds/chunker-python/src/google_labs_html_chunker/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/google/labs-prototypes/5666a92183f3c6be78e8a16a0efec4b7ec641f0a/seeds/chunker-python/src/google_labs_html_chunker/__init__.py -------------------------------------------------------------------------------- /seeds/chunker-python/src/main.py: -------------------------------------------------------------------------------- 1 | # Copyright 2023 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | import argparse 15 | from google_labs_html_chunker.html_chunker import HtmlChunker 16 | 17 | # Main function to try out HtmlChunker on a saved html file. 18 | # 19 | # Example usage: 20 | # python3 main.py -i path/to/input_file.html -o path/to/output_file.txt --maxwords 200 --no-greedyagg 21 | 22 | if __name__ == "__main__": 23 | arg_parser = argparse.ArgumentParser() 24 | arg_parser.add_argument("-i", "--infile", help="HTML input file path.", required=True) 25 | arg_parser.add_argument("-o", "--outfile", help="Output passages file path.", required=True) 26 | arg_parser.add_argument("--maxwords", type=int, default=200, help="Max words per aggregate passage.") 27 | arg_parser.add_argument("--greedyagg", action=argparse.BooleanOptionalAction, help="Whether to greedily aggregate sibling nodes.") 28 | arg_parser.add_argument("--excludetags", type=str, default="noscript,script,style", help="Comma-separated HTML tags from which to exclude text.") 29 | args = arg_parser.parse_args() 30 | 31 | html_file = open(args.infile, "r") 32 | html = html_file.read() 33 | html_file.close() 34 | 35 | chunker = HtmlChunker( 36 | max_words_per_aggregate_passage=args.maxwords, 37 | greedily_aggregate_sibling_nodes=args.greedyagg, 38 | html_tags_to_exclude={tag for tag in args.excludetags.split(',')}, 39 | ) 40 | passages = chunker.chunk(html) 41 | 42 | passages_file = open(args.outfile, "w") 43 | passages_file.writelines(passage + "\n\n" for passage in passages) 44 | passages_file.close() 45 | -------------------------------------------------------------------------------- /seeds/chunker/.gitignore: -------------------------------------------------------------------------------- 1 | temp/ -------------------------------------------------------------------------------- /seeds/chunker/.npmignore: -------------------------------------------------------------------------------- 1 | .env 2 | tsconfig.tsbuildinfo 3 | -------------------------------------------------------------------------------- /seeds/chunker/README.md: -------------------------------------------------------------------------------- 1 | # Your README goes here -------------------------------------------------------------------------------- /seeds/chunker/cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import process, { exit } from "process"; 3 | import { readFile } from "fs/promises"; 4 | 5 | import { BasicChunker } from "./dist/src/index.js"; 6 | 7 | /** 8 | * @license 9 | * Copyright 2023 Google LLC 10 | * SPDX-License-Identifier: Apache-2.0 11 | */ 12 | 13 | const filename = process.argv[2]; 14 | if (!filename) { 15 | console.log("Give me a path to a file with structured data (JSON) to chunk"); 16 | exit(1); 17 | } 18 | 19 | const data = JSON.parse(await readFile(filename)); 20 | 21 | console.log(`Chunking ${filename} ...`); 22 | 23 | const chunker = new BasicChunker({ 24 | maxWordsPerPassage: 100, 25 | greedilyAggregateSiblings: true, 26 | }); 27 | const result = chunker.chunk(data); 28 | 29 | console.log("DONE", result); 30 | -------------------------------------------------------------------------------- /seeds/chunker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@google-labs/chunker", 3 | "version": "0.0.1", 4 | "description": "A simple chunker for breaking up structured data into chunks, suitable for RAG", 5 | "main": "./dist/src/index.js", 6 | "exports": "./dist/src/index.js", 7 | "types": "dist/src/index.d.ts", 8 | "type": "module", 9 | "bin": { 10 | "chunker": "./cli.js" 11 | }, 12 | "scripts": { 13 | "dev": "wireit", 14 | "test": "wireit", 15 | "build": "wireit", 16 | "build:tsc": "wireit", 17 | "lint": "wireit" 18 | }, 19 | "wireit": { 20 | "build": { 21 | "dependencies": [ 22 | "build:tsc" 23 | ] 24 | }, 25 | "build:tsc": { 26 | "command": "tsc -b", 27 | "env": { 28 | "FORCE_COLOR": "1" 29 | }, 30 | "files": [ 31 | "src/**/*.ts", 32 | "tests/**/*.ts", 33 | "tsconfig.json", 34 | "../../core/tsconfig/base.json" 35 | ], 36 | "output": [ 37 | "dist/" 38 | ], 39 | "clean": "if-file-deleted" 40 | }, 41 | "dev": { 42 | "command": "chunker", 43 | "dependencies": [ 44 | "build:tsc" 45 | ], 46 | "files": [], 47 | "output": [] 48 | }, 49 | "test": { 50 | "command": "ava", 51 | "env": { 52 | "FORCE_COLOR": "1" 53 | }, 54 | "dependencies": [ 55 | "build:tsc" 56 | ], 57 | "files": [], 58 | "output": [] 59 | }, 60 | "lint": { 61 | "command": "eslint . --ext .ts", 62 | "env": { 63 | "FORCE_COLOR": "1" 64 | }, 65 | "files": [ 66 | "src/**/*.ts", 67 | "tests/**/*.ts" 68 | ], 69 | "output": [] 70 | } 71 | }, 72 | "repository": { 73 | "type": "git", 74 | "url": "https://github.com/google/labs-prototypes" 75 | }, 76 | "files": [ 77 | "dist/src" 78 | ], 79 | "ava": { 80 | "timeout": "30s", 81 | "files": [ 82 | "tests/**/*.ts" 83 | ], 84 | "workerThreads": false, 85 | "typescript": { 86 | "rewritePaths": { 87 | "./": "dist/" 88 | }, 89 | "compile": false 90 | } 91 | }, 92 | "keywords": [], 93 | "author": "Google Labs Team", 94 | "license": "Apache-2.0", 95 | "bugs": { 96 | "url": "https://github.com/google/labs-prototypes/issues" 97 | }, 98 | "homepage": "https://github.com/google/labs-prototypes#readme", 99 | "devDependencies": { 100 | "@ava/typescript": "^4.1.0", 101 | "@google-labs/tsconfig": "^0.0.1", 102 | "@types/node": "^18.19.31", 103 | "@typescript-eslint/eslint-plugin": "^5.62.0", 104 | "@typescript-eslint/parser": "^5.62.0", 105 | "ava": "^5.3.1", 106 | "typescript": "^5.4.5" 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /seeds/chunker/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2023 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | export { BasicChunker } from "./basic.js"; 8 | -------------------------------------------------------------------------------- /seeds/chunker/tests/chunker-all.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2023 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import test from "ava"; 8 | 9 | import { BasicChunker } from "../src/index.js"; 10 | import { readFile, readdir } from "fs/promises"; 11 | 12 | const TEST_CASES_DIRECTORY = "./tests/data"; 13 | 14 | (await readdir(TEST_CASES_DIRECTORY)).forEach(async (testCase) => { 15 | test(`chunker: ${testCase}`, async (t) => { 16 | const data = JSON.parse( 17 | await readFile(`${TEST_CASES_DIRECTORY}/${testCase}`, "utf-8") 18 | ); 19 | if (data.skip) { 20 | t.log(`Skipping ${testCase}`); 21 | t.pass(); 22 | return; 23 | } 24 | const chunker = new BasicChunker(data.options); 25 | const result = chunker.chunk(data.input); 26 | t.deepEqual(result, data.output); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /seeds/chunker/tests/data/makers-1-greedy.json: -------------------------------------------------------------------------------- 1 | { 2 | "options": { 3 | "maxWordsPerPassage": 20, 4 | "greedilyAggregateSiblings": true 5 | }, 6 | "input": { 7 | "type": "bodySection", 8 | "children": [ 9 | { 10 | "type": "paragraph", 11 | "children": [ 12 | { "type": "text", "text": "We Are Entering a Maker Renaissance" } 13 | ] 14 | }, 15 | { 16 | "type": "paragraph", 17 | "children": [ 18 | { 19 | "type": "text", 20 | "text": "Why generative AI will fuel a new era for builders" 21 | } 22 | ] 23 | }, 24 | { "type": "paragraph", "text": "" }, 25 | { 26 | "type": "paragraph", 27 | "children": [ 28 | { 29 | "type": "text", 30 | "text": "We are living in an era ripe for makers." 31 | } 32 | ] 33 | } 34 | ] 35 | }, 36 | "output": [ 37 | "We Are Entering a Maker Renaissance Why generative AI will fuel a new era for builders", 38 | "We are living in an era ripe for makers." 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /seeds/chunker/tests/data/makers-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "options": { 3 | "maxWordsPerPassage": 20 4 | }, 5 | "input": { 6 | "type": "bodySection", 7 | "children": [ 8 | { 9 | "type": "paragraph", 10 | "children": [ 11 | { "type": "text", "text": "We Are Entering a Maker Renaissance" } 12 | ] 13 | }, 14 | { 15 | "type": "paragraph", 16 | "children": [ 17 | { 18 | "type": "text", 19 | "text": "Why generative AI will fuel a new era for builders" 20 | } 21 | ] 22 | }, 23 | { "type": "paragraph", "text": "" }, 24 | { 25 | "type": "paragraph", 26 | "children": [ 27 | { 28 | "type": "text", 29 | "text": "We are living in an era ripe for makers." 30 | } 31 | ] 32 | } 33 | ] 34 | }, 35 | "output": [ 36 | "We Are Entering a Maker Renaissance", 37 | "Why generative AI will fuel a new era for builders", 38 | "We are living in an era ripe for makers." 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /seeds/chunker/tests/data/non-peers-to-chunk-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "options": { 3 | "maxWordsPerPassage": 10 4 | }, 5 | "input": { 6 | "type": "body", 7 | "children": [ 8 | { 9 | "type": "text", 10 | "text": "A quick brown fox jumped" 11 | }, 12 | { 13 | "type": "p", 14 | "children": [ 15 | { 16 | "type": "text", 17 | "text": "over a lazy dog." 18 | }, 19 | { 20 | "type": "text", 21 | "text": "A quick brown fox jumped over a lazy dog" 22 | } 23 | ] 24 | } 25 | ] 26 | }, 27 | "output": [ 28 | "A quick brown fox jumped", 29 | "over a lazy dog.", 30 | "A quick brown fox jumped over a lazy dog" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /seeds/chunker/tests/data/simple-one-chunk.json: -------------------------------------------------------------------------------- 1 | { 2 | "options": { 3 | "maxWordsPerPassage": 10 4 | }, 5 | "input": { 6 | "type": "body", 7 | "children": [ 8 | { 9 | "type": "text", 10 | "text": "A quick brown fox jumped" 11 | }, 12 | { 13 | "type": "text", 14 | "text": "over a lazy dog." 15 | } 16 | ] 17 | }, 18 | "output": ["A quick brown fox jumped over a lazy dog."] 19 | } 20 | -------------------------------------------------------------------------------- /seeds/chunker/tests/data/simple-one-non-peers.json: -------------------------------------------------------------------------------- 1 | { 2 | "options": { 3 | "maxWordsPerPassage": 10 4 | }, 5 | "input": { 6 | "type": "body", 7 | "children": [ 8 | { 9 | "type": "text", 10 | "text": "A quick brown fox jumped" 11 | }, 12 | { 13 | "type": "p", 14 | "children": [ 15 | { 16 | "type": "text", 17 | "text": "over a lazy dog." 18 | } 19 | ] 20 | } 21 | ] 22 | }, 23 | "output": ["A quick brown fox jumped over a lazy dog."] 24 | } 25 | -------------------------------------------------------------------------------- /seeds/chunker/tests/data/simplest.json: -------------------------------------------------------------------------------- 1 | { 2 | "options": { 3 | "maxWordsPerPassage": 10 4 | }, 5 | "input": { 6 | "type": "body", 7 | "children": [ 8 | { 9 | "type": "text", 10 | "text": "Hello World!" 11 | } 12 | ] 13 | }, 14 | "output": ["Hello World!"] 15 | } 16 | -------------------------------------------------------------------------------- /seeds/chunker/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "outDir": "./dist" 5 | }, 6 | "include": ["src/**/*", "tests/**/*"], 7 | "extends": "../../core/tsconfig/base.json" 8 | } 9 | -------------------------------------------------------------------------------- /seeds/discovery-types/.npmignore: -------------------------------------------------------------------------------- 1 | .env 2 | tsconfig.tsbuildinfo 3 | -------------------------------------------------------------------------------- /seeds/discovery-types/README.md: -------------------------------------------------------------------------------- 1 | # The simplest possible Discovery -> TypeScript declarations converter 2 | 3 | Made primarily to read the PaLM API Discovery doc and spit out nice TypeScript declarations. 4 | 5 | To use: 6 | 7 | ```ts 8 | import { config } from "dotenv"; 9 | 10 | import { toTypes } from "@google-labs/discovery-types"; 11 | 12 | config(); 13 | 14 | const DISCOVER_DOC_URL = 15 | "https://generativelanguage.googleapis.com/$discovery/rest?version=v1beta2"; 16 | const { API_KEY } = process.env; 17 | if (!API_KEY) throw new Error("API_KEY is not defined"); 18 | 19 | const response = await fetch(`${DISCOVER_DOC_URL}&key=${API_KEY}`); 20 | const doc = await response.json(); 21 | 22 | const types = toTypes(doc); 23 | console.log(types); 24 | ``` 25 | -------------------------------------------------------------------------------- /seeds/discovery-types/docs/api/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /seeds/discovery-types/docs/api/README.md: -------------------------------------------------------------------------------- 1 | @google-labs/discovery-types / [Exports](modules.md) 2 | 3 | # The simplest possible Discovery -> TypeScript declarations converter 4 | 5 | Made primarily to read the PaLM API Discovery doc and spit out nice TypeScript declarations. 6 | 7 | To use: 8 | 9 | ```ts 10 | import { config } from "dotenv"; 11 | 12 | import { toTypes } from "@google-labs/discovery-types"; 13 | 14 | config(); 15 | 16 | const DISCOVER_DOC_URL = 17 | "https://generativelanguage.googleapis.com/$discovery/rest?version=v1beta2"; 18 | const { API_KEY } = process.env; 19 | if (!API_KEY) throw new Error("API_KEY is not defined"); 20 | 21 | const response = await fetch(`${DISCOVER_DOC_URL}&key=${API_KEY}`); 22 | const doc = await response.json(); 23 | 24 | const types = toTypes(doc); 25 | console.log(types); 26 | ``` 27 | -------------------------------------------------------------------------------- /seeds/discovery-types/docs/api/modules.md: -------------------------------------------------------------------------------- 1 | [@google-labs/discovery-types](README.md) / Exports 2 | 3 | # @google-labs/discovery-types 4 | 5 | ## Table of contents 6 | 7 | ### Functions 8 | 9 | - [toTypes](modules.md#totypes) 10 | 11 | ## Functions 12 | 13 | ### toTypes 14 | 15 | ▸ **toTypes**(`o`): `string` 16 | 17 | #### Parameters 18 | 19 | | Name | Type | 20 | | :------ | :------ | 21 | | `o` | `unknown` | 22 | 23 | #### Returns 24 | 25 | `string` 26 | 27 | #### Defined in 28 | 29 | [index.ts:11](https://github.com/google/labs-prototypes/blob/99919d5/seeds/discovery-types/src/index.ts#L11) 30 | -------------------------------------------------------------------------------- /seeds/discovery-types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@google-labs/discovery-types", 3 | "private": true, 4 | "version": "0.0.1", 5 | "description": "Simplest possible Discovery doc-to-TypeScript definitions converter", 6 | "main": "./dist/src/index.js", 7 | "exports": "./dist/src/index.js", 8 | "types": "dist/src/index.d.ts", 9 | "type": "module", 10 | "scripts": { 11 | "generate:docs": "wireit", 12 | "test": "wireit", 13 | "build": "wireit", 14 | "build:tsc": "wireit", 15 | "lint": "wireit" 16 | }, 17 | "wireit": { 18 | "build": { 19 | "dependencies": [ 20 | "build:tsc" 21 | ] 22 | }, 23 | "build:tsc": { 24 | "command": "tsc -b", 25 | "env": { 26 | "FORCE_COLOR": "1" 27 | }, 28 | "files": [ 29 | "src/**/*.ts", 30 | "tests/**/*.ts", 31 | "tsconfig.json", 32 | "../../core/tsconfig/base.json" 33 | ], 34 | "output": [ 35 | "dist/", 36 | "!dist/**/*.min.js{,.map}" 37 | ], 38 | "clean": "if-file-deleted" 39 | }, 40 | "test": { 41 | "command": "ava", 42 | "env": { 43 | "FORCE_COLOR": "1" 44 | }, 45 | "dependencies": [ 46 | "build:tsc" 47 | ], 48 | "files": [], 49 | "output": [] 50 | }, 51 | "lint": { 52 | "command": "eslint . --ext .ts", 53 | "env": { 54 | "FORCE_COLOR": "1" 55 | }, 56 | "files": [ 57 | "src/**/*.ts", 58 | "tests/**/*.ts" 59 | ], 60 | "output": [] 61 | }, 62 | "generate:docs": { 63 | "command": "typedoc --plugin typedoc-plugin-markdown", 64 | "files": [ 65 | "src/**/*.ts", 66 | "tsconfig.json", 67 | "../../core/tsconfig/base.json" 68 | ], 69 | "output": [ 70 | "docs/api/" 71 | ] 72 | } 73 | }, 74 | "repository": { 75 | "type": "git", 76 | "url": "https://github.com/google/labs-prototypes" 77 | }, 78 | "files": [ 79 | "dist/src" 80 | ], 81 | "ava": { 82 | "timeout": "30s", 83 | "files": [ 84 | "tests/**/*.ts" 85 | ], 86 | "workerThreads": false, 87 | "typescript": { 88 | "rewritePaths": { 89 | "./": "dist/" 90 | }, 91 | "compile": false 92 | } 93 | }, 94 | "keywords": [], 95 | "author": "Google Labs Team", 96 | "license": "Apache-2.0", 97 | "bugs": { 98 | "url": "https://github.com/google/labs-prototypes/issues" 99 | }, 100 | "homepage": "https://github.com/google/labs-prototypes#readme", 101 | "devDependencies": { 102 | "@ava/typescript": "^4.1.0", 103 | "@google-labs/tsconfig": "^0.0.1", 104 | "@types/node": "^18.19.31", 105 | "@types/prettier": "^2.7.3", 106 | "@typescript-eslint/eslint-plugin": "^5.62.0", 107 | "@typescript-eslint/parser": "^5.62.0", 108 | "ava": "^5.3.1", 109 | "typedoc": "^0.25.13", 110 | "typescript": "^5.4.5" 111 | }, 112 | "dependencies": { 113 | "dotenv": "^16.4.5", 114 | "prettier": "^2.8.8" 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /seeds/discovery-types/src/converter.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2023 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * This is a minimal implementation of the Discovery Document to TypeScript converter. 9 | * It is not intended to be a complete implementation, rather just enough code 10 | * to parse the Discovery doc for https://developers.generativeai.google/api/rest/generativelanguage 11 | * and produce decent TypeScript definitions for the request/response objects. 12 | */ 13 | 14 | export interface Schema { 15 | id: string; 16 | $ref: string; 17 | readonly: boolean; 18 | required: boolean; 19 | description: string; 20 | enum?: string[]; 21 | enumDescriptions?: string[]; 22 | type: string; 23 | items: Schema; 24 | properties: Record; 25 | } 26 | 27 | export interface DiscoveryDoc { 28 | schemas: Record; 29 | } 30 | 31 | const sorted = (o: Record): [string, Schema][] => { 32 | const result = Object.entries(o); 33 | result.sort(); 34 | return result; 35 | }; 36 | 37 | const toInterface = (schema: Schema): string => { 38 | const name = schema.id; 39 | const comment = toComment(schema.description); 40 | const type = toType(schema); 41 | return `${comment}export interface ${name} ${type}`; 42 | }; 43 | 44 | const toType = (schema: Schema): string => { 45 | if (schema.$ref) return schema.$ref; 46 | if (schema.enum) return toEnum(schema); 47 | if (schema.type == "integer") return "number"; 48 | if (schema.type == "array") return toArray(schema.items); 49 | if (schema.type != "object") return schema.type; 50 | 51 | return `{\n${sorted(schema.properties) 52 | .map(([name, property]) => { 53 | const comment = toComment(property.description); 54 | const isRequired = comment && comment.startsWith("Required."); 55 | const readonly = property.readonly ? "readonly" : ""; 56 | const optional = property.required || isRequired ? "" : "?"; 57 | const type = toType(property); 58 | return `${comment}${readonly}${name}${optional}: ${type}`; 59 | }) 60 | .join("\n")}\n}`; 61 | }; 62 | 63 | const toArray = (items: Schema): string => { 64 | return `${toType(items)}[]`; 65 | }; 66 | 67 | const toEnum = (schema: Schema): string => { 68 | const values = schema.enum || []; 69 | return `${values.map((v) => `"${v}"`).join(" | ")}`; 70 | }; 71 | 72 | const toComment = (value: string): string => { 73 | return `\n/**\n * ${value 74 | .split("\n") 75 | .join("\n * ") 76 | .replace(/\*\//g, "*\\/")} */\n`; 77 | }; 78 | 79 | export const fromDoc = (doc: DiscoveryDoc): string => { 80 | return sorted(doc.schemas) 81 | .map(([_name, schema]) => toInterface(schema)) 82 | .join("\n"); 83 | }; 84 | -------------------------------------------------------------------------------- /seeds/discovery-types/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2023 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import prettier from "prettier"; 8 | 9 | import { fromDoc, DiscoveryDoc } from "./converter.js"; 10 | 11 | export const toTypes = (o: unknown) => { 12 | const doc = o as DiscoveryDoc; 13 | const types = fromDoc(doc); 14 | const formatted = prettier.format(types, { 15 | parser: "typescript", 16 | arrowParens: "always", 17 | printWidth: 80, 18 | semi: true, 19 | tabWidth: 2, 20 | trailingComma: "es5", 21 | useTabs: false, 22 | }); 23 | return formatted; 24 | }; 25 | -------------------------------------------------------------------------------- /seeds/discovery-types/tests/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2023 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import test from "ava"; 8 | 9 | test("discovery-types", async (t) => { 10 | t.pass(); 11 | }); 12 | -------------------------------------------------------------------------------- /seeds/discovery-types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "outDir": "./dist" 5 | }, 6 | "include": ["src/**/*", "tests/**/*"], 7 | "extends": "@google-labs/tsconfig/base.json", 8 | "typedocOptions": { 9 | "entryPoints": "./src/index.ts", 10 | "out": "./docs/api", 11 | "githubPages": "false", 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /seeds/gemini-guide/eleventy.config.cjs: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /* eslint-disable @typescript-eslint/no-var-requires */ 8 | /* eslint-env node */ 9 | 10 | const markdownItGitHubAlerts = require("markdown-it-github-alerts"); 11 | const markdownItGitHubHeadings = require("markdown-it-github-headings"); 12 | const syntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight"); 13 | 14 | module.exports = function (eleventyConfig) { 15 | eleventyConfig.addPlugin(syntaxHighlight); 16 | 17 | eleventyConfig.amendLibrary("md", (mdLib) => { 18 | mdLib.use(markdownItGitHubAlerts, { icons: "" }); 19 | mdLib.use(markdownItGitHubHeadings, { 20 | prefix: "", 21 | linkIcon: `
Link
`, 22 | }); 23 | 24 | return mdLib; 25 | }); 26 | }; 27 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/_includes/footer.njk: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/_includes/gallery.njk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include "head.njk" %} 5 | Gemini Patterns 6 | 7 | 8 | 9 | {% include "header.njk" %} 10 | 11 |
12 |
13 | {%- for item in collections.patterns -%} 14 | 15 |

{{ item.data.title }}

16 |

{{ item.data.description }}

17 |
18 | {%- endfor -%} 19 |
20 |
21 | 22 | {% include "footer.njk" %} 23 | 24 | 25 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/_includes/head.njk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/_includes/header.njk: -------------------------------------------------------------------------------- 1 |
2 | 6 | GitHub 7 |
8 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/_includes/pattern.njk: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include "head.njk" %} 5 | {{ title }} | Gemini Patterns 6 | 7 | 8 | 9 | 10 | {% include "header.njk" %} 11 | 12 |
13 | {{content | safe}} 14 |
15 | 16 | {% include "footer.njk" %} 17 | 18 | 19 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/index.html: -------------------------------------------------------------------------------- 1 | {% include "gallery.njk" %} 2 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/js/placeholder.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | // Placeholder for some code. 8 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/patterns/bar/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: pattern.njk 3 | title: Bar 4 | description: Some brief descriptive text about the bar pattern for the gallery card 5 | color: yellow 6 | tags: 7 | - patterns 8 | --- 9 | 10 | This is the bar pattern 11 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/patterns/baz/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: pattern.njk 3 | title: Baz 4 | description: Some brief descriptive text about the baz pattern for the gallery card 5 | color: blue 6 | tags: 7 | - patterns 8 | --- 9 | 10 | This is the baz pattern 11 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/patterns/foo/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: pattern.njk 3 | title: Foo 4 | description: Some brief descriptive text about the foo pattern for the gallery card 5 | color: green 6 | tags: 7 | - patterns 8 | --- 9 | 10 | Some text about foo 11 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/patterns/qux/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: pattern.njk 3 | title: Qux 4 | description: Some brief descriptive text about the qux pattern for the gallery card 5 | color: red 6 | tags: 7 | - patterns 8 | --- 9 | 10 | Some text about qux 11 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/static/common.css: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | body { 8 | margin: 0; 9 | background: #0c0e10; 10 | font-family: "Google Sans", Arial, sans-serif; 11 | } 12 | 13 | header { 14 | padding: 15px 30px; 15 | border-bottom: 1px solid #46474a; 16 | display: flex; 17 | justify-content: space-between; 18 | align-items: center; 19 | background: #0c0e10; 20 | } 21 | 22 | header > #logo { 23 | text-decoration: none; 24 | color: #fff; 25 | display: flex; 26 | align-items: center; 27 | justify-content: center; 28 | } 29 | 30 | header > #logo > #patterns-text { 31 | margin: 5px 0 0 10px; 32 | font-size: 26px; 33 | } 34 | 35 | header > #logo, 36 | header > #logo:visited { 37 | color: #fff; 38 | } 39 | 40 | header #github { 41 | width: 28px; 42 | height: 28px; 43 | font-size: 0; 44 | background: no-repeat center/28px url(./third_party/github/github-mark.svg); 45 | } 46 | 47 | footer { 48 | border-top: 1px solid #46474a; 49 | color: #fff; 50 | padding: 24px; 51 | font-size: 90%; 52 | opacity: 60%; 53 | display: flex; 54 | align-items: center; 55 | justify-content: center; 56 | } 57 | 58 | footer a { 59 | color: white; 60 | } 61 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/static/gallery.css: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #cards { 8 | display: flex; 9 | flex-wrap: wrap; 10 | gap: 30px; 11 | padding: 30px; 12 | } 13 | 14 | .card { 15 | background: #1a1c1e; 16 | color: white; 17 | text-decoration: none; 18 | border: 1px solid #45474f; 19 | border-radius: 20px; 20 | width: 300px; 21 | min-height: 150px; 22 | padding: 10px 20px; 23 | display: flex; 24 | flex-direction: column; 25 | justify-content: space-between; 26 | } 27 | 28 | .card:hover { 29 | background: #2a2c2e; 30 | } 31 | 32 | .card > h2 { 33 | color: #adc4ff; 34 | font-weight: normal; 35 | font-size: 22px; 36 | } 37 | 38 | .card > p { 39 | font-size: 15px; 40 | padding-bottom: 0; 41 | line-height: 28px; 42 | } 43 | 44 | .card.green > h2 { 45 | color: #a5d6a7; 46 | } 47 | 48 | .card.blue > h2 { 49 | color: #90caf9; 50 | } 51 | 52 | .card.yellow > h2 { 53 | color: #fff59d; 54 | } 55 | 56 | .card.red > h2 { 57 | color: #ef9a9a; 58 | } 59 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/static/pattern.css: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | main { 8 | padding: 24px; 9 | color: white; 10 | } 11 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/static/third_party/github/github-mark.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/static/third_party/icons/check-circle.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/static/third_party/icons/copy-to-clipboard.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/static/third_party/icons/lightbulb.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/static/third_party/icons/link.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/static/third_party/icons/menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/static/third_party/icons/note.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/gemini-guide/src/static/third_party/icons/warning.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /seeds/gemini-guide/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "outDir": "dist/tsc/", 5 | "rootDir": "src/js/", 6 | "experimentalDecorators": true, 7 | "useDefineForClassFields": false, 8 | "allowJs": false, 9 | "lib": ["ES2022", "DOM", "DOM.Iterable"], 10 | "tsBuildInfoFile": "dist/tsc/.tsbuildinfo" 11 | }, 12 | "include": ["src/js/**/*"], 13 | "extends": "../../core/tsconfig/base.json" 14 | } 15 | -------------------------------------------------------------------------------- /seeds/gems/text_classification/README.md: -------------------------------------------------------------------------------- 1 | # 20 Newsgroups Text Dataset 2 | 3 | ## Dataset description 4 | 5 | The [20 Newsgroups Text Dataset](https://scikit-learn.org/0.19/datasets/twenty_newsgroups.html) contains 18,000 newsgroups posts on 20 topics divided into training and test sets. The split between the training and test datasets are based on messages posted before and after a specific date. For this tutorial, you will be using the subsets of the training and test datasets. You will preprocess and organize the data into Pandas dataframes. 6 | 7 | ## Leaderboard 8 | 9 | | Username| Dataset | Notebook| Accuracy | 10 | | :--- | :----: | :----: | ---:| 11 | |[@shilpakancharla](https://github.com/shilpakancharla)|[20 Newsgroups Text Dataset](https://scikit-learn.org/0.19/datasets/twenty_newsgroups.html)| [Text classifier](20_newsgroups/train_text_classifier_embeddings.ipynb)| 92% | -------------------------------------------------------------------------------- /seeds/palm-lite/.npmignore: -------------------------------------------------------------------------------- 1 | .env 2 | tsconfig.tsbuildinfo 3 | -------------------------------------------------------------------------------- /seeds/palm-lite/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [0.0.2] - 2023-07-31 4 | 5 | - started a changelog 6 | - updated link to homepage in `package.json` 7 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/enums/PalmModelMethod.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / PalmModelMethod 2 | 3 | # Enumeration: PalmModelMethod 4 | 5 | ## Table of contents 6 | 7 | ### Enumeration Members 8 | 9 | - [EmbedText](PalmModelMethod.md#embedtext) 10 | - [GenerateMessage](PalmModelMethod.md#generatemessage) 11 | - [GenerateText](PalmModelMethod.md#generatetext) 12 | 13 | ## Enumeration Members 14 | 15 | ### EmbedText 16 | 17 | • **EmbedText** = ``"embedText"`` 18 | 19 | #### Defined in 20 | 21 | [index.ts:28](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/index.ts#L28) 22 | 23 | ___ 24 | 25 | ### GenerateMessage 26 | 27 | • **GenerateMessage** = ``"generateMessage"`` 28 | 29 | #### Defined in 30 | 31 | [index.ts:26](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/index.ts#L26) 32 | 33 | ___ 34 | 35 | ### GenerateText 36 | 37 | • **GenerateText** = ``"generateText"`` 38 | 39 | #### Defined in 40 | 41 | [index.ts:27](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/index.ts#L27) 42 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/CitationMetadata.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / CitationMetadata 2 | 3 | # Interface: CitationMetadata 4 | 5 | A collection of source attributions for a piece of content. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [citationSources](CitationMetadata.md#citationsources) 12 | 13 | ## Properties 14 | 15 | ### citationSources 16 | 17 | • `Optional` **citationSources**: [`CitationSource`](CitationSource.md)[] 18 | 19 | Citations to sources for a specific response. 20 | 21 | #### Defined in 22 | 23 | [types.ts:11](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L11) 24 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/CitationSource.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / CitationSource 2 | 3 | # Interface: CitationSource 4 | 5 | A citation to a source for a portion of a specific response. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [endIndex](CitationSource.md#endindex) 12 | - [license](CitationSource.md#license) 13 | - [startIndex](CitationSource.md#startindex) 14 | - [uri](CitationSource.md#uri) 15 | 16 | ## Properties 17 | 18 | ### endIndex 19 | 20 | • `Optional` **endIndex**: `number` 21 | 22 | Optional. End of the attributed segment, exclusive. 23 | 24 | #### Defined in 25 | 26 | [types.ts:19](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L19) 27 | 28 | ___ 29 | 30 | ### license 31 | 32 | • `Optional` **license**: `string` 33 | 34 | Optional. License for the GitHub project that is attributed as a source for segment. License info is required for code citations. 35 | 36 | #### Defined in 37 | 38 | [types.ts:23](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L23) 39 | 40 | ___ 41 | 42 | ### startIndex 43 | 44 | • `Optional` **startIndex**: `number` 45 | 46 | Optional. Start of segment of the response that is attributed to this source. Index indicates the start of the segment, measured in bytes. 47 | 48 | #### Defined in 49 | 50 | [types.ts:27](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L27) 51 | 52 | ___ 53 | 54 | ### uri 55 | 56 | • `Optional` **uri**: `string` 57 | 58 | Optional. URI that is attributed as a source for a portion of the text. 59 | 60 | #### Defined in 61 | 62 | [types.ts:31](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L31) 63 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/ContentFilter.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / ContentFilter 2 | 3 | # Interface: ContentFilter 4 | 5 | Content filtering metadata associated with processing a single request. ContentFilter contains a reason and an optional supporting string. The reason may be unspecified. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [message](ContentFilter.md#message) 12 | - [reason](ContentFilter.md#reason) 13 | 14 | ## Properties 15 | 16 | ### message 17 | 18 | • `Optional` **message**: `string` 19 | 20 | A string that describes the filtering behavior in more detail. 21 | 22 | #### Defined in 23 | 24 | [types.ts:39](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L39) 25 | 26 | ___ 27 | 28 | ### reason 29 | 30 | • `Optional` **reason**: ``"BLOCKED_REASON_UNSPECIFIED"`` \| ``"SAFETY"`` \| ``"OTHER"`` 31 | 32 | The reason content was blocked during request processing. 33 | 34 | #### Defined in 35 | 36 | [types.ts:43](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L43) 37 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/CountMessageTokensRequest.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / CountMessageTokensRequest 2 | 3 | # Interface: CountMessageTokensRequest 4 | 5 | Counts the number of tokens in the `prompt` sent to a model. Models may tokenize text differently, so each model may return a different `token_count`. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [prompt](CountMessageTokensRequest.md#prompt) 12 | 13 | ## Properties 14 | 15 | ### prompt 16 | 17 | • `Optional` **prompt**: [`MessagePrompt`](MessagePrompt.md) 18 | 19 | Required. The prompt, whose token count is to be returned. 20 | 21 | #### Defined in 22 | 23 | [types.ts:51](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L51) 24 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/CountMessageTokensResponse.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / CountMessageTokensResponse 2 | 3 | # Interface: CountMessageTokensResponse 4 | 5 | A response from `CountMessageTokens`. It returns the model's `token_count` for the `prompt`. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [tokenCount](CountMessageTokensResponse.md#tokencount) 12 | 13 | ## Properties 14 | 15 | ### tokenCount 16 | 17 | • `Optional` **tokenCount**: `number` 18 | 19 | The number of tokens that the `model` tokenizes the `prompt` into. Always non-negative. 20 | 21 | #### Defined in 22 | 23 | [types.ts:59](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L59) 24 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/EmbedTextRequest.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / EmbedTextRequest 2 | 3 | # Interface: EmbedTextRequest 4 | 5 | Request to get a text embedding from the model. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [text](EmbedTextRequest.md#text) 12 | 13 | ## Properties 14 | 15 | ### text 16 | 17 | • `Optional` **text**: `string` 18 | 19 | Required. The free-form input text that the model will turn into an embedding. 20 | 21 | #### Defined in 22 | 23 | [types.ts:67](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L67) 24 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/EmbedTextResponse.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / EmbedTextResponse 2 | 3 | # Interface: EmbedTextResponse 4 | 5 | The response to a EmbedTextRequest. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [embedding](EmbedTextResponse.md#embedding) 12 | 13 | ## Properties 14 | 15 | ### embedding 16 | 17 | • `Optional` **embedding**: [`Embedding`](Embedding.md) 18 | 19 | Output only. The embedding generated from the input text. 20 | 21 | #### Defined in 22 | 23 | [types.ts:75](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L75) 24 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/Embedding.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / Embedding 2 | 3 | # Interface: Embedding 4 | 5 | A list of floats representing the embedding. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [value](Embedding.md#value) 12 | 13 | ## Properties 14 | 15 | ### value 16 | 17 | • `Optional` **value**: `number`[] 18 | 19 | The embedding values. 20 | 21 | #### Defined in 22 | 23 | [types.ts:83](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L83) 24 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/Example.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / Example 2 | 3 | # Interface: Example 4 | 5 | An input/output example used to instruct the Model. It demonstrates how the model should respond or format its response. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [input](Example.md#input) 12 | - [output](Example.md#output) 13 | 14 | ## Properties 15 | 16 | ### input 17 | 18 | • `Optional` **input**: [`Message`](Message.md) 19 | 20 | Required. An example of an input `Message` from the user. 21 | 22 | #### Defined in 23 | 24 | [types.ts:91](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L91) 25 | 26 | ___ 27 | 28 | ### output 29 | 30 | • `Optional` **output**: [`Message`](Message.md) 31 | 32 | Required. An example of what the model should output given the input. 33 | 34 | #### Defined in 35 | 36 | [types.ts:95](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L95) 37 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/GenerateMessageRequest.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / GenerateMessageRequest 2 | 3 | # Interface: GenerateMessageRequest 4 | 5 | Request to generate a message response from the model. 6 | 7 | ## Implemented by 8 | 9 | - [`Chat`](../classes/Chat.md) 10 | 11 | ## Table of contents 12 | 13 | ### Properties 14 | 15 | - [candidateCount](GenerateMessageRequest.md#candidatecount) 16 | - [prompt](GenerateMessageRequest.md#prompt) 17 | - [temperature](GenerateMessageRequest.md#temperature) 18 | - [topK](GenerateMessageRequest.md#topk) 19 | - [topP](GenerateMessageRequest.md#topp) 20 | 21 | ## Properties 22 | 23 | ### candidateCount 24 | 25 | • `Optional` **candidateCount**: `number` 26 | 27 | Optional. The number of generated response messages to return. This value must be between `[1, 8]`, inclusive. If unset, this will default to `1`. 28 | 29 | #### Defined in 30 | 31 | [types.ts:103](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L103) 32 | 33 | ___ 34 | 35 | ### prompt 36 | 37 | • `Optional` **prompt**: [`MessagePrompt`](MessagePrompt.md) 38 | 39 | Required. The structured textual input given to the model as a prompt. Given a prompt, the model will return what it predicts is the next message in the discussion. 40 | 41 | #### Defined in 42 | 43 | [types.ts:107](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L107) 44 | 45 | ___ 46 | 47 | ### temperature 48 | 49 | • `Optional` **temperature**: `number` 50 | 51 | Optional. Controls the randomness of the output. Values can range over `[0.0,1.0]`, inclusive. A value closer to `1.0` will produce responses that are more varied, while a value closer to `0.0` will typically result in less surprising responses from the model. 52 | 53 | #### Defined in 54 | 55 | [types.ts:111](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L111) 56 | 57 | ___ 58 | 59 | ### topK 60 | 61 | • `Optional` **topK**: `number` 62 | 63 | Optional. The maximum number of tokens to consider when sampling. The model uses combined Top-k and nucleus sampling. Top-k sampling considers the set of `top_k` most probable tokens. 64 | 65 | #### Defined in 66 | 67 | [types.ts:115](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L115) 68 | 69 | ___ 70 | 71 | ### topP 72 | 73 | • `Optional` **topP**: `number` 74 | 75 | Optional. The maximum cumulative probability of tokens to consider when sampling. The model uses combined Top-k and nucleus sampling. Nucleus sampling considers the smallest set of tokens whose probability sum is at least `top_p`. 76 | 77 | #### Defined in 78 | 79 | [types.ts:119](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L119) 80 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/GenerateMessageResponse.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / GenerateMessageResponse 2 | 3 | # Interface: GenerateMessageResponse 4 | 5 | The response from the model. This includes candidate messages and conversation history in the form of chronologically-ordered messages. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [candidates](GenerateMessageResponse.md#candidates) 12 | - [filters](GenerateMessageResponse.md#filters) 13 | - [messages](GenerateMessageResponse.md#messages) 14 | 15 | ## Properties 16 | 17 | ### candidates 18 | 19 | • `Optional` **candidates**: [`Message`](Message.md)[] 20 | 21 | Candidate response messages from the model. 22 | 23 | #### Defined in 24 | 25 | [types.ts:127](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L127) 26 | 27 | ___ 28 | 29 | ### filters 30 | 31 | • `Optional` **filters**: [`ContentFilter`](ContentFilter.md)[] 32 | 33 | A set of content filtering metadata for the prompt and response text. This indicates which `SafetyCategory`(s) blocked a candidate from this response, the lowest `HarmProbability` that triggered a block, and the HarmThreshold setting for that category. 34 | 35 | #### Defined in 36 | 37 | [types.ts:131](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L131) 38 | 39 | ___ 40 | 41 | ### messages 42 | 43 | • `Optional` **messages**: [`Message`](Message.md)[] 44 | 45 | The conversation history used by the model. 46 | 47 | #### Defined in 48 | 49 | [types.ts:135](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L135) 50 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/GenerateTextResponse.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / GenerateTextResponse 2 | 3 | # Interface: GenerateTextResponse 4 | 5 | The response from the model, including candidate completions. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [candidates](GenerateTextResponse.md#candidates) 12 | - [filters](GenerateTextResponse.md#filters) 13 | - [safetyFeedback](GenerateTextResponse.md#safetyfeedback) 14 | 15 | ## Properties 16 | 17 | ### candidates 18 | 19 | • `Optional` **candidates**: [`TextCompletion`](TextCompletion.md)[] 20 | 21 | Candidate responses from the model. 22 | 23 | #### Defined in 24 | 25 | [types.ts:179](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L179) 26 | 27 | ___ 28 | 29 | ### filters 30 | 31 | • `Optional` **filters**: [`ContentFilter`](ContentFilter.md)[] 32 | 33 | A set of content filtering metadata for the prompt and response text. This indicates which `SafetyCategory`(s) blocked a candidate from this response, the lowest `HarmProbability` that triggered a block, and the HarmThreshold setting for that category. This indicates the smallest change to the `SafetySettings` that would be necessary to unblock at least 1 response. The blocking is configured by the `SafetySettings` in the request (or the default `SafetySettings` of the API). 34 | 35 | #### Defined in 36 | 37 | [types.ts:183](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L183) 38 | 39 | ___ 40 | 41 | ### safetyFeedback 42 | 43 | • `Optional` **safetyFeedback**: [`SafetyFeedback`](SafetyFeedback.md)[] 44 | 45 | Returns any safety feedback related to content filtering. 46 | 47 | #### Defined in 48 | 49 | [types.ts:187](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L187) 50 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/ListModelsResponse.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / ListModelsResponse 2 | 3 | # Interface: ListModelsResponse 4 | 5 | Response from `ListModel` containing a paginated list of Models. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [models](ListModelsResponse.md#models) 12 | - [nextPageToken](ListModelsResponse.md#nextpagetoken) 13 | 14 | ## Properties 15 | 16 | ### models 17 | 18 | • `Optional` **models**: [`Model`](Model.md)[] 19 | 20 | The returned Models. 21 | 22 | #### Defined in 23 | 24 | [types.ts:195](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L195) 25 | 26 | ___ 27 | 28 | ### nextPageToken 29 | 30 | • `Optional` **nextPageToken**: `string` 31 | 32 | A token, which can be sent as `page_token` to retrieve the next page. If this field is omitted, there are no more pages. 33 | 34 | #### Defined in 35 | 36 | [types.ts:199](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L199) 37 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/Message.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / Message 2 | 3 | # Interface: Message 4 | 5 | The base unit of structured text. A `Message` includes an `author` and the `content` of the `Message`. The `author` is used to tag messages when they are fed to the model as text. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [author](Message.md#author) 12 | - [citationMetadata](Message.md#citationmetadata) 13 | - [content](Message.md#content) 14 | 15 | ## Properties 16 | 17 | ### author 18 | 19 | • `Optional` **author**: `string` 20 | 21 | Optional. The author of this Message. This serves as a key for tagging the content of this Message when it is fed to the model as text. The author can be any alphanumeric string. 22 | 23 | #### Defined in 24 | 25 | [types.ts:207](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L207) 26 | 27 | ___ 28 | 29 | ### citationMetadata 30 | 31 | • `Optional` **citationMetadata**: [`CitationMetadata`](CitationMetadata.md) 32 | 33 | Output only. Citation information for model-generated `content` in this `Message`. If this `Message` was generated as output from the model, this field may be populated with attribution information for any text included in the `content`. This field is used only on output. 34 | 35 | #### Defined in 36 | 37 | [types.ts:211](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L211) 38 | 39 | ___ 40 | 41 | ### content 42 | 43 | • `Optional` **content**: `string` 44 | 45 | Required. The text content of the structured `Message`. 46 | 47 | #### Defined in 48 | 49 | [types.ts:215](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L215) 50 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/MessagePrompt.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / MessagePrompt 2 | 3 | # Interface: MessagePrompt 4 | 5 | All of the structured input text passed to the model as a prompt. A `MessagePrompt` contains a structured set of fields that provide context for the conversation, examples of user input/model output message pairs that prime the model to respond in different ways, and the conversation history or list of messages representing the alternating turns of the conversation between the user and the model. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [context](MessagePrompt.md#context) 12 | - [examples](MessagePrompt.md#examples) 13 | - [messages](MessagePrompt.md#messages) 14 | 15 | ## Properties 16 | 17 | ### context 18 | 19 | • `Optional` **context**: `string` 20 | 21 | Optional. Text that should be provided to the model first to ground the response. If not empty, this `context` will be given to the model first before the `examples` and `messages`. When using a `context` be sure to provide it with every request to maintain continuity. This field can be a description of your prompt to the model to help provide context and guide the responses. Examples: "Translate the phrase from English to French." or "Given a statement, classify the sentiment as happy, sad or neutral." Anything included in this field will take precedence over message history if the total input size exceeds the model's `input_token_limit` and the input request is truncated. 22 | 23 | #### Defined in 24 | 25 | [types.ts:223](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L223) 26 | 27 | ___ 28 | 29 | ### examples 30 | 31 | • `Optional` **examples**: [`Example`](Example.md)[] 32 | 33 | Optional. Examples of what the model should generate. This includes both user input and the response that the model should emulate. These `examples` are treated identically to conversation messages except that they take precedence over the history in `messages`: If the total input size exceeds the model's `input_token_limit` the input will be truncated. Items will be dropped from `messages` before `examples`. 34 | 35 | #### Defined in 36 | 37 | [types.ts:227](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L227) 38 | 39 | ___ 40 | 41 | ### messages 42 | 43 | • `Optional` **messages**: [`Message`](Message.md)[] 44 | 45 | Required. A snapshot of the recent conversation history sorted chronologically. Turns alternate between two authors. If the total input size exceeds the model's `input_token_limit` the input will be truncated: The oldest items will be dropped from `messages`. 46 | 47 | #### Defined in 48 | 49 | [types.ts:231](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L231) 50 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/PartialGenerateMessageRequest.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / PartialGenerateMessageRequest 2 | 3 | # Interface: PartialGenerateMessageRequest 4 | 5 | A partical `GenerateMessageRequest` interface, for use with the `Chat` builder. 6 | It's basically the same as `GenerateMessageRequest`, except that `prompt` is optional. 7 | 8 | ## Hierarchy 9 | 10 | - `Omit`<[`GenerateMessageRequest`](GenerateMessageRequest.md), ``"prompt"``\> 11 | 12 | ↳ **`PartialGenerateMessageRequest`** 13 | 14 | ## Table of contents 15 | 16 | ### Properties 17 | 18 | - [candidateCount](PartialGenerateMessageRequest.md#candidatecount) 19 | - [prompt](PartialGenerateMessageRequest.md#prompt) 20 | - [temperature](PartialGenerateMessageRequest.md#temperature) 21 | - [topK](PartialGenerateMessageRequest.md#topk) 22 | - [topP](PartialGenerateMessageRequest.md#topp) 23 | 24 | ## Properties 25 | 26 | ### candidateCount 27 | 28 | • `Optional` **candidateCount**: `number` 29 | 30 | Optional. The number of generated response messages to return. This value must be between `[1, 8]`, inclusive. If unset, this will default to `1`. 31 | 32 | #### Inherited from 33 | 34 | Omit.candidateCount 35 | 36 | #### Defined in 37 | 38 | [types.ts:103](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L103) 39 | 40 | ___ 41 | 42 | ### prompt 43 | 44 | • `Optional` **prompt**: [`MessagePrompt`](MessagePrompt.md) 45 | 46 | #### Defined in 47 | 48 | [chat.ts:15](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/chat.ts#L15) 49 | 50 | ___ 51 | 52 | ### temperature 53 | 54 | • `Optional` **temperature**: `number` 55 | 56 | Optional. Controls the randomness of the output. Values can range over `[0.0,1.0]`, inclusive. A value closer to `1.0` will produce responses that are more varied, while a value closer to `0.0` will typically result in less surprising responses from the model. 57 | 58 | #### Inherited from 59 | 60 | Omit.temperature 61 | 62 | #### Defined in 63 | 64 | [types.ts:111](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L111) 65 | 66 | ___ 67 | 68 | ### topK 69 | 70 | • `Optional` **topK**: `number` 71 | 72 | Optional. The maximum number of tokens to consider when sampling. The model uses combined Top-k and nucleus sampling. Top-k sampling considers the set of `top_k` most probable tokens. 73 | 74 | #### Inherited from 75 | 76 | Omit.topK 77 | 78 | #### Defined in 79 | 80 | [types.ts:115](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L115) 81 | 82 | ___ 83 | 84 | ### topP 85 | 86 | • `Optional` **topP**: `number` 87 | 88 | Optional. The maximum cumulative probability of tokens to consider when sampling. The model uses combined Top-k and nucleus sampling. Nucleus sampling considers the smallest set of tokens whose probability sum is at least `top_p`. 89 | 90 | #### Inherited from 91 | 92 | Omit.topP 93 | 94 | #### Defined in 95 | 96 | [types.ts:119](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L119) 97 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/SafetyFeedback.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / SafetyFeedback 2 | 3 | # Interface: SafetyFeedback 4 | 5 | Safety feedback for an entire request. This field is populated if content in the input and/or response is blocked due to safety settings. SafetyFeedback may not exist for every HarmCategory. Each SafetyFeedback will return the safety settings used by the request as well as the lowest HarmProbability that should be allowed in order to return a result. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [rating](SafetyFeedback.md#rating) 12 | - [setting](SafetyFeedback.md#setting) 13 | 14 | ## Properties 15 | 16 | ### rating 17 | 18 | • `Optional` **rating**: [`SafetyRating`](SafetyRating.md) 19 | 20 | Safety rating evaluated from content. 21 | 22 | #### Defined in 23 | 24 | [types.ts:287](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L287) 25 | 26 | ___ 27 | 28 | ### setting 29 | 30 | • `Optional` **setting**: [`SafetySetting`](SafetySetting.md) 31 | 32 | Safety settings applied to the request. 33 | 34 | #### Defined in 35 | 36 | [types.ts:291](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L291) 37 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/SafetyRating.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / SafetyRating 2 | 3 | # Interface: SafetyRating 4 | 5 | Safety rating for a piece of content. The safety rating contains the category of harm and the harm probability level in that category for a piece of content. Content is classified for safety across a number of harm categories and the probability of the harm classification is included here. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [category](SafetyRating.md#category) 12 | - [probability](SafetyRating.md#probability) 13 | 14 | ## Properties 15 | 16 | ### category 17 | 18 | • `Optional` **category**: ``"HARM_CATEGORY_UNSPECIFIED"`` \| ``"HARM_CATEGORY_DEROGATORY"`` \| ``"HARM_CATEGORY_TOXICITY"`` \| ``"HARM_CATEGORY_VIOLENCE"`` \| ``"HARM_CATEGORY_SEXUAL"`` \| ``"HARM_CATEGORY_MEDICAL"`` \| ``"HARM_CATEGORY_DANGEROUS"`` 19 | 20 | Required. The category for this rating. 21 | 22 | #### Defined in 23 | 24 | [types.ts:299](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L299) 25 | 26 | ___ 27 | 28 | ### probability 29 | 30 | • `Optional` **probability**: ``"HARM_PROBABILITY_UNSPECIFIED"`` \| ``"NEGLIGIBLE"`` \| ``"LOW"`` \| ``"MEDIUM"`` \| ``"HIGH"`` 31 | 32 | Required. The probability of harm for this content. 33 | 34 | #### Defined in 35 | 36 | [types.ts:310](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L310) 37 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/SafetySetting.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / SafetySetting 2 | 3 | # Interface: SafetySetting 4 | 5 | Safety setting, affecting the safety-blocking behavior. Passing a safety setting for a category changes the allowed proability that content is blocked. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [category](SafetySetting.md#category) 12 | - [threshold](SafetySetting.md#threshold) 13 | 14 | ## Properties 15 | 16 | ### category 17 | 18 | • `Optional` **category**: ``"HARM_CATEGORY_UNSPECIFIED"`` \| ``"HARM_CATEGORY_DEROGATORY"`` \| ``"HARM_CATEGORY_TOXICITY"`` \| ``"HARM_CATEGORY_VIOLENCE"`` \| ``"HARM_CATEGORY_SEXUAL"`` \| ``"HARM_CATEGORY_MEDICAL"`` \| ``"HARM_CATEGORY_DANGEROUS"`` 19 | 20 | Required. The category for this setting. 21 | 22 | #### Defined in 23 | 24 | [types.ts:323](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L323) 25 | 26 | ___ 27 | 28 | ### threshold 29 | 30 | • `Optional` **threshold**: ``"HARM_BLOCK_THRESHOLD_UNSPECIFIED"`` \| ``"BLOCK_LOW_AND_ABOVE"`` \| ``"BLOCK_MEDIUM_AND_ABOVE"`` \| ``"BLOCK_ONLY_HIGH"`` 31 | 32 | Required. Controls the probability threshold at which harm is blocked. 33 | 34 | #### Defined in 35 | 36 | [types.ts:334](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L334) 37 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/TextCompletion.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / TextCompletion 2 | 3 | # Interface: TextCompletion 4 | 5 | Output text returned from a model. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [citationMetadata](TextCompletion.md#citationmetadata) 12 | - [output](TextCompletion.md#output) 13 | - [safetyRatings](TextCompletion.md#safetyratings) 14 | 15 | ## Properties 16 | 17 | ### citationMetadata 18 | 19 | • `Optional` **citationMetadata**: [`CitationMetadata`](CitationMetadata.md) 20 | 21 | Output only. Citation information for model-generated `output` in this `TextCompletion`. This field may be populated with attribution information for any text included in the `output`. 22 | 23 | #### Defined in 24 | 25 | [types.ts:346](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L346) 26 | 27 | ___ 28 | 29 | ### output 30 | 31 | • `Optional` **output**: `string` 32 | 33 | Output only. The generated text returned from the model. 34 | 35 | #### Defined in 36 | 37 | [types.ts:350](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L350) 38 | 39 | ___ 40 | 41 | ### safetyRatings 42 | 43 | • `Optional` **safetyRatings**: [`SafetyRating`](SafetyRating.md)[] 44 | 45 | Ratings for the safety of a response. There is at most one rating per category. 46 | 47 | #### Defined in 48 | 49 | [types.ts:354](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L354) 50 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/interfaces/TextPrompt.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](../README.md) / [Exports](../modules.md) / TextPrompt 2 | 3 | # Interface: TextPrompt 4 | 5 | Text given to the model as a prompt. The Model will use this TextPrompt to Generate a text completion. 6 | 7 | ## Table of contents 8 | 9 | ### Properties 10 | 11 | - [text](TextPrompt.md#text) 12 | 13 | ## Properties 14 | 15 | ### text 16 | 17 | • `Optional` **text**: `string` 18 | 19 | Required. The prompt text. 20 | 21 | #### Defined in 22 | 23 | [types.ts:362](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/types.ts#L362) 24 | -------------------------------------------------------------------------------- /seeds/palm-lite/docs/api/modules.md: -------------------------------------------------------------------------------- 1 | [@google-labs/palm-lite](README.md) / Exports 2 | 3 | # @google-labs/palm-lite 4 | 5 | ## Table of contents 6 | 7 | ### Enumerations 8 | 9 | - [PalmModelMethod](enums/PalmModelMethod.md) 10 | 11 | ### Classes 12 | 13 | - [Chat](classes/Chat.md) 14 | - [Text](classes/Text.md) 15 | 16 | ### Interfaces 17 | 18 | - [CitationMetadata](interfaces/CitationMetadata.md) 19 | - [CitationSource](interfaces/CitationSource.md) 20 | - [ContentFilter](interfaces/ContentFilter.md) 21 | - [CountMessageTokensRequest](interfaces/CountMessageTokensRequest.md) 22 | - [CountMessageTokensResponse](interfaces/CountMessageTokensResponse.md) 23 | - [EmbedTextRequest](interfaces/EmbedTextRequest.md) 24 | - [EmbedTextResponse](interfaces/EmbedTextResponse.md) 25 | - [Embedding](interfaces/Embedding.md) 26 | - [Example](interfaces/Example.md) 27 | - [GenerateMessageRequest](interfaces/GenerateMessageRequest.md) 28 | - [GenerateMessageResponse](interfaces/GenerateMessageResponse.md) 29 | - [GenerateTextRequest](interfaces/GenerateTextRequest.md) 30 | - [GenerateTextResponse](interfaces/GenerateTextResponse.md) 31 | - [ListModelsResponse](interfaces/ListModelsResponse.md) 32 | - [Message](interfaces/Message.md) 33 | - [MessagePrompt](interfaces/MessagePrompt.md) 34 | - [Model](interfaces/Model.md) 35 | - [PartialGenerateMessageRequest](interfaces/PartialGenerateMessageRequest.md) 36 | - [PartialGenerateTextRequest](interfaces/PartialGenerateTextRequest.md) 37 | - [SafetyFeedback](interfaces/SafetyFeedback.md) 38 | - [SafetyRating](interfaces/SafetyRating.md) 39 | - [SafetySetting](interfaces/SafetySetting.md) 40 | - [TextCompletion](interfaces/TextCompletion.md) 41 | - [TextPrompt](interfaces/TextPrompt.md) 42 | 43 | ### Type Aliases 44 | 45 | - [SafetyCategory](modules.md#safetycategory) 46 | - [SafetyThreshold](modules.md#safetythreshold) 47 | 48 | ### Functions 49 | 50 | - [palm](modules.md#palm) 51 | 52 | ## Type Aliases 53 | 54 | ### SafetyCategory 55 | 56 | Ƭ **SafetyCategory**: typeof [`category`](interfaces/SafetySetting.md#category) 57 | 58 | Enum of valid categories in `SafetySetting` object. 59 | 60 | #### Defined in 61 | 62 | [text.ts:17](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/text.ts#L17) 63 | 64 | ___ 65 | 66 | ### SafetyThreshold 67 | 68 | Ƭ **SafetyThreshold**: typeof [`threshold`](interfaces/SafetySetting.md#threshold) 69 | 70 | Enum of valid thresholds in `SafetySetting` object. 71 | 72 | #### Defined in 73 | 74 | [text.ts:21](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/text.ts#L21) 75 | 76 | ## Functions 77 | 78 | ### palm 79 | 80 | ▸ **palm**(`apiKey`): `PaLM` 81 | 82 | The entry point into the `palm-lite` library. Usage: 83 | ```typescript 84 | import { palm } from "palm-lite"; 85 | 86 | // Make sure to set the PALM_KEY environment variable. 87 | const PALM_KEY = process.env.PALM_KEY; 88 | const request = palm(PALM_KEY).message({ 89 | prompt: { 90 | messages: [ { content: "Hello there!" } ], 91 | }, 92 | }); 93 | const data = await fetch(request); 94 | const response = await data.json(); 95 | console.log(response.candidates[0].content); 96 | ``` 97 | 98 | #### Parameters 99 | 100 | | Name | Type | Description | 101 | | :------ | :------ | :------ | 102 | | `apiKey` | `string` | PaLM API key | 103 | 104 | #### Returns 105 | 106 | `PaLM` 107 | 108 | Returns an object that lets you make `message`, `text`, and `embedding` request to PaLM API. 109 | 110 | #### Defined in 111 | 112 | [index.ts:118](https://github.com/google/labs-prototypes/blob/99919d5/seeds/palm-lite/src/index.ts#L118) 113 | -------------------------------------------------------------------------------- /seeds/palm-lite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@google-labs/palm-lite", 3 | "version": "0.0.3", 4 | "description": "A zero-dependency client for PaLM APIs", 5 | "main": "./dist/src/index.js", 6 | "exports": "./dist/src/index.js", 7 | "types": "dist/src/index.d.ts", 8 | "type": "module", 9 | "scripts": { 10 | "generate:docs": "wireit", 11 | "test": "wireit", 12 | "build": "wireit", 13 | "build:tsc": "wireit", 14 | "make-types": "wireit", 15 | "make-models": "wireit", 16 | "lint": "wireit" 17 | }, 18 | "wireit": { 19 | "build": { 20 | "dependencies": [ 21 | "build:tsc" 22 | ] 23 | }, 24 | "build:tsc": { 25 | "command": "tsc -b", 26 | "env": { 27 | "FORCE_COLOR": "1" 28 | }, 29 | "files": [ 30 | "src/**/*.ts", 31 | "tests/**/*.ts", 32 | "tsconfig.json", 33 | "../../core/tsconfig/base.json" 34 | ], 35 | "output": [ 36 | "dist/" 37 | ], 38 | "clean": "if-file-deleted" 39 | }, 40 | "test": { 41 | "command": "ava", 42 | "env": { 43 | "FORCE_COLOR": "1" 44 | }, 45 | "dependencies": [ 46 | "build:tsc" 47 | ], 48 | "files": [], 49 | "output": [] 50 | }, 51 | "lint": { 52 | "command": "eslint . --ext .ts", 53 | "env": { 54 | "FORCE_COLOR": "1" 55 | }, 56 | "files": [ 57 | "src/**/*.ts", 58 | "tests/**/*.ts" 59 | ], 60 | "output": [] 61 | }, 62 | "generate:docs": { 63 | "command": "typedoc --plugin typedoc-plugin-markdown", 64 | "files": [ 65 | "src/**/*.ts", 66 | "tsconfig.json", 67 | "../../core/tsconfig/base.json" 68 | ], 69 | "output": [ 70 | "docs/api/" 71 | ] 72 | }, 73 | "make-types": { 74 | "command": "node ./scripts/make-types.js", 75 | "dependencies": [ 76 | "../discovery-types:build" 77 | ], 78 | "files": [ 79 | "scripts/make-types.js" 80 | ], 81 | "output": [ 82 | "src/types.ts" 83 | ] 84 | }, 85 | "make-models": { 86 | "command": "node ./scripts/make-models.js", 87 | "files": [ 88 | "scripts/make-models.js" 89 | ], 90 | "output": [ 91 | "src/models.ts" 92 | ] 93 | } 94 | }, 95 | "repository": { 96 | "type": "git", 97 | "url": "https://github.com/google/labs-prototypes" 98 | }, 99 | "files": [ 100 | "dist/src" 101 | ], 102 | "ava": { 103 | "timeout": "30s", 104 | "files": [ 105 | "tests/**/*.ts" 106 | ], 107 | "workerThreads": false, 108 | "typescript": { 109 | "rewritePaths": { 110 | "./": "dist/" 111 | }, 112 | "compile": false 113 | } 114 | }, 115 | "keywords": [], 116 | "author": "Google Labs Team", 117 | "license": "Apache-2.0", 118 | "bugs": { 119 | "url": "https://github.com/google/labs-prototypes/issues" 120 | }, 121 | "homepage": "https://github.com/google/labs-prototypes/seeds/palm-lite#readme", 122 | "devDependencies": { 123 | "@ava/typescript": "^4.1.0", 124 | "@google-labs/discovery-types": "^0.0.1", 125 | "@google-labs/tsconfig": "^0.0.1", 126 | "@types/node": "^18.19.31", 127 | "@typescript-eslint/eslint-plugin": "^5.62.0", 128 | "@typescript-eslint/parser": "^5.62.0", 129 | "ava": "^5.3.1", 130 | "typedoc": "^0.25.13", 131 | "typescript": "^5.4.5" 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /seeds/palm-lite/scripts/make-models.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2023 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * This script generates a nice list of Types currently available from PaLM API. 9 | */ 10 | 11 | import { config } from "dotenv"; 12 | import { writeFile } from "fs/promises"; 13 | import process from "process"; 14 | 15 | config(); 16 | 17 | const MODELS_URL = "https://generativelanguage.googleapis.com/v1beta2/models"; 18 | 19 | const { PALM_KEY } = process.env; 20 | if (!PALM_KEY) throw new Error("PALM_KEY is not defined"); 21 | 22 | const response = await fetch(`${MODELS_URL}?key=${PALM_KEY}`); 23 | const { models } = await response.json(); 24 | 25 | const modelsByMethod = {}; 26 | models.forEach((model) => { 27 | const supportedMethods = model.supportedGenerationMethods; 28 | supportedMethods.forEach((method) => { 29 | const bag = modelsByMethod[method]; 30 | if (!bag) modelsByMethod[method] = [model]; 31 | else bag.push(model); 32 | }); 33 | delete model.supportedGenerationMethods; 34 | model.name = model.name.replace("models/", ""); 35 | }); 36 | 37 | const preamble = `/** 38 | * This file was generated by scripts/make-models.js on ${new Date().toISOString()} 39 | * Do not edit this file manually. 40 | */ 41 | 42 | `; 43 | 44 | const template = (models) => 45 | `export const models = ${JSON.stringify(models, null, 2)};`; 46 | 47 | await writeFile("./src/models.ts", `${preamble}${template(modelsByMethod)}`); 48 | -------------------------------------------------------------------------------- /seeds/palm-lite/scripts/make-types.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2023 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /** 8 | * This scripts generates PaLM API types from the Google Discover doc. 9 | */ 10 | 11 | import { config } from "dotenv"; 12 | import { toTypes } from "@google-labs/discovery-types"; 13 | import { writeFile } from "fs/promises"; 14 | import process from "process"; 15 | 16 | config(); 17 | 18 | const DISCOVER_DOC_URL = 19 | "https://generativelanguage.googleapis.com/$discovery/rest?version=v1beta2"; 20 | const { PALM_KEY } = process.env; 21 | if (!PALM_KEY) throw new Error("PALM_KEY is not defined"); 22 | 23 | const response = await fetch(`${DISCOVER_DOC_URL}&key=${PALM_KEY}`); 24 | const doc = await response.json(); 25 | const types = toTypes(doc); 26 | const preamble = `/** 27 | * This file was generated by scripts/make-types.js on ${new Date().toISOString()} 28 | * Do not edit this file manually. 29 | */ 30 | 31 | `; 32 | await writeFile("./src/types.ts", `${preamble}${types}`); 33 | -------------------------------------------------------------------------------- /seeds/palm-lite/src/chat.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2023 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { GenerateMessageRequest, MessagePrompt } from "./types.js"; 8 | 9 | /** 10 | * A partical `GenerateMessageRequest` interface, for use with the `Chat` builder. 11 | * It's basically the same as `GenerateMessageRequest`, except that `prompt` is optional. 12 | */ 13 | export interface PartialGenerateMessageRequest 14 | extends Omit { 15 | prompt?: MessagePrompt; 16 | } 17 | 18 | /** 19 | * A convenience builder for chat-like requests. 20 | * 21 | * Implements `GenerateMessageRequest` interface. 22 | * 23 | * Example: 24 | * 25 | * ```typescript 26 | * const chat = new Chat(); 27 | * chat.addMessage("Hello there!"); 28 | * const data = await fetch(palm(PALM_KEY).message(chat)); 29 | * const response = await data.json(); 30 | * ``` 31 | */ 32 | export class Chat implements GenerateMessageRequest { 33 | temperature?: number; 34 | candidateCount?: number; 35 | topP?: number; 36 | topK?: number; 37 | prompt: MessagePrompt = { messages: [] }; 38 | 39 | /** 40 | * Creates a new instance of a `GenerateMessageRequest` builder. You can pass this instance directly into `palm().message()`. The builder follows the typical pattern of builder classes, where you can chain methods together to build the request, like so: 41 | * 42 | * ```typescript 43 | * const chat = new Chat(); 44 | * chat 45 | * .addMessage("Hello there!"). 46 | * .addExample({ 47 | input: "Pull up! All craft pull up!", 48 | output: "It's a trap!", 49 | * }); 50 | * const data = await fetch(palm(PALM_KEY).message(chat)); 51 | * const response = await data.json(); 52 | * ``` 53 | * @param request A partial request object. Just put things like `temperature` and `candidateCount` into it and they will be used in the built instance. 54 | */ 55 | constructor(request?: PartialGenerateMessageRequest) { 56 | Object.assign(this, request); 57 | } 58 | 59 | /** 60 | * Helper for setting the `context` property of the prompt. 61 | * @param context Text that should be provided to the model first to ground the response. 62 | * @returns The builder instance. 63 | */ 64 | context(context: string) { 65 | this.prompt.context = context; 66 | return this; 67 | } 68 | 69 | /** 70 | * Helper for adding an example to the prompt. 71 | * @param example The example of what the model should generate, in the format of `{ input: string, output: string }`. 72 | * @returns The builder instance. 73 | */ 74 | addExample({ input, output }: { input: string; output: string }) { 75 | if (!this.prompt.examples) this.prompt.examples = []; 76 | this.prompt.examples.push({ 77 | input: { content: input }, 78 | output: { content: output }, 79 | }); 80 | return this; 81 | } 82 | 83 | /** 84 | * Helper for adding to the snapshot of recent conversation history for the prompt. This is what you would typically use to start the conversation and help the model keep traack of it. 85 | * @param message The message to add to the history of messages. 86 | * @returns The builder instance. 87 | */ 88 | addMessage(message: string) { 89 | this.prompt?.messages?.push({ content: message }); 90 | return this; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /seeds/palm-lite/src/models.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file was generated by scripts/make-models.js on 2023-06-14T18:18:10.946Z 3 | * Do not edit this file manually. 4 | */ 5 | 6 | export const models = { 7 | generateMessage: [ 8 | { 9 | name: "chat-bison-001", 10 | version: "001", 11 | displayName: "Chat Bison", 12 | description: "Chat-optimized generative language model.", 13 | inputTokenLimit: 4096, 14 | outputTokenLimit: 1024, 15 | temperature: 0.25, 16 | topP: 0.95, 17 | topK: 40, 18 | }, 19 | ], 20 | generateText: [ 21 | { 22 | name: "text-bison-001", 23 | version: "001", 24 | displayName: "Text Bison", 25 | description: "Model targeted for text generation.", 26 | inputTokenLimit: 8196, 27 | outputTokenLimit: 1024, 28 | temperature: 0.7, 29 | topP: 0.95, 30 | topK: 40, 31 | }, 32 | ], 33 | embedText: [ 34 | { 35 | name: "embedding-gecko-001", 36 | version: "001", 37 | displayName: "Embedding Gecko", 38 | description: "Obtain a distributed representation of a text.", 39 | inputTokenLimit: 1024, 40 | outputTokenLimit: 1, 41 | }, 42 | ], 43 | }; 44 | -------------------------------------------------------------------------------- /seeds/palm-lite/tests/chat.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2023 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import test from "ava"; 8 | 9 | import { Chat } from "../src/chat.js"; 10 | 11 | test("Constructor argument pass-through works as advertised", (t) => { 12 | { 13 | const chat = new Chat({ temperature: 0.5 }); 14 | t.is(chat.temperature, 0.5); 15 | } 16 | { 17 | const chat = new Chat(); 18 | t.is(chat.temperature, undefined); 19 | } 20 | { 21 | const chat = new Chat({}); 22 | t.is(chat.temperature, undefined); 23 | } 24 | }); 25 | 26 | test("addMessage() works as advertised", (t) => { 27 | const chat = new Chat(); 28 | t.deepEqual(chat.prompt, { messages: [] }); 29 | 30 | chat.addMessage("Hello there!"); 31 | t.deepEqual(chat.prompt, { messages: [{ content: "Hello there!" }] }); 32 | 33 | chat.addMessage("General Kenobi!"); 34 | t.deepEqual(chat.prompt, { 35 | messages: [{ content: "Hello there!" }, { content: "General Kenobi!" }], 36 | }); 37 | 38 | const returns = chat.addMessage("You are a bold one."); 39 | t.is(returns, chat); 40 | }); 41 | 42 | test("addExample() works as advertised", (t) => { 43 | const chat = new Chat(); 44 | 45 | chat.addExample({ input: "What is the meaning of life?", output: "42" }); 46 | t.deepEqual(chat.prompt, { 47 | examples: [ 48 | { 49 | input: { content: "What is the meaning of life?" }, 50 | output: { content: "42" }, 51 | }, 52 | ], 53 | messages: [], 54 | }); 55 | chat.addExample({ 56 | input: "Pull up! All craft pull up!", 57 | output: "It's a trap!", 58 | }); 59 | t.deepEqual(chat.prompt, { 60 | examples: [ 61 | { 62 | input: { content: "What is the meaning of life?" }, 63 | output: { content: "42" }, 64 | }, 65 | { 66 | input: { content: "Pull up! All craft pull up!" }, 67 | output: { content: "It's a trap!" }, 68 | }, 69 | ], 70 | messages: [], 71 | }); 72 | 73 | const returns = chat.addExample({ 74 | input: "I have a bad feeling about this.", 75 | output: "I have a very bad feeling about this.", 76 | }); 77 | t.is(returns, chat); 78 | }); 79 | 80 | test("context() works as advertised", (t) => { 81 | const chat = new Chat(); 82 | 83 | chat.context("What is the meaning of life?"); 84 | t.deepEqual(chat.prompt, { 85 | context: "What is the meaning of life?", 86 | messages: [], 87 | }); 88 | chat.context("Pull up! All craft pull up!"); 89 | t.deepEqual(chat.prompt, { 90 | context: "Pull up! All craft pull up!", 91 | messages: [], 92 | }); 93 | 94 | const returns = chat.context("I have a bad feeling about this."); 95 | t.is(returns, chat); 96 | }); 97 | -------------------------------------------------------------------------------- /seeds/palm-lite/tests/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2023 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import test from "ava"; 8 | 9 | import { PalmModelMethod, palm } from "../src/index.js"; 10 | 11 | test("palm() produces a PaLM instance", (t) => { 12 | const instance = palm("PALM_KEY"); 13 | t.is(typeof instance.message, "function"); 14 | t.is(typeof instance.text, "function"); 15 | t.is(typeof instance.embedding, "function"); 16 | }); 17 | 18 | test("palm().message() produces a valid Request", async (t) => { 19 | const request = palm("PALM_KEY").message({ 20 | prompt: { 21 | messages: [ 22 | { 23 | content: "Hello there!", 24 | }, 25 | ], 26 | }, 27 | }); 28 | t.true(request instanceof Request); 29 | t.is(request.method, "POST"); 30 | t.is(request.headers.get("Content-Type"), "application/json"); 31 | t.is( 32 | request.url, 33 | "https://generativelanguage.googleapis.com/v1beta2/models/chat-bison-001:generateMessage?key=PALM_KEY" 34 | ); 35 | const body = await request.json(); 36 | t.deepEqual(body, { 37 | prompt: { 38 | messages: [ 39 | { 40 | content: "Hello there!", 41 | }, 42 | ], 43 | }, 44 | }); 45 | }); 46 | 47 | test("palm().text() produces a valid Request", async (t) => { 48 | const request = palm("PALM_KEY").text({ prompt: { text: "" } }); 49 | t.true(request instanceof Request); 50 | t.is(request.method, "POST"); 51 | t.is(request.headers.get("Content-Type"), "application/json"); 52 | t.is( 53 | request.url, 54 | "https://generativelanguage.googleapis.com/v1beta2/models/text-bison-001:generateText?key=PALM_KEY" 55 | ); 56 | const body = await request.json(); 57 | t.deepEqual(body, { prompt: { text: "" } }); 58 | }); 59 | 60 | test("palm().embedding() produces a valid Request", async (t) => { 61 | const request = palm("PALM_KEY").embedding({ text: "Hello there!" }); 62 | t.true(request instanceof Request); 63 | t.is(request.method, "POST"); 64 | t.is(request.headers.get("Content-Type"), "application/json"); 65 | t.is( 66 | request.url, 67 | "https://generativelanguage.googleapis.com/v1beta2/models/embedding-gecko-001:embedText?key=PALM_KEY" 68 | ); 69 | const body = await request.json(); 70 | t.deepEqual(body, { text: "Hello there!" }); 71 | }); 72 | 73 | test("palm().getModelId() returns the right default model ids", (t) => { 74 | t.is( 75 | palm("PALM_KEY").getModelId(PalmModelMethod.GenerateMessage), 76 | "chat-bison-001" 77 | ); 78 | t.is( 79 | palm("PALM_KEY").getModelId(PalmModelMethod.GenerateText), 80 | "text-bison-001" 81 | ); 82 | t.is( 83 | palm("PALM_KEY").getModelId(PalmModelMethod.EmbedText), 84 | "embedding-gecko-001" 85 | ); 86 | }); 87 | -------------------------------------------------------------------------------- /seeds/palm-lite/tests/text.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2023 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import test from "ava"; 8 | 9 | import { Text } from "../src/text.js"; 10 | 11 | test("Constructor argument pass-through works as advertised", (t) => { 12 | { 13 | const text = new Text({ temperature: 0.5 }); 14 | t.is(text.temperature, 0.5); 15 | } 16 | { 17 | const text = new Text(); 18 | t.is(text.temperature, undefined); 19 | } 20 | { 21 | const text = new Text({}); 22 | t.is(text.temperature, undefined); 23 | } 24 | }); 25 | 26 | test("text() works as advertised", (t) => { 27 | const text = new Text(); 28 | t.deepEqual(text.prompt, { text: "" }); 29 | 30 | text.text("Hello there!"); 31 | t.deepEqual(text.prompt, { text: "Hello there!" }); 32 | 33 | const returns = text.text("General Kenobi!"); 34 | t.is(returns, text); 35 | }); 36 | 37 | test("addSafetySetting() works as adversited", (t) => { 38 | const text = new Text(); 39 | 40 | text.addSafetySetting("HARM_CATEGORY_DANGEROUS", "BLOCK_LOW_AND_ABOVE"); 41 | t.deepEqual(text.safetySettings, [ 42 | { 43 | category: "HARM_CATEGORY_DANGEROUS", 44 | threshold: "BLOCK_LOW_AND_ABOVE", 45 | }, 46 | ]); 47 | 48 | text.addSafetySetting("HARM_CATEGORY_MEDICAL", "BLOCK_ONLY_HIGH"); 49 | t.deepEqual(text.safetySettings, [ 50 | { 51 | category: "HARM_CATEGORY_DANGEROUS", 52 | threshold: "BLOCK_LOW_AND_ABOVE", 53 | }, 54 | { 55 | category: "HARM_CATEGORY_MEDICAL", 56 | threshold: "BLOCK_ONLY_HIGH", 57 | }, 58 | ]); 59 | 60 | const returns = text.addSafetySetting( 61 | "HARM_CATEGORY_VIOLENCE", 62 | "HARM_BLOCK_THRESHOLD_UNSPECIFIED" 63 | ); 64 | t.is(returns, text); 65 | }); 66 | 67 | test("addStopSequence() works as advertised", (t) => { 68 | const text = new Text(); 69 | 70 | text.addStopSequence("RESPONSE"); 71 | t.deepEqual(text.stopSequences, ["RESPONSE"]); 72 | 73 | text.addStopSequence("=="); 74 | t.deepEqual(text.stopSequences, ["RESPONSE", "=="]); 75 | 76 | const returns = text.addStopSequence("It's a trap!"); 77 | t.is(returns, text); 78 | }); 79 | -------------------------------------------------------------------------------- /seeds/palm-lite/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "outDir": "./dist" 5 | }, 6 | "include": ["src/**/*", "tests/**/*"], 7 | "extends": "../../core/tsconfig/base.json", 8 | "typedocOptions": { 9 | "entryPoints": "./src/index.ts", 10 | "out": "./docs/api", 11 | "githubPages": "false" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /seeds/team-experiments/.gitignore: -------------------------------------------------------------------------------- 1 | .vercel 2 | -------------------------------------------------------------------------------- /seeds/team-experiments/README.md: -------------------------------------------------------------------------------- 1 | # AI Teams Experiments 2 | 3 | This is a Breadboard starter project. 4 | 5 | ## Setup 6 | 7 | Install deps 8 | 9 | ```bash 10 | npm i -g vercel 11 | npm i 12 | ``` 13 | 14 | Save keys. Create a file named `.env` in this directory. Add the following keys: 15 | 16 | ```bash 17 | GEMINI_KEY="your key goes here" 18 | model="gemini-1.5-pro-latest" 19 | ``` 20 | 21 | ## Run 22 | 23 | ```bash 24 | npm i && npm run dev 25 | ``` 26 | -------------------------------------------------------------------------------- /seeds/team-experiments/api/proxy.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { 8 | AnyProxyRequestMessage, 9 | HTTPServerTransport, 10 | ProxyServer, 11 | ProxyServerConfig, 12 | ServerResponse, 13 | hasOrigin, 14 | } from "@google-labs/breadboard/remote"; 15 | import type { VercelRequest, VercelResponse } from "@vercel/node"; 16 | 17 | import Core from "@google-labs/core-kit"; 18 | import { asRuntimeKit } from "@google-labs/breadboard"; 19 | import { IncomingMessage } from "http"; 20 | 21 | const config: ProxyServerConfig = { 22 | kits: [asRuntimeKit(Core)], 23 | proxy: [ 24 | "fetch", 25 | { 26 | node: "secrets", 27 | tunnel: { 28 | GEMINI_KEY: { 29 | to: "fetch", 30 | when: { 31 | url: hasOrigin("https://generativelanguage.googleapis.com"), 32 | }, 33 | }, 34 | SCRAPING_BEE_KEY: { 35 | to: "fetch", 36 | when: { 37 | url: hasOrigin("https://app.scrapingbee.com/"), 38 | }, 39 | }, 40 | }, 41 | }, 42 | ], 43 | }; 44 | 45 | class ResponseAdapter implements ServerResponse { 46 | #response: VercelResponse; 47 | 48 | constructor(response: VercelResponse) { 49 | this.#response = response; 50 | } 51 | 52 | header(field: string, value: string): unknown { 53 | this.#response.setHeader(field, value); 54 | return this; 55 | } 56 | 57 | write(chunk: unknown): boolean { 58 | return this.#response.write(chunk); 59 | } 60 | 61 | end(): unknown { 62 | this.#response.end(); 63 | return this; 64 | } 65 | } 66 | 67 | const extractRequestBody = async (request: IncomingMessage) => { 68 | return new Promise((resolve, reject) => { 69 | let body = ""; 70 | request.on("data", (chunk) => { 71 | body += chunk.toString(); 72 | }); 73 | request.on("end", () => { 74 | resolve(JSON.parse(body) as AnyProxyRequestMessage); 75 | }); 76 | request.on("error", reject); 77 | }); 78 | }; 79 | 80 | export default async function handler( 81 | request: VercelRequest, 82 | response: VercelResponse 83 | ) { 84 | if (request.method === "GET") { 85 | response.setHeader("Content-Type", "text/html"); 86 | response.write("

USE POST

"); 87 | response.end(); 88 | return; 89 | } 90 | const body = await extractRequestBody(request); 91 | const server = new ProxyServer( 92 | new HTTPServerTransport({ body }, new ResponseAdapter(response)) 93 | ); 94 | try { 95 | await server.serve(config); 96 | } catch (e) { 97 | response.statusCode = 500; 98 | response.setHeader("Content-Type", "text/html"); 99 | response.write(`

Server Error: ${(e as Error).message}

`); 100 | response.end(); 101 | } 102 | return; 103 | } 104 | -------------------------------------------------------------------------------- /seeds/team-experiments/api/secrets.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | export function GET() { 8 | const model = process.env.model; 9 | let result; 10 | if (!model) { 11 | result = JSON.stringify({ error: "Could not retrieve secrets" }); 12 | } else { 13 | result = JSON.stringify({ parsed: { model } }); 14 | } 15 | return new Response(result, { 16 | status: 200, 17 | headers: { 18 | "Content-Type": "application/json", 19 | }, 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /seeds/team-experiments/graphs/boards/blank.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Blank board", 3 | "description": "A blank board. Use it to start a new board", 4 | "$schema": "https://raw.githubusercontent.com/breadboard-ai/breadboard/@google-labs/breadboard-schema@1.4.0/packages/schema/breadboard.schema.json", 5 | "version": "0.0.1", 6 | "edges": [ 7 | { 8 | "from": "input-1", 9 | "to": "output-2", 10 | "out": "text", 11 | "in": "text" 12 | } 13 | ], 14 | "nodes": [ 15 | { 16 | "id": "output-2", 17 | "type": "output", 18 | "configuration": { 19 | "schema": { 20 | "type": "object", 21 | "properties": { 22 | "text": { 23 | "type": "string", 24 | "title": "text" 25 | } 26 | } 27 | } 28 | } 29 | }, 30 | { 31 | "id": "input-1", 32 | "type": "input", 33 | "configuration": { 34 | "schema": { 35 | "type": "object", 36 | "properties": { 37 | "text": { 38 | "type": "string", 39 | "title": "text" 40 | } 41 | }, 42 | "required": [ 43 | "text" 44 | ] 45 | } 46 | } 47 | } 48 | ], 49 | "kits": [], 50 | "graphs": {} 51 | } -------------------------------------------------------------------------------- /seeds/team-experiments/graphs/boards/subgraph-example.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Subgraph Example", 3 | "description": "An example of using subgraphs within a board", 4 | "$schema": "https://raw.githubusercontent.com/breadboard-ai/breadboard/@google-labs/breadboard-schema@1.4.0/packages/schema/breadboard.schema.json", 5 | "version": "0.0.1", 6 | "edges": [ 7 | { 8 | "from": "invoke-3", 9 | "to": "output-2", 10 | "out": "hello", 11 | "in": "hello" 12 | }, 13 | { 14 | "from": "input-1", 15 | "to": "invoke-3", 16 | "out": "text", 17 | "in": "text" 18 | } 19 | ], 20 | "nodes": [ 21 | { 22 | "id": "output-2", 23 | "type": "output", 24 | "configuration": { 25 | "schema": { 26 | "type": "object", 27 | "properties": { 28 | "hello": { 29 | "type": "string", 30 | "title": "hello" 31 | } 32 | } 33 | } 34 | } 35 | }, 36 | { 37 | "id": "invoke-3", 38 | "type": "invoke", 39 | "configuration": { 40 | "$board": "#mySubgraph" 41 | }, 42 | "metadata": { 43 | "title": "Subgraph Invoker" 44 | } 45 | }, 46 | { 47 | "id": "input-1", 48 | "type": "input", 49 | "configuration": { 50 | "schema": { 51 | "type": "object", 52 | "properties": { 53 | "text": { 54 | "type": "string", 55 | "title": "text" 56 | } 57 | }, 58 | "required": [ 59 | "text" 60 | ] 61 | } 62 | } 63 | } 64 | ], 65 | "kits": [], 66 | "graphs": { 67 | "mySubgraph": { 68 | "edges": [ 69 | { 70 | "from": "fn-3", 71 | "to": "output-2", 72 | "out": "hello", 73 | "in": "hello" 74 | }, 75 | { 76 | "from": "input-1", 77 | "to": "fn-3", 78 | "out": "text", 79 | "in": "text" 80 | } 81 | ], 82 | "nodes": [ 83 | { 84 | "id": "output-2", 85 | "type": "output", 86 | "configuration": { 87 | "schema": { 88 | "type": "object", 89 | "properties": { 90 | "hello": { 91 | "type": "string", 92 | "title": "hello" 93 | } 94 | } 95 | } 96 | } 97 | }, 98 | { 99 | "id": "fn-3", 100 | "type": "runJavascript", 101 | "configuration": { 102 | "code": "const fn_3 = ({ text }) => {\n return { hello: `HELLO, ${text}` };\n};", 103 | "name": "fn_3", 104 | "raw": true 105 | }, 106 | "metadata": { 107 | "title": "Hello Maker" 108 | } 109 | }, 110 | { 111 | "id": "input-1", 112 | "type": "input", 113 | "configuration": { 114 | "schema": { 115 | "type": "object", 116 | "properties": { 117 | "text": { 118 | "type": "string", 119 | "title": "text" 120 | } 121 | }, 122 | "required": [ 123 | "text" 124 | ] 125 | } 126 | } 127 | } 128 | ], 129 | "graphs": {} 130 | } 131 | } 132 | } -------------------------------------------------------------------------------- /seeds/team-experiments/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Teams Experiments 6 | 7 | 8 | 9 | 15 | 16 | -------------------------------------------------------------------------------- /seeds/team-experiments/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@google-labs/team-experiments", 3 | "version": "1.0.0", 4 | "description": "Experimenting with teams of workers", 5 | "type": "module", 6 | "scripts": { 7 | "build": "vite build", 8 | "dev:board": "breadboard debug src/boards --watch -o graphs", 9 | "dev:server": "wireit", 10 | "dev": "npm run dev:server --watch" 11 | }, 12 | "wireit": { 13 | "dev:server": { 14 | "command": "tsx src/server/index.ts", 15 | "service": true, 16 | "files": [ 17 | "src/server/**/*.ts", 18 | "tsconfig.json" 19 | ] 20 | } 21 | }, 22 | "keywords": [], 23 | "author": "Your Name Here", 24 | "license": "Apache-2.0", 25 | "devDependencies": { 26 | "tsx": "^4.7.2", 27 | "typescript": "^5.4.5", 28 | "vite": "^5.2.9", 29 | "vite-plugin-vercel": "^6.0.1", 30 | "wireit": "^0.14.4" 31 | }, 32 | "dependencies": { 33 | "@google-labs/agent-kit": "^0.7.0", 34 | "@google-labs/breadboard": "^0.20.0", 35 | "@google-labs/breadboard-cli": "^0.9.3", 36 | "@google-labs/core-kit": "^0.9.0", 37 | "@google-labs/gemini-kit": "^0.4.0", 38 | "@google-labs/template-kit": "^0.3.2", 39 | "@google-labs/json-kit": "^0.3.0", 40 | "@types/markdown-it": "^14.0.1", 41 | "@vercel/node": "^3.0.27", 42 | "dotenv": "^16.4.5", 43 | "lit": "^3.1.3", 44 | "markdown-it": "^14.1.0", 45 | "puppeteer": "^22.6.5" 46 | }, 47 | "private": true 48 | } 49 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/bgl/book/outline-critic.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Outline Critic", 3 | "description": "A prompt to conjure up the book outline critic", 4 | "version": "0.0.1", 5 | "nodes": [ 6 | { 7 | "type": "input", 8 | "id": "input", 9 | "configuration": { 10 | "schema": { 11 | "type": "object", 12 | "properties": { 13 | "fictiongenre": { 14 | "type": "string", 15 | "title": "Fiction Genre", 16 | "examples": [] 17 | } 18 | }, 19 | "required": [] 20 | } 21 | }, 22 | "metadata": { 23 | "visual": { 24 | "x": 0, 25 | "y": 11 26 | } 27 | } 28 | }, 29 | { 30 | "type": "output", 31 | "id": "output", 32 | "configuration": { 33 | "schema": { 34 | "type": "object", 35 | "properties": { 36 | "prompt": { 37 | "type": "string", 38 | "title": "prompt", 39 | "examples": [] 40 | } 41 | }, 42 | "required": [] 43 | } 44 | }, 45 | "metadata": { 46 | "visual": { 47 | "x": 784, 48 | "y": 0 49 | } 50 | } 51 | }, 52 | { 53 | "id": "promptTemplate-355784ad", 54 | "type": "promptTemplate", 55 | "metadata": { 56 | "title": "Book Critic Persona", 57 | "logLevel": "debug", 58 | "visual": { 59 | "x": 238, 60 | "y": 0 61 | } 62 | }, 63 | "configuration": { 64 | "template": "You are an accomplished book editor and publisher, specializing in the {{fiction_genre}} genre. Your specialty is being able to recognize what story elements and characters will make a great novel. You are great at giving insightful feedback to authors to help them make their novels better.\n" 65 | } 66 | }, 67 | { 68 | "id": "promptTemplate-b043199d", 69 | "type": "promptTemplate", 70 | "metadata": { 71 | "visual": { 72 | "x": 522, 73 | "y": 0 74 | }, 75 | "title": "Critique Outline", 76 | "logLevel": "debug" 77 | }, 78 | "configuration": { 79 | "template": "{{bookcritic}}\n\nYour friend, an accomplished author, has written an outline for a new book and has asked you for insightful feedback. \n\nReview the outline that the author submitted. Please read it very carefully. Then, provide feedback for the author. Give the author up to five specific suggestions to make the novel more compelling and have more chance to be a bestseller!\n\nYour feedback and suggestions:\n" 80 | } 81 | } 82 | ], 83 | "edges": [ 84 | { 85 | "from": "input", 86 | "to": "promptTemplate-355784ad", 87 | "out": "fictiongenre", 88 | "in": "fiction_genre" 89 | }, 90 | { 91 | "from": "promptTemplate-355784ad", 92 | "to": "promptTemplate-b043199d", 93 | "out": "prompt", 94 | "in": "bookcritic" 95 | }, 96 | { 97 | "from": "promptTemplate-b043199d", 98 | "to": "output", 99 | "out": "prompt", 100 | "in": "prompt" 101 | } 102 | ] 103 | } -------------------------------------------------------------------------------- /seeds/team-experiments/public/bgl/book/outline-editor.bgl.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Outline Editor", 3 | "description": "Conjures up the Outline Editor persona", 4 | "version": "0.0.1", 5 | "nodes": [ 6 | { 7 | "type": "input", 8 | "id": "input", 9 | "configuration": { 10 | "schema": { 11 | "type": "object", 12 | "properties": { 13 | "author": { 14 | "type": "string", 15 | "title": "Author", 16 | "examples": [] 17 | }, 18 | "pagetarget": { 19 | "type": "string", 20 | "title": "Target number of pages", 21 | "examples": [] 22 | }, 23 | "storyarc": { 24 | "type": "string", 25 | "title": "Story Arc", 26 | "examples": [] 27 | }, 28 | "workingtitle": { 29 | "type": "string", 30 | "title": "The working title", 31 | "examples": [] 32 | } 33 | }, 34 | "required": [] 35 | } 36 | }, 37 | "metadata": { 38 | "visual": { 39 | "x": 0, 40 | "y": 11 41 | } 42 | } 43 | }, 44 | { 45 | "type": "output", 46 | "id": "output", 47 | "configuration": { 48 | "schema": { 49 | "type": "object", 50 | "properties": { 51 | "text": { 52 | "type": "string", 53 | "title": "text" 54 | } 55 | } 56 | } 57 | }, 58 | "metadata": { 59 | "visual": { 60 | "x": 476, 61 | "y": 33 62 | } 63 | } 64 | }, 65 | { 66 | "id": "promptTemplate-12efa891", 67 | "type": "promptTemplate", 68 | "metadata": { 69 | "visual": { 70 | "x": 210, 71 | "y": 0 72 | }, 73 | "title": "Create Template", 74 | "logLevel": "debug" 75 | }, 76 | "configuration": { 77 | "template": "{{author}}\n\nYour first step was to write a detailed outline for the novel. You are shooting for around {{pagetarget}} pages for the finished novel.\n\nThe key themes of the novel are: \n{{storyarc}}\n\nYou have written a first draft of your outline, and then asked an outstanding book editor and publisher to give you suggestions. Based on their suggestions you are going to rewrite and improve your outline.\n\nThis is great feedback and you want to try to incorporate some of it, while still staying true to your original vision for the novel. Please write an improved outline for your novel, by taking the feedback into account. \n\nREVISED OUTLINE FOR {{workingtitle}}:\n" 78 | } 79 | } 80 | ], 81 | "edges": [ 82 | { 83 | "from": "promptTemplate-12efa891", 84 | "to": "output", 85 | "out": "prompt", 86 | "in": "text" 87 | }, 88 | { 89 | "from": "input", 90 | "to": "promptTemplate-12efa891", 91 | "out": "author", 92 | "in": "author" 93 | }, 94 | { 95 | "from": "input", 96 | "to": "promptTemplate-12efa891", 97 | "out": "pagetarget", 98 | "in": "pagetarget" 99 | }, 100 | { 101 | "from": "input", 102 | "to": "promptTemplate-12efa891", 103 | "out": "storyarc", 104 | "in": "storyarc" 105 | }, 106 | { 107 | "from": "input", 108 | "to": "promptTemplate-12efa891", 109 | "out": "workingtitle", 110 | "in": "workingtitle" 111 | } 112 | ] 113 | } -------------------------------------------------------------------------------- /seeds/team-experiments/public/bgl/insta/get-page.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Internet", 3 | "description": "Provides access to the Internet. Given a URL, returns back the text content of the web page.", 4 | "version": "0.0.1", 5 | "nodes": [ 6 | { 7 | "type": "input", 8 | "id": "input", 9 | "configuration": { 10 | "schema": { 11 | "type": "object", 12 | "properties": { 13 | "url": { 14 | "type": "string", 15 | "title": "URL", 16 | "examples": [] 17 | } 18 | }, 19 | "required": [] 20 | } 21 | }, 22 | "metadata": { 23 | "visual": { 24 | "x": -360, 25 | "y": -56 26 | } 27 | } 28 | }, 29 | { 30 | "type": "output", 31 | "id": "output", 32 | "configuration": { 33 | "schema": { 34 | "type": "object", 35 | "properties": { 36 | "contents": { 37 | "type": "string", 38 | "title": "Contents", 39 | "examples": [] 40 | } 41 | }, 42 | "required": [] 43 | } 44 | }, 45 | "metadata": { 46 | "visual": { 47 | "x": 403, 48 | "y": -63 49 | } 50 | } 51 | }, 52 | { 53 | "id": "fetch-6a37cd89", 54 | "type": "fetch", 55 | "metadata": { 56 | "visual": { 57 | "x": 110, 58 | "y": -193 59 | }, 60 | "title": "Get Page Contents", 61 | "logLevel": "debug" 62 | } 63 | }, 64 | { 65 | "id": "urlTemplate-8d425f0c", 66 | "type": "urlTemplate", 67 | "metadata": { 68 | "visual": { 69 | "x": -159, 70 | "y": -82 71 | }, 72 | "title": "Make URL", 73 | "logLevel": "debug" 74 | }, 75 | "configuration": { 76 | "template": "/api/browse?url={url}" 77 | } 78 | } 79 | ], 80 | "edges": [ 81 | { 82 | "from": "urlTemplate-8d425f0c", 83 | "to": "fetch-6a37cd89", 84 | "out": "url", 85 | "in": "url" 86 | }, 87 | { 88 | "from": "fetch-6a37cd89", 89 | "to": "output", 90 | "out": "response", 91 | "in": "contents" 92 | }, 93 | { 94 | "from": "input", 95 | "to": "urlTemplate-8d425f0c", 96 | "out": "url", 97 | "in": "url" 98 | } 99 | ] 100 | } -------------------------------------------------------------------------------- /seeds/team-experiments/public/bgl/insta/loop-example.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Blank board", 3 | "description": "A blank board. Use it as a starting point for your creations.", 4 | "version": "0.0.1", 5 | "nodes": [ 6 | { 7 | "id": "human-df33b091", 8 | "type": "human", 9 | "metadata": { 10 | "visual": { 11 | "x": -244, 12 | "y": -77 13 | }, 14 | "logLevel": "debug" 15 | } 16 | }, 17 | { 18 | "id": "worker-d7be5a87", 19 | "type": "worker", 20 | "metadata": { 21 | "visual": { 22 | "x": 1, 23 | "y": 182 24 | } 25 | }, 26 | "configuration": { 27 | "instruction": "You are a friendly chat bot who is happy to make up whatever it wants, just to keep the user entertained and pleased." 28 | } 29 | }, 30 | { 31 | "id": "input-7251140f", 32 | "type": "input", 33 | "configuration": { 34 | "schema": { 35 | "properties": { 36 | "context": { 37 | "type": "object", 38 | "title": "Context", 39 | "examples": [], 40 | "default": "[]" 41 | } 42 | }, 43 | "type": "object", 44 | "required": [] 45 | } 46 | }, 47 | "metadata": { 48 | "visual": { 49 | "x": -458, 50 | "y": -76 51 | } 52 | } 53 | } 54 | ], 55 | "edges": [ 56 | { 57 | "from": "human-df33b091", 58 | "to": "worker-d7be5a87", 59 | "out": "context", 60 | "in": "context" 61 | }, 62 | { 63 | "from": "input-7251140f", 64 | "to": "human-df33b091", 65 | "out": "context", 66 | "in": "context" 67 | }, 68 | { 69 | "from": "worker-d7be5a87", 70 | "to": "human-df33b091", 71 | "out": "context", 72 | "in": "context" 73 | } 74 | ] 75 | } -------------------------------------------------------------------------------- /seeds/team-experiments/public/bgl/insta/mock-get-page.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Get Web Page", 3 | "description": "Given a URL, returns back the text content of the web page.", 4 | "version": "0.0.1", 5 | "nodes": [ 6 | { 7 | "type": "input", 8 | "id": "input", 9 | "configuration": { 10 | "schema": { 11 | "type": "object", 12 | "properties": { 13 | "text": { 14 | "type": "string", 15 | "title": "text", 16 | "examples": [ 17 | "https://breadboard-ai.github.io/breadboard/" 18 | ] 19 | } 20 | }, 21 | "required": [] 22 | } 23 | }, 24 | "metadata": { 25 | "visual": { 26 | "x": -266, 27 | "y": 85 28 | } 29 | } 30 | }, 31 | { 32 | "type": "output", 33 | "id": "output", 34 | "configuration": { 35 | "schema": { 36 | "type": "object", 37 | "properties": { 38 | "text": { 39 | "type": "string", 40 | "title": "text" 41 | } 42 | } 43 | } 44 | }, 45 | "metadata": { 46 | "visual": { 47 | "x": 437, 48 | "y": 172 49 | } 50 | } 51 | }, 52 | { 53 | "id": "promptTemplate-54c7a477", 54 | "type": "promptTemplate", 55 | "metadata": { 56 | "visual": { 57 | "x": -1, 58 | "y": 28 59 | } 60 | }, 61 | "configuration": { 62 | "template": "{\"url\":\"{{url}}\",\"content\":\"Show docs\\nBREADBOARD\\nA GENERATIVE AI PROTOTYPE FRAMEWORK\\nGET STARTED →\\nMake Anything\\n\\nBreadboard lets you design sophisticated Generative AI experiences. Build complex workflows visually, free from API wrangling.\\n\\nDebug On the Fly\\n\\nStart making boards and see them visualized in real time.\\n\\nFlexible Kits\\n\\nNo need to reinvent the wheel. From AI to webcam capture, we’ve got you covered.\\n\\nOpen Source\\n\\nWant to contribute? Feel free! Breadboard is completely open source on GitHub.\\n\\nThe Happy Path\\n\\nIf you're eager to start making boards with Breadboard as quickly as possible, here's a yellow brick road that will take you there. It's not quite a tutorial, but more like a step-by-step onboarding guide with some of the best practices baked in.\\n\\nGET GOING →\\nGenerate Web Apps\\n\\nMade something awesome? Share it with others and let them play with it immediately!\\n\\nCopyright 2024 Google LLC. Code licensed under Apache License 2.0\"}\n" 63 | } 64 | } 65 | ], 66 | "edges": [ 67 | { 68 | "from": "input", 69 | "to": "promptTemplate-54c7a477", 70 | "out": "text", 71 | "in": "url" 72 | }, 73 | { 74 | "from": "promptTemplate-54c7a477", 75 | "to": "output", 76 | "out": "prompt", 77 | "in": "text" 78 | } 79 | ] 80 | } -------------------------------------------------------------------------------- /seeds/team-experiments/public/bgl/insta/tool-search.bgl.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Search the Web", 3 | "description": "Given a term, searches the Web for it and returns a list of links and descriptions that match.", 4 | "version": "0.0.1", 5 | "nodes": [ 6 | { 7 | "type": "input", 8 | "id": "input", 9 | "configuration": { 10 | "schema": { 11 | "type": "object", 12 | "properties": { 13 | "search": { 14 | "type": "string", 15 | "title": "Search", 16 | "examples": [], 17 | "description": "The term to search the Web for" 18 | } 19 | }, 20 | "required": [] 21 | } 22 | }, 23 | "metadata": { 24 | "visual": { 25 | "x": 14, 26 | "y": 352 27 | } 28 | } 29 | }, 30 | { 31 | "type": "output", 32 | "id": "output", 33 | "configuration": { 34 | "schema": { 35 | "type": "object", 36 | "properties": { 37 | "json": { 38 | "type": "object", 39 | "title": "JSON", 40 | "examples": [] 41 | } 42 | }, 43 | "required": [] 44 | } 45 | }, 46 | "metadata": { 47 | "visual": { 48 | "x": 594.9999999999999, 49 | "y": 505 50 | } 51 | } 52 | }, 53 | { 54 | "id": "fetch-27da0eda", 55 | "type": "fetch", 56 | "metadata": { 57 | "visual": { 58 | "x": 568, 59 | "y": 150.9999999999999 60 | }, 61 | "title": "Scraping Bee", 62 | "description": "Calling Scraping Bee to Get the Contents", 63 | "logLevel": "debug" 64 | }, 65 | "configuration": { 66 | "method": "GET" 67 | } 68 | }, 69 | { 70 | "id": "urlTemplate-77553e6f", 71 | "type": "urlTemplate", 72 | "configuration": { 73 | "template": "https://app.scrapingbee.com/api/v1/store/google?api_key={SCRAPING_BEE_KEY}&search={search}&language=en&nb_results=30" 74 | }, 75 | "metadata": { 76 | "visual": { 77 | "x": 270, 78 | "y": 226 79 | }, 80 | "title": "Scraping Bee API Template", 81 | "logLevel": "debug" 82 | } 83 | }, 84 | { 85 | "id": "secrets-197969de", 86 | "type": "secrets", 87 | "configuration": { 88 | "keys": [ 89 | "SCRAPING_BEE_KEY" 90 | ] 91 | }, 92 | "metadata": { 93 | "visual": { 94 | "x": 25, 95 | "y": 3.9999999999998863 96 | }, 97 | "title": "Get API Key", 98 | "description": "Asking for API Key", 99 | "logLevel": "debug" 100 | } 101 | } 102 | ], 103 | "edges": [ 104 | { 105 | "from": "urlTemplate-77553e6f", 106 | "to": "fetch-27da0eda", 107 | "out": "url", 108 | "in": "url" 109 | }, 110 | { 111 | "from": "secrets-197969de", 112 | "to": "urlTemplate-77553e6f", 113 | "out": "SCRAPING_BEE_KEY", 114 | "in": "SCRAPING_BEE_KEY" 115 | }, 116 | { 117 | "from": "input", 118 | "to": "urlTemplate-77553e6f", 119 | "out": "search", 120 | "in": "search" 121 | }, 122 | { 123 | "from": "fetch-27da0eda", 124 | "to": "output", 125 | "out": "response", 126 | "in": "json" 127 | } 128 | ] 129 | } -------------------------------------------------------------------------------- /seeds/team-experiments/public/bgl/test-invokes.bgl.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Test Invokes", 3 | "description": "Testing various ways of invoking things", 4 | "version": "0.0.1", 5 | "nodes": [ 6 | { 7 | "type": "input", 8 | "id": "input", 9 | "configuration": { 10 | "schema": { 11 | "type": "object", 12 | "properties": { 13 | "text": { 14 | "type": "string", 15 | "title": "text", 16 | "examples": [], 17 | "format": "multiline" 18 | } 19 | }, 20 | "required": [] 21 | } 22 | }, 23 | "metadata": { 24 | "visual": { 25 | "x": -227, 26 | "y": 50 27 | } 28 | } 29 | }, 30 | { 31 | "type": "output", 32 | "id": "output", 33 | "configuration": { 34 | "schema": { 35 | "type": "object", 36 | "properties": { 37 | "text": { 38 | "type": "string", 39 | "title": "text" 40 | } 41 | } 42 | } 43 | }, 44 | "metadata": { 45 | "visual": { 46 | "x": 329, 47 | "y": 18 48 | } 49 | } 50 | }, 51 | { 52 | "id": "invoke-5e1d840c", 53 | "type": "invoke", 54 | "metadata": { 55 | "title": "Nice Title", 56 | "visual": { 57 | "x": 36, 58 | "y": -187 59 | } 60 | }, 61 | "configuration": { 62 | "$board": { 63 | "kind": "board", 64 | "path": "https://breadboard-ai.web.app/graphs/ad-writer-2.json" 65 | } 66 | } 67 | } 68 | ], 69 | "edges": [ 70 | { 71 | "from": "input", 72 | "out": "text", 73 | "to": "invoke-5e1d840c", 74 | "in": "context" 75 | }, 76 | { 77 | "from": "invoke-5e1d840c", 78 | "to": "output", 79 | "out": "json", 80 | "in": "text" 81 | } 82 | ] 83 | } 84 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/bgl/today.bgl.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Today", 3 | "description": "Returns today's date.", 4 | "version": "0.0.1", 5 | "nodes": [ 6 | { 7 | "type": "output", 8 | "id": "output", 9 | "configuration": { 10 | "schema": { 11 | "type": "object", 12 | "properties": { 13 | "date": { 14 | "type": "string", 15 | "title": "date", 16 | "examples": [] 17 | } 18 | }, 19 | "required": [] 20 | } 21 | }, 22 | "metadata": { 23 | "visual": { 24 | "x": 196, 25 | "y": 0 26 | } 27 | } 28 | }, 29 | { 30 | "id": "runJavascript-1a44bd49", 31 | "type": "runJavascript", 32 | "metadata": { 33 | "visual": { 34 | "x": -101, 35 | "y": -52 36 | } 37 | }, 38 | "configuration": { 39 | "name": "run", 40 | "code": "const run = () => new Date().toDateString();" 41 | } 42 | }, 43 | { 44 | "id": "input-32145e88", 45 | "type": "input", 46 | "metadata": { 47 | "visual": { 48 | "x": -401, 49 | "y": -2 50 | } 51 | }, 52 | "configuration": { 53 | "schema": { 54 | "properties": { 55 | "question": { 56 | "type": "string", 57 | "title": "Question", 58 | "examples": [], 59 | "description": "The question must be \"what is today?\"" 60 | } 61 | }, 62 | "type": "object", 63 | "required": [] 64 | } 65 | } 66 | } 67 | ], 68 | "edges": [ 69 | { 70 | "from": "runJavascript-1a44bd49", 71 | "to": "output", 72 | "out": "result", 73 | "in": "date" 74 | }, 75 | { 76 | "from": "input-32145e88", 77 | "to": "runJavascript-1a44bd49", 78 | "out": "question", 79 | "in": "question" 80 | } 81 | ] 82 | } -------------------------------------------------------------------------------- /seeds/team-experiments/public/bgl/use-tools.bgl.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Use Tools", 3 | "description": "An example for using tools", 4 | "version": "0.0.1", 5 | "nodes": [ 6 | { 7 | "type": "input", 8 | "id": "input", 9 | "configuration": { 10 | "schema": { 11 | "type": "object", 12 | "properties": { 13 | "text": { 14 | "type": "string", 15 | "title": "text" 16 | } 17 | } 18 | } 19 | }, 20 | "metadata": { 21 | "visual": { 22 | "x": -180, 23 | "y": 104 24 | } 25 | } 26 | }, 27 | { 28 | "type": "output", 29 | "id": "output", 30 | "configuration": { 31 | "schema": { 32 | "type": "object", 33 | "properties": { 34 | "text": { 35 | "type": "string", 36 | "title": "text" 37 | } 38 | } 39 | } 40 | }, 41 | "metadata": { 42 | "visual": { 43 | "x": 253, 44 | "y": 42 45 | } 46 | } 47 | }, 48 | { 49 | "id": "toolWorker-09264f9f", 50 | "type": "toolWorker", 51 | "metadata": { 52 | "visual": { 53 | "x": -1, 54 | "y": -91 55 | } 56 | }, 57 | "configuration": { 58 | "instruction": "You are a friendly assistant who helps answering user's question using tools. When the question does not require a tool, just answer it without calling a tool.", 59 | "tools": [ 60 | { 61 | "kind": "board", 62 | "path": "file://fsapi~bgl/today.bgl.json" 63 | } 64 | ] 65 | } 66 | } 67 | ], 68 | "edges": [ 69 | { 70 | "from": "input", 71 | "out": "text", 72 | "to": "toolWorker-09264f9f", 73 | "in": "context" 74 | }, 75 | { 76 | "from": "toolWorker-09264f9f", 77 | "to": "output", 78 | "out": "text", 79 | "in": "text" 80 | } 81 | ] 82 | } -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/README.md: -------------------------------------------------------------------------------- 1 | # Icons 2 | 3 | These icons are from [Material Design Icons](https://fonts.google.com/icons), and are licensed under [Apache 2.0](https://github.com/google/material-design-icons/blob/master/LICENSE). 4 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/add-blue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/add-circle.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/add-note.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/add-photo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/add.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/arrow-back-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/arrow-back.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/assets/application-pdf.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/assets/generic.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/assets/image-png.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/before.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/collapse.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/copy-to-clipboard.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/delete.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/download.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/edit.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/error.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/expand.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/history.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/info.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/preview.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/quick-jump.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/refresh.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/reset-alt.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/reset-image.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/reset.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/resume-blue.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/roles/historian.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/roles/team-lead.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/save.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/search.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/send-blue.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/settings.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/start.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /seeds/team-experiments/public/third_party/icons/warning.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/boards/blank.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { board } from "@google-labs/breadboard"; 8 | 9 | export default await board(({ text }) => { 10 | return { text }; 11 | }).serialize({ 12 | title: "Blank board", 13 | description: "A blank board. Use it to start a new board", 14 | version: "0.0.1", 15 | }); 16 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/boards/collector-loop.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { board } from "@google-labs/breadboard"; 8 | import worker from "./collector"; 9 | import { agents } from "@google-labs/agent-kit"; 10 | 11 | export default await board(() => { 12 | const repeater = agents.repeater({ 13 | $metadata: { title: "Media Collector Loop" }, 14 | worker, 15 | }); 16 | return { context: repeater.context }; 17 | }).serialize({ 18 | title: "Media Collection Loop", 19 | description: "Collect all the media", 20 | version: "0.0.1", 21 | }); 22 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/boards/subgraph-example-map.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { board, code } from "@google-labs/breadboard"; 8 | import { core } from "@google-labs/core-kit"; 9 | 10 | const hello = code(({ text }) => { 11 | return { hello: `HELLO, ${text}` }; 12 | }); 13 | 14 | const main = await board(({ names }) => { 15 | names 16 | .isArray() 17 | .title("Names of people to greet") 18 | .examples(JSON.stringify(["Paul", "Joe", "Al", "Kevin", "Croissant"])); 19 | 20 | const greeter = core.map({ 21 | $metadata: { title: "Greeter" }, 22 | board: "#mySubgraph", 23 | list: names, 24 | }); 25 | 26 | return { hello: greeter.list }; 27 | }).serialize({ 28 | title: "Subgraph Example with Map", 29 | description: "An example of using subgraphs within a board using `core.map`.", 30 | version: "0.0.1", 31 | }); 32 | 33 | main.graphs = { 34 | mySubgraph: await board(({ item }) => { 35 | const helloMaker = hello({ 36 | $metadata: { title: "Hello Maker" }, 37 | text: item, 38 | }); 39 | return { item: helloMaker.hello }; 40 | }).serialize(), 41 | }; 42 | 43 | export default main; 44 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/boards/subgraph-example.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { board, code } from "@google-labs/breadboard"; 8 | import { core } from "@google-labs/core-kit"; 9 | 10 | const hello = code(({ text }) => { 11 | return { hello: `HELLO, ${text}` }; 12 | }); 13 | 14 | const main = await board(({ text }) => { 15 | const subgraphInvoker = core.invoke({ 16 | $metadata: { title: "Subgraph Invoker" }, 17 | $board: "#mySubgraph", 18 | text, 19 | }); 20 | return { hello: subgraphInvoker.hello }; 21 | }).serialize({ 22 | title: "Subgraph Example", 23 | description: "An example of using subgraphs within a board", 24 | version: "0.0.1", 25 | }); 26 | 27 | main.graphs = { 28 | mySubgraph: await board(({ text }) => { 29 | const helloMaker = hello({ 30 | $metadata: { title: "Hello Maker" }, 31 | text, 32 | }); 33 | return { hello: helloMaker.hello }; 34 | }).serialize(), 35 | }; 36 | 37 | export default main; 38 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/breadboard/README.md: -------------------------------------------------------------------------------- 1 | These files are all candidates for moving back into Breadboard or becoming 2 | their own package that makes running boards in apps easier. 3 | 4 | This is why they are separated out. 5 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/breadboard/events.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { 8 | ErrorResponse, 9 | GraphEndProbeData, 10 | GraphStartProbeData, 11 | InputResponse, 12 | NodeStartProbeMessage, 13 | OutputResponse, 14 | SkipProbeMessage, 15 | } from "@google-labs/breadboard"; 16 | import { RunInputEvent, RunOutputEvent, RunSecretEvent } from "./types.js"; 17 | import { SecretResult } from "@google-labs/breadboard/harness"; 18 | import { End, InputResolveRequest } from "@google-labs/breadboard/remote"; 19 | 20 | const opts = { 21 | composed: true, 22 | bubbles: false, 23 | cancelable: true, 24 | }; 25 | 26 | export class PendingEvent extends Event { 27 | static readonly eventName = "pending"; 28 | 29 | constructor(public data: { timestamp: number }) { 30 | super(PendingEvent.eventName, { ...opts }); 31 | } 32 | } 33 | 34 | export class InputEvent extends Event implements RunInputEvent { 35 | static readonly eventName = "input"; 36 | 37 | constructor( 38 | public data: InputResponse, 39 | public reply: (data: InputResolveRequest) => Promise 40 | ) { 41 | super(InputEvent.eventName, { ...opts }); 42 | } 43 | } 44 | 45 | export class OutputEvent extends Event implements RunOutputEvent { 46 | static readonly eventName = "output"; 47 | 48 | constructor(public data: OutputResponse) { 49 | super(OutputEvent.eventName, { ...opts }); 50 | } 51 | } 52 | 53 | export class SecretEvent extends Event implements RunSecretEvent { 54 | static readonly eventName = "secret"; 55 | 56 | constructor( 57 | public data: SecretResult["data"], 58 | public reply: (data: InputResolveRequest) => Promise 59 | ) { 60 | super(SecretEvent.eventName, { ...opts }); 61 | } 62 | } 63 | 64 | export class RunnerErrorEvent extends Event { 65 | static readonly eventName = "error"; 66 | 67 | constructor(public data: ErrorResponse) { 68 | super(RunnerErrorEvent.eventName, { ...opts }); 69 | } 70 | } 71 | 72 | export class EndEvent extends Event { 73 | static readonly eventName = "end"; 74 | 75 | constructor(public data: End) { 76 | super(EndEvent.eventName, { ...opts }); 77 | } 78 | } 79 | 80 | export class SkipEvent extends Event { 81 | static readonly eventName = "skip"; 82 | 83 | constructor(public data: SkipProbeMessage["data"]) { 84 | super(SkipEvent.eventName, { ...opts }); 85 | } 86 | } 87 | 88 | export class GraphStartEvent extends Event { 89 | static readonly eventName = "graphstart"; 90 | 91 | constructor(public data: GraphStartProbeData) { 92 | super(GraphStartEvent.eventName, { ...opts }); 93 | } 94 | } 95 | 96 | export class GraphEndEvent extends Event { 97 | static readonly eventName = "graphend"; 98 | 99 | constructor(public data: GraphEndProbeData) { 100 | super(GraphEndEvent.eventName, { ...opts }); 101 | } 102 | } 103 | 104 | export class NodeStartEvent extends Event { 105 | static readonly eventName = "nodestart"; 106 | 107 | constructor(public data: NodeStartProbeMessage["data"]) { 108 | super(NodeStartEvent.eventName, { ...opts }); 109 | } 110 | } 111 | 112 | export class NodeEndEvent extends Event { 113 | static readonly eventName = "nodeend"; 114 | 115 | constructor(public data: NodeStartProbeMessage["data"]) { 116 | super(NodeEndEvent.eventName, { ...opts }); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/breadboard/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | export { Runner } from "./runner.js"; 8 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/breadboard/runner.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { InputValues } from "@google-labs/breadboard"; 8 | import { RunConfig, run } from "@google-labs/breadboard/harness"; 9 | import { InputResolveRequest } from "@google-labs/breadboard/remote"; 10 | import { 11 | EndEvent, 12 | GraphEndEvent, 13 | GraphStartEvent, 14 | InputEvent, 15 | NodeEndEvent, 16 | NodeStartEvent, 17 | OutputEvent, 18 | PendingEvent, 19 | RunnerErrorEvent, 20 | SecretEvent, 21 | SkipEvent, 22 | } from "./events.js"; 23 | import { RunEventTarget } from "./types.js"; 24 | 25 | // TODO: Decide if this interaction model is better. 26 | export class Runner extends (EventTarget as RunEventTarget) implements Runner { 27 | #run: ReturnType | null = null; 28 | #pendingInput: ((data: InputResolveRequest) => Promise) | null = null; 29 | 30 | start(config: RunConfig) { 31 | this.#run = run(config); 32 | this.#pendingInput = null; 33 | this.resume(); 34 | } 35 | 36 | waitingForInputs() { 37 | return !!this.#pendingInput; 38 | } 39 | 40 | provideInputs(inputs: InputValues) { 41 | if (!this.#pendingInput) { 42 | return false; 43 | } 44 | this.#pendingInput({ inputs }); 45 | this.#pendingInput = null; 46 | this.dispatchEvent(new PendingEvent({ timestamp: 0 })); 47 | this.resume(); 48 | } 49 | 50 | async resume(): Promise { 51 | if (!this.#run) return false; 52 | if (this.waitingForInputs()) return true; 53 | 54 | for (;;) { 55 | const result = await this.#run.next(); 56 | if (result.done) { 57 | this.#run = null; 58 | return false; 59 | } 60 | const { type, data, reply } = result.value; 61 | switch (type) { 62 | case "input": { 63 | if (!this.dispatchEvent(new InputEvent(data, reply))) { 64 | break; 65 | } else { 66 | this.#pendingInput = reply; 67 | } 68 | return true; 69 | } 70 | case "error": { 71 | this.dispatchEvent(new RunnerErrorEvent(data)); 72 | break; 73 | } 74 | case "end": { 75 | this.dispatchEvent(new EndEvent(data)); 76 | break; 77 | } 78 | case "skip": { 79 | this.dispatchEvent(new SkipEvent(data)); 80 | break; 81 | } 82 | case "graphstart": { 83 | this.dispatchEvent(new GraphStartEvent(data)); 84 | break; 85 | } 86 | case "graphend": { 87 | this.dispatchEvent(new GraphEndEvent(data)); 88 | break; 89 | } 90 | case "nodestart": { 91 | this.dispatchEvent(new NodeStartEvent(data)); 92 | break; 93 | } 94 | case "nodeend": { 95 | this.dispatchEvent(new NodeEndEvent(data)); 96 | break; 97 | } 98 | case "output": { 99 | this.dispatchEvent(new OutputEvent(data)); 100 | break; 101 | } 102 | case "secret": { 103 | this.dispatchEvent(new SecretEvent(data, reply)); 104 | break; 105 | } 106 | } 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/breadboard/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { 8 | ErrorResponse, 9 | GraphEndProbeData, 10 | GraphStartProbeData, 11 | InputResponse, 12 | NodeEndProbeMessage, 13 | NodeStartProbeMessage, 14 | OutputResponse, 15 | SkipProbeMessage, 16 | } from "@google-labs/breadboard"; 17 | import { SecretResult } from "@google-labs/breadboard/harness"; 18 | import { End, InputResolveRequest } from "@google-labs/breadboard/remote"; 19 | 20 | type RunEventMap = { 21 | input: RunInputEvent; 22 | output: RunOutputEvent; 23 | secret: RunSecretEvent; 24 | pending: RunPendingEvent; 25 | error: RunErrorEvent; 26 | end: RunEndEvent; 27 | skip: RunSkipEvent; 28 | graphstart: RunGraphStartEvent; 29 | graphend: RunGraphEndEvent; 30 | nodestart: RunNodeStartEvent; 31 | nodeend: RunNodeEndEvent; 32 | }; 33 | 34 | export type RunPendingEvent = Event & { 35 | data: { timestamp: number }; 36 | }; 37 | 38 | export type RunInputEvent = Event & { 39 | data: InputResponse; 40 | reply: (data: InputResolveRequest) => Promise; 41 | }; 42 | 43 | export type RunOutputEvent = Event & { 44 | data: OutputResponse; 45 | }; 46 | 47 | export type RunSecretEvent = Event & { 48 | data: SecretResult["data"]; 49 | reply: (data: InputResolveRequest) => Promise; 50 | }; 51 | 52 | export type RunErrorEvent = Event & { 53 | data: ErrorResponse; 54 | }; 55 | 56 | export type RunEndEvent = Event & { 57 | data: End; 58 | }; 59 | 60 | export type RunSkipEvent = Event & { 61 | data: SkipProbeMessage; 62 | }; 63 | 64 | export type RunGraphStartEvent = Event & { 65 | data: GraphStartProbeData; 66 | }; 67 | 68 | export type RunGraphEndEvent = Event & { 69 | data: GraphEndProbeData; 70 | }; 71 | 72 | export type RunNodeStartEvent = Event & { 73 | data: NodeStartProbeMessage["data"]; 74 | }; 75 | 76 | export type RunNodeEndEvent = Event & { 77 | data: NodeEndProbeMessage["data"]; 78 | }; 79 | 80 | export type TypedEventTarget = { 81 | new (): IntermediateEventTarget; 82 | }; 83 | 84 | // TODO: This needs to be a more global helper. 85 | interface IntermediateEventTarget extends EventTarget { 86 | addEventListener( 87 | type: K, 88 | callback: ( 89 | event: EventMap[K] extends Event ? EventMap[K] : never 90 | ) => EventMap[K] extends Event ? void : never, 91 | options?: boolean | AddEventListenerOptions 92 | ): void; 93 | 94 | addEventListener( 95 | type: string, 96 | callback: EventListenerOrEventListenerObject | null, 97 | options?: EventListenerOptions | boolean 98 | ): void; 99 | } 100 | 101 | export type RunEventTarget = TypedEventTarget; 102 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/constants/constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | export const SECOND = 1_000; 8 | export const MINUTE = SECOND * 60; 9 | export const HOUR = MINUTE * 60; 10 | export const DAY = HOUR * 24; 11 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/events/events.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import type { ConversationInputPart, State } from "../types/types.js"; 8 | 9 | const opts = { 10 | composed: true, 11 | bubbles: true, 12 | cancelable: true, 13 | }; 14 | 15 | export class StateChangeEvent extends Event { 16 | static readonly eventName = "statechange"; 17 | 18 | constructor(public state: State) { 19 | super(StateChangeEvent.eventName, { ...opts }); 20 | } 21 | } 22 | 23 | export class ConversationItemCreateEvent extends Event { 24 | static readonly eventName = "conversationitemcreate"; 25 | 26 | constructor(public message: ConversationInputPart | ConversationInputPart[]) { 27 | super(ConversationItemCreateEvent.eventName, { ...opts }); 28 | } 29 | } 30 | 31 | export class TeamSelectEvent extends Event { 32 | static readonly eventName = "teamselect"; 33 | 34 | constructor(public id: string) { 35 | super(TeamSelectEvent.eventName, { ...opts }); 36 | } 37 | } 38 | 39 | export class TeamSectionSelectEvent extends Event { 40 | static readonly eventName = "teamsectionselect"; 41 | 42 | constructor(public id: number) { 43 | super(TeamSectionSelectEvent.eventName, { ...opts }); 44 | } 45 | } 46 | 47 | export class MultiPartInputEvent extends Event { 48 | static readonly eventName = "multipartinput"; 49 | 50 | constructor(public parts: ConversationInputPart[]) { 51 | super(MultiPartInputEvent.eventName, { ...opts }); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/mock/activity.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { MINUTE } from "../constants/constants.js"; 8 | import { ActivityItem, ItemFormat, Participant } from "../types/types.js"; 9 | 10 | export const activityItems: ActivityItem[] = [ 11 | { 12 | datetime: new Date(Date.now() - MINUTE * 25), 13 | who: Participant.TEAM_MEMBER, 14 | role: "Media Coordinator", 15 | headline: "Defining Campaign", 16 | active: false, 17 | subItems: [ 18 | { 19 | datetime: new Date(Date.now() - MINUTE * 25), 20 | who: Participant.TEAM_MEMBER, 21 | headline: "Considering Brief", 22 | active: false, 23 | }, 24 | { 25 | datetime: new Date(Date.now() - MINUTE * 24), 26 | who: Participant.TEAM_MEMBER, 27 | headline: "Critiquing Brief", 28 | active: false, 29 | }, 30 | { 31 | datetime: new Date(Date.now() - MINUTE * 23), 32 | who: Participant.TEAM_MEMBER, 33 | headline: "Formatting information", 34 | active: false, 35 | }, 36 | ], 37 | }, 38 | { 39 | datetime: new Date(Date.now() - MINUTE * 24), 40 | who: Participant.TEAM_MEMBER, 41 | headline: "Updated job description", 42 | format: ItemFormat.MARKDOWN, 43 | content: [ 44 | `Create an Instagram campaign to promote soccer club Fremont FC.`, 45 | ` * Use brand assets to create campaign schedule`, 46 | ` * Generate images for the campaign`, 47 | ` * Write campaign messages`, 48 | ` * Critique ad campaigns`, 49 | ` * Ask you for campaign preferences`, 50 | ` * Generate posts for each scheduled game`, 51 | ], 52 | active: false, 53 | }, 54 | { 55 | datetime: new Date(Date.now() - MINUTE * 20), 56 | who: Participant.TEAM_MEMBER, 57 | role: "Historian", 58 | headline: "Check past work items", 59 | active: false, 60 | }, 61 | { 62 | datetime: new Date(Date.now() - MINUTE * 18), 63 | who: Participant.TEAM_MEMBER, 64 | headline: "Summarized past work", 65 | format: ItemFormat.MARKDOWN, 66 | active: false, 67 | subItems: [ 68 | { 69 | datetime: new Date(Date.now() - MINUTE * 25), 70 | who: Participant.TEAM_MEMBER, 71 | headline: "Considering Past Workd", 72 | active: false, 73 | }, 74 | { 75 | datetime: new Date(Date.now() - MINUTE * 24), 76 | who: Participant.TEAM_MEMBER, 77 | headline: "Critiquing Past Work", 78 | active: false, 79 | }, 80 | { 81 | datetime: new Date(Date.now() - MINUTE * 23), 82 | who: Participant.TEAM_MEMBER, 83 | headline: "Formatting Past Work", 84 | active: false, 85 | }, 86 | ], 87 | }, 88 | { 89 | datetime: new Date(Date.now() - MINUTE * 16), 90 | who: Participant.TEAM_MEMBER, 91 | role: "Team Lead", 92 | headline: "Checked assets", 93 | active: false, 94 | }, 95 | ]; 96 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/mock/assets.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { MINUTE } from "../constants/constants.js"; 8 | import { 9 | AssetItem, 10 | ConversationItem, 11 | ItemFormat, 12 | ItemType, 13 | Participant, 14 | } from "../types/types.js"; 15 | 16 | export const jobDescription: ConversationItem = { 17 | datetime: new Date(Date.now() - MINUTE * 2), 18 | who: Participant.TEAM_MEMBER, 19 | role: "Team Lead", 20 | type: ItemType.DATA, 21 | format: ItemFormat.MARKDOWN, 22 | message: [ 23 | `# Job Description`, 24 | `Create an Instagram campaign to promote soccer club Fremont FC.`, 25 | ` * Use brand assets to create campaign schedule`, 26 | ` * Generate images for the campaign`, 27 | ` * Write campaign messages`, 28 | ` * Critique ad campaigns`, 29 | ` * Ask you for campaign preferences`, 30 | ` * Generate posts for each scheduled game`, 31 | ], 32 | }; 33 | 34 | export const assetItems: AssetItem[] = [ 35 | { 36 | datetime: new Date(Date.now() - MINUTE * 10), 37 | who: Participant.USER, 38 | name: "FremontFC-Logo.png", 39 | mime_type: "image/png", 40 | url: "#", 41 | }, 42 | { 43 | datetime: new Date(Date.now() - MINUTE * 4), 44 | who: Participant.USER, 45 | name: "2024 FFC Schedule.pdf", 46 | mime_type: "application/pdf", 47 | url: "#", 48 | }, 49 | { 50 | datetime: new Date(Date.now() - MINUTE * 2), 51 | who: Participant.USER, 52 | name: "2024 Campaign Playbook (March 11, 2024)", 53 | mime_type: "application/pdf", 54 | url: "#", 55 | }, 56 | ]; 57 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/mock/conversation.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { MINUTE } from "../constants/constants.js"; 8 | import { 9 | ConversationItem, 10 | ItemFormat, 11 | ItemType, 12 | Participant, 13 | } from "../types/types.js"; 14 | 15 | export const conversationItems: ConversationItem[] = [ 16 | { 17 | datetime: new Date(Date.now() - MINUTE * 5), 18 | who: Participant.TEAM_MEMBER, 19 | role: "Team Lead", 20 | type: ItemType.TEXT_CONVERSATION, 21 | format: ItemFormat.TEXT, 22 | message: [ 23 | `I'm here to help you find an AI team that meets your needs.`, 24 | `Describe the task you need to complete`, 25 | ], 26 | }, 27 | { 28 | datetime: new Date(Date.now() - MINUTE * 4), 29 | who: Participant.USER, 30 | type: ItemType.TEXT_CONVERSATION, 31 | format: ItemFormat.TEXT, 32 | message: 33 | "I want to create an Instagram campaign to promote my soccer club called Fremont FC", 34 | }, 35 | { 36 | datetime: new Date(Date.now() - MINUTE * 3), 37 | who: Participant.TEAM_MEMBER, 38 | role: "Team Lead", 39 | type: ItemType.TEXT_CONVERSATION, 40 | format: ItemFormat.TEXT, 41 | message: 42 | "Here's the job description I have from your previous conversation", 43 | }, 44 | { 45 | datetime: new Date(Date.now() - MINUTE * 3), 46 | who: Participant.TEAM_MEMBER, 47 | role: "Team Lead", 48 | type: ItemType.DATA, 49 | format: ItemFormat.MARKDOWN, 50 | message: [ 51 | `# Job Description`, 52 | `Create an Instagram campaign to promote soccer club Fremont FC.`, 53 | ` * Generate images for the campaign`, 54 | ` * Write campaign messages`, 55 | ` * Critique ad campaigns`, 56 | ` * Ask you for campaign preferences`, 57 | ` * Generate posts for each scheduled game`, 58 | ], 59 | }, 60 | { 61 | datetime: new Date(Date.now() - MINUTE * 2.5), 62 | who: Participant.USER, 63 | type: ItemType.TEXT_CONVERSATION, 64 | format: ItemFormat.TEXT, 65 | message: 66 | "Yeah, but I want to use my team's logo and player photos to create multimedia posts promoting each new game", 67 | }, 68 | { 69 | datetime: new Date(Date.now() - MINUTE * 2.3), 70 | who: Participant.TEAM_MEMBER, 71 | role: "Team Lead", 72 | type: ItemType.TEXT_CONVERSATION, 73 | format: ItemFormat.TEXT, 74 | message: "Sure, I've updated the job description", 75 | }, 76 | { 77 | datetime: new Date(Date.now() - MINUTE * 2), 78 | who: Participant.TEAM_MEMBER, 79 | role: "Team Lead", 80 | type: ItemType.DATA, 81 | format: ItemFormat.MARKDOWN, 82 | message: [ 83 | `# Job Description`, 84 | `Create an Instagram campaign to promote soccer club Fremont FC.`, 85 | ` * Use brand assets to create campaign schedule`, 86 | ` * Generate images for the campaign`, 87 | ` * Write campaign messages`, 88 | ` * Critique ad campaigns`, 89 | ` * Ask you for campaign preferences`, 90 | ` * Generate posts for each scheduled game`, 91 | ], 92 | }, 93 | ]; 94 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/mock/team-list.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { MINUTE } from "../constants/constants.js"; 8 | import { ItemStatus, Participant, TeamListItem } from "../types/types.js"; 9 | 10 | export const teamListItems: Map = new Map([ 11 | [ 12 | "team-1", 13 | { 14 | datetime: new Date(Date.now() - 20 * MINUTE), 15 | teamName: "Onboarding to Social Campaign", 16 | description: "Collect information to post to social media", 17 | status: ItemStatus.ACTIVE, 18 | statusDescription: "Not started", 19 | who: Participant.TEAM_MEMBER, 20 | role: "Media Coordinator", 21 | graph: "/bgl/insta/onboard-for-social.json", 22 | }, 23 | ], 24 | [ 25 | "team-4", 26 | { 27 | datetime: new Date(Date.now() - 20 * MINUTE), 28 | teamName: "Social Campaign", 29 | description: "Uses simple chat (just makes up stuff)", 30 | status: ItemStatus.ACTIVE, 31 | statusDescription: "Brand input needed", 32 | who: Participant.TEAM_MEMBER, 33 | role: "Media Coordinator", 34 | graph: "/bgl/insta/simple-chat.bgl.json", 35 | }, 36 | ], 37 | [ 38 | "team-2", 39 | { 40 | datetime: new Date(Date.now() - 20 * MINUTE), 41 | teamName: "Multimedia Campaign Manager Team", 42 | description: 43 | "Uses 'get page' tool: ask it about various URLs and it will scrape them and summarize them", 44 | status: ItemStatus.COMPLETE, 45 | who: Participant.TEAM_MEMBER, 46 | role: "Media Coordinator", 47 | graph: "/bgl/insta/chat-with-tools.bgl.json", 48 | }, 49 | ], 50 | [ 51 | "team-3", 52 | { 53 | datetime: new Date(Date.now() - 45 * MINUTE), 54 | teamName: "Customer Service Curator Team", 55 | description: 56 | "It's a super long title that needs to be truncated because it's so long", 57 | status: ItemStatus.INERT, 58 | who: Participant.USER, 59 | }, 60 | ], 61 | ]); 62 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/router/router.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { StateChangeEvent } from "../events/events"; 8 | import { SECTION, State } from "../types/types.js"; 9 | 10 | export class Router extends EventTarget { 11 | static #instance: Router; 12 | static instance() { 13 | if (!this.#instance) { 14 | this.#instance = new Router(); 15 | } 16 | 17 | return this.#instance; 18 | } 19 | 20 | // Do not instantiate directly. 21 | private constructor() { 22 | super(); 23 | 24 | this.#parseURLForState(); 25 | 26 | window.addEventListener("popstate", () => { 27 | this.#parseURLForState(); 28 | }); 29 | } 30 | 31 | #state: State = { 32 | teamId: null, 33 | teamSection: 0, 34 | section: SECTION.TEAM_LIST, 35 | }; 36 | 37 | #parseURLForState() { 38 | const params = new URLSearchParams(window.location.search); 39 | 40 | this.#state.teamId = params.has("teamId") ? params.get("teamId") : null; 41 | this.#state.teamSection = params.has("teamSection") 42 | ? Number.parseInt(params.get("teamSection") as string, 10) 43 | : null; 44 | this.#state.section = params.has("section") 45 | ? (params.get("section") as SECTION) 46 | : null; 47 | 48 | this.emitState(); 49 | } 50 | 51 | emitState() { 52 | this.dispatchEvent(new StateChangeEvent(this.#state)); 53 | } 54 | 55 | set(state: Partial) { 56 | const unifiedState = { ...this.#state, ...state }; 57 | 58 | const params = new URLSearchParams(window.location.search); 59 | for (const [name, value] of Object.entries(unifiedState)) { 60 | if (value === null) { 61 | params.delete(name); 62 | continue; 63 | } 64 | 65 | const serializedValue = value.toString(); 66 | if (serializedValue === "") { 67 | continue; 68 | } 69 | 70 | params.set(name, value.toString()); 71 | } 72 | 73 | const currentSearch = window.location.search.replace(/^\?/, ""); 74 | if (params.toString() !== currentSearch) { 75 | const url = new URL(window.location.href); 76 | url.search = params.toString(); 77 | window.history.pushState(null, "", url); 78 | } 79 | 80 | this.#parseURLForState(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/server/api.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { IncomingMessage, ServerResponse } from "http"; 8 | import { serverError } from "./errors"; 9 | import { getPageContent } from "./browse"; 10 | import { root } from "./common"; 11 | import { resolve } from "path"; 12 | import { readdir } from "fs/promises"; 13 | import { VercelRequest, VercelResponse } from "@vercel/node"; 14 | 15 | type Handler = ( 16 | url: URL, 17 | req: IncomingMessage, 18 | res: ServerResponse 19 | ) => Promise; 20 | 21 | export const fromVercelFunction = (funcImport: unknown): Handler => { 22 | type VercelFunction = { 23 | GET: (request: Request) => Promise; 24 | default: ( 25 | request: VercelRequest, 26 | response: VercelResponse 27 | ) => VercelResponse; 28 | headers: Record; 29 | }; 30 | const fun = funcImport as VercelFunction; 31 | return async ( 32 | url: URL, 33 | req: IncomingMessage, 34 | res: ServerResponse 35 | ): Promise => { 36 | const request = new Request(url); 37 | if (fun.GET) { 38 | const response = await fun.GET(request); 39 | res.writeHead( 40 | response.status, 41 | Object.fromEntries(response.headers.entries()) 42 | ); 43 | res.end(await response.text()); 44 | } else { 45 | await fun.default( 46 | req as unknown as VercelRequest, 47 | res as unknown as VercelResponse 48 | ); 49 | } 50 | return true; 51 | }; 52 | }; 53 | 54 | export const getAPIs = async () => { 55 | const path = resolve(root(), "api"); 56 | const names = await readdir(path); 57 | const apis = new Map(); 58 | for (const name of names) { 59 | const funcImport = await import(resolve(path, name)); 60 | const apiPath = name.slice(0, -3); 61 | apis.set(apiPath, fromVercelFunction(funcImport)); 62 | } 63 | return apis; 64 | }; 65 | 66 | export const api = async ( 67 | url: URL, 68 | req: IncomingMessage, 69 | res: ServerResponse, 70 | endpointPath: string, 71 | handler: Handler 72 | ) => { 73 | if (url.pathname === endpointPath) return handler(url, req, res); 74 | return false; 75 | }; 76 | 77 | export const browseApi = async (url: URL, res: ServerResponse) => { 78 | const urlParam = url.searchParams.get("url"); 79 | if (!urlParam) { 80 | serverError(res, `URL parameter not supplied`); 81 | return false; 82 | } 83 | const urlToBrowse = URL.canParse(urlParam) ? new URL(urlParam) : null; 84 | if (!urlToBrowse) { 85 | serverError(res, `Invalid URL parameter: ${urlParam}`); 86 | return false; 87 | } 88 | 89 | if (urlToBrowse.protocol !== "https:") { 90 | serverError(res, `The URL protocol must be https.`); 91 | return false; 92 | } 93 | const content = await getPageContent(urlParam); 94 | res.writeHead(200, { "Content-Type": "application/json" }); 95 | const response = { url: urlParam, content }; 96 | res.end(JSON.stringify(response)); 97 | return true; 98 | }; 99 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/server/browse.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import puppeteer from "puppeteer"; 8 | 9 | export const getPageContent = async (url: string) => { 10 | const browser = await puppeteer.launch(); 11 | const page = await browser.newPage(); 12 | try { 13 | await page.goto(url); 14 | await page.setViewport({ width: 1080, height: 1024 }); 15 | // TODO: Do something more elaborate. 16 | const content = await page.evaluate(() => { 17 | return document.body.innerText; 18 | }); 19 | 20 | return content; 21 | } catch (e) { 22 | return `Unable to retrieve the page: ${(e as Error).message}`; 23 | } finally { 24 | await browser.close(); 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/server/common.ts: -------------------------------------------------------------------------------- 1 | import { dirname, resolve } from "path"; 2 | import { fileURLToPath } from "url"; 3 | 4 | const MODULE_PATH = dirname(fileURLToPath(import.meta.url)); 5 | const ROOT_PATH = resolve(MODULE_PATH, "../../"); 6 | 7 | export const root = () => { 8 | return ROOT_PATH; 9 | }; 10 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/server/errors.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { ServerResponse } from "http"; 8 | 9 | export const serverError = (res: ServerResponse, error: string) => { 10 | res.writeHead(500, "Server Error"); 11 | res.end(error); 12 | }; 13 | 14 | export const notFound = (res: ServerResponse, error: string) => { 15 | res.writeHead(404, "Page not found"); 16 | res.end(error); 17 | }; 18 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/server/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { IncomingMessage, ServerResponse, createServer } from "http"; 8 | import { createServer as createViteServer } from "vite"; 9 | import { serveIndex } from "./static.js"; 10 | import { serverError } from "./errors.js"; 11 | import { getAPIs } from "./api.js"; 12 | 13 | const PORT = 3000; 14 | const HOST = "localhost"; 15 | const HOSTNAME = `http://${HOST}:${PORT}`; 16 | 17 | const vite = await createViteServer({ 18 | server: { middlewareMode: true }, 19 | appType: "custom", 20 | optimizeDeps: { esbuildOptions: { target: "esnext" } }, 21 | }); 22 | 23 | const apis = await getAPIs(); 24 | 25 | const serveApi = async ( 26 | req: IncomingMessage, 27 | res: ServerResponse, 28 | next: () => void 29 | ) => { 30 | const url = req.url; 31 | if (!url) { 32 | return; 33 | } 34 | const resolvedURL = URL.canParse(url, HOSTNAME) 35 | ? new URL(url, HOSTNAME) 36 | : null; 37 | if (!resolvedURL) { 38 | serverError(res, `Invalid URL: ${url}`); 39 | return; 40 | } 41 | 42 | const pathname = resolvedURL.pathname; 43 | if (pathname.startsWith("/api/")) { 44 | const api = apis.get(pathname.slice(5)); 45 | if (api) { 46 | try { 47 | if (await api(resolvedURL, req, res)) return true; 48 | } catch (e) { 49 | console.error("API ERROR", pathname, e); 50 | } 51 | } 52 | } 53 | 54 | next(); 55 | }; 56 | 57 | const server = createServer(async (req, res) => { 58 | serveApi(req, res, async () => { 59 | vite.middlewares(req, res, async () => { 60 | serveIndex(req, res, async (contents: string) => { 61 | return await vite.transformIndexHtml("/index.html", contents); 62 | }); 63 | }); 64 | }); 65 | }); 66 | 67 | server.listen(PORT, HOST, () => { 68 | console.info(`Running on "http://${HOST}:${PORT}"...`); 69 | }); 70 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/server/static.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { readFile } from "fs/promises"; 8 | import { extname, resolve } from "path"; 9 | import { IncomingMessage, ServerResponse } from "http"; 10 | import { notFound } from "./errors.js"; 11 | import { root } from "./common.js"; 12 | 13 | const CONTENT_TYPE = new Map([ 14 | [".html", "text/html"], 15 | [".json", "application/json"], 16 | ]); 17 | const DEFAULT_CONTENT_TYPE = "text/plain"; 18 | 19 | /** 20 | * Serve a static file 21 | */ 22 | export const serveFile = async ( 23 | res: ServerResponse, 24 | path: string, 25 | transformer?: (contents: string) => Promise 26 | ) => { 27 | const contentType = CONTENT_TYPE.get(extname(path)) || DEFAULT_CONTENT_TYPE; 28 | try { 29 | const resolvedPath = resolve(root(), path); 30 | let contents = await readFile(resolvedPath, "utf-8"); 31 | if (transformer) contents = await transformer(contents); 32 | res.writeHead(200, { "Content-Type": contentType }); 33 | res.end(contents); 34 | } catch { 35 | notFound(res, "Static file not found"); 36 | } 37 | }; 38 | 39 | export const serveIndex = async ( 40 | req: IncomingMessage, 41 | res: ServerResponse, 42 | transformer: (contents: string) => Promise 43 | ) => { 44 | const url = req.url; 45 | if (!url) { 46 | // Don't know how to serve this, let's bail. 47 | return; 48 | } 49 | 50 | // We parse the URL here because we may have search params included in the 51 | // URL, and that prevents us from finding a match to `/`. With a parsed URL we 52 | // can just look at the pathname property and go from there. 53 | const fullUrl = new URL(url, `http://${req.headers.host}`); 54 | const { pathname } = fullUrl; 55 | if (pathname === "/" || pathname === "/index.html") { 56 | serveFile(res, "index.html", transformer); 57 | return; 58 | } 59 | 60 | notFound(res, "Page Not Found. Are you looking for '/index.html' maybe?"); 61 | }; 62 | 63 | export const serveDir = async ( 64 | req: IncomingMessage, 65 | res: ServerResponse, 66 | dir: string, 67 | path: string, 68 | next: () => Promise 69 | ) => { 70 | const url = req.url; 71 | if (!url) { 72 | return next(); 73 | } 74 | if (!url.startsWith(path)) { 75 | return next(); 76 | } 77 | 78 | const resolvedPath = url.slice(path.length + 1); 79 | 80 | const resolvedDir = resolve(root(), dir, resolvedPath); 81 | serveFile(res, resolvedDir); 82 | }; 83 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/types/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | export enum SECTION { 8 | TEAM_LIST = "team-list", 9 | TEAM_JOB = "team-job", 10 | } 11 | 12 | export interface State { 13 | teamId: string | null; 14 | teamSection: number | null; 15 | section: SECTION | null; 16 | } 17 | 18 | export enum Participant { 19 | USER = "user", 20 | TEAM_MEMBER = "team-member", 21 | } 22 | 23 | export enum ItemFormat { 24 | TEXT = "text", 25 | MARKDOWN = "markdown", 26 | MULTIPART = "multipart", 27 | ENUM = "enum", 28 | } 29 | 30 | export enum ItemType { 31 | TEXT_CONVERSATION = "text-conversation", 32 | DATA = "data", 33 | INPUT = "input", 34 | PENDING = "pending", 35 | MULTIPART = "multipart", 36 | } 37 | 38 | export enum ItemStatus { 39 | INERT = "inert", 40 | ACTIVE = "active", 41 | COMPLETE = "complete", 42 | } 43 | 44 | export type ConversationInputOption = string; 45 | 46 | export type ConversationInputPart = 47 | | string 48 | | { 49 | inline_data: { mime_type: string; data: string }; 50 | url: string; 51 | name: string; 52 | }; 53 | 54 | export interface ConversationPending { 55 | datetime: Date; 56 | type: ItemType.PENDING; 57 | who: Participant; 58 | role?: string; 59 | } 60 | 61 | export interface ConversationText { 62 | datetime: Date; 63 | type: ItemType.TEXT_CONVERSATION; 64 | who: Participant; 65 | role?: string; 66 | format: ItemFormat; 67 | message: string | string[]; 68 | } 69 | 70 | export interface ConversationData { 71 | datetime: Date; 72 | type: ItemType.DATA; 73 | who: Participant; 74 | role?: string; 75 | format: ItemFormat; 76 | message: string | string[]; 77 | } 78 | 79 | export interface ConversationMultipart { 80 | datetime: Date; 81 | type: ItemType.MULTIPART; 82 | who: Participant; 83 | format: ItemFormat; 84 | role?: string; 85 | parts: ConversationInputPart[]; 86 | } 87 | 88 | export interface ConversationMultipartInput { 89 | datetime: Date; 90 | type: ItemType.INPUT; 91 | who: Participant; 92 | format: ItemFormat.MULTIPART; 93 | role?: string; 94 | title: string; 95 | parts: ConversationInputPart[]; 96 | } 97 | 98 | export interface ConversationEnumeratedInput { 99 | datetime: Date; 100 | type: ItemType.INPUT; 101 | who: Participant; 102 | format: ItemFormat.ENUM; 103 | role?: string; 104 | title: string; 105 | options: ConversationInputOption[]; 106 | } 107 | 108 | export type ConversationItem = 109 | | ConversationText 110 | | ConversationData 111 | | ConversationPending 112 | | ConversationMultipart 113 | | ConversationMultipartInput 114 | | ConversationEnumeratedInput; 115 | 116 | export interface ActivityItem { 117 | datetime: Date; 118 | who: Participant; 119 | role?: string; 120 | headline: string; 121 | content?: string | string[]; 122 | subItems?: ActivityItem[]; 123 | active: boolean; 124 | format?: ItemFormat; 125 | } 126 | 127 | export interface AssetItem { 128 | datetime: Date; 129 | who: Participant; 130 | role?: string; 131 | name: string; 132 | mime_type: string; 133 | url: string; 134 | } 135 | 136 | export interface TeamListItem { 137 | datetime: Date; 138 | teamName: string; 139 | description?: string | string[]; 140 | format?: ItemFormat; 141 | status: ItemStatus; 142 | statusDescription?: string; 143 | who: Participant; 144 | role?: string; 145 | graph?: string; 146 | } 147 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/ui/directives/markdown.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2023 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { noChange } from "lit"; 8 | import { 9 | Directive, 10 | DirectiveParameters, 11 | Part, 12 | directive, 13 | } from "lit/directive.js"; 14 | import { unsafeHTML } from "lit/directives/unsafe-html.js"; 15 | import MarkdownIt from "markdown-it"; 16 | 17 | class MarkdownDirective extends Directive { 18 | #markdownIt = MarkdownIt(); 19 | #lastValue: string | null = null; 20 | 21 | update(_part: Part, [value]: DirectiveParameters) { 22 | if (this.#lastValue === value) { 23 | return noChange; 24 | } 25 | 26 | this.#lastValue = value; 27 | return this.render(value); 28 | } 29 | 30 | /** 31 | * Renders the markdown string to HTML using MarkdownIt. 32 | * 33 | * Note: MarkdownIt doesn't enable HTML in its output, so we render the 34 | * value directly without further sanitization. 35 | * @see https://github.com/markdown-it/markdown-it/blob/master/docs/security.md 36 | */ 37 | render(value: string) { 38 | const htmlString = this.#markdownIt.render(value); 39 | return unsafeHTML(htmlString); 40 | } 41 | } 42 | 43 | export const markdown = directive(MarkdownDirective); 44 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/ui/elements/elements.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | export { AssetsList } from "./assets-list/assets-list.js"; 8 | export { Conversation } from "./conversation/conversation.js"; 9 | export { MultiPartInput } from "./conversation/multi-part-input.js"; 10 | export { Switcher } from "./switcher/switcher.js"; 11 | export { TeamActivity } from "./team-activity/team-activity.js"; 12 | export { TeamJob } from "./team-job/team-job.js"; 13 | export { TeamList } from "./team-list/team-list.js"; 14 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/ui/elements/switcher/switcher.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { LitElement, html, css, nothing } from "lit"; 8 | import { customElement, property } from "lit/decorators.js"; 9 | 10 | @customElement("at-switcher") 11 | export class Switcher extends LitElement { 12 | @property({ 13 | hasChanged(value: unknown) { 14 | return typeof value === "number"; 15 | }, 16 | }) 17 | selected = 0; 18 | 19 | @property({ reflect: true, attribute: true }) 20 | disabled = false; 21 | 22 | @property({ reflect: true, type: Number }) 23 | slots = 2; 24 | 25 | static styles = css` 26 | :host { 27 | display: grid; 28 | grid-template-rows: var(--grid-size-12) auto; 29 | overflow: auto; 30 | position: relative; 31 | } 32 | 33 | #buttons { 34 | background: var(--output-50); 35 | display: flex; 36 | align-items: center; 37 | justify-content: space-around; 38 | height: 100%; 39 | border-bottom: 1px solid #d9d9d9; 40 | z-index: 1; 41 | } 42 | 43 | #buttons button { 44 | margin: 0 var(--grid-size-2); 45 | background: none; 46 | border: none; 47 | position: relative; 48 | height: var(--grid-size-8); 49 | font-size: var(--bb-font-medium); 50 | white-space: nowrap; 51 | color: var(--neutral-900); 52 | height: 100%; 53 | cursor: pointer; 54 | } 55 | 56 | #buttons button:not([disabled]):hover, 57 | #buttons button:not([disabled])[active] { 58 | color: var(--output-700); 59 | } 60 | 61 | #buttons button[active]::after { 62 | content: ""; 63 | border-radius: 10px 10px 0 0; 64 | background: var(--output-700); 65 | position: absolute; 66 | left: 0; 67 | height: 3px; 68 | bottom: 0; 69 | width: 100%; 70 | } 71 | 72 | slot { 73 | display: none; 74 | } 75 | 76 | slot[active] { 77 | display: block; 78 | width: 100%; 79 | height: 100%; 80 | overflow: auto; 81 | } 82 | `; 83 | 84 | render() { 85 | const renderableChildren = new Array(this.slots).fill(null); 86 | return html`
87 | ${renderableChildren.map((_, idx) => { 88 | if (!this.children[idx]) { 89 | console.warn(`No child found in index ${idx}`); 90 | return nothing; 91 | } 92 | 93 | return html``; 100 | })} 101 |
102 | ${renderableChildren.map((_, idx) => { 103 | return html``; 107 | })} 108 | `; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/ui/secrets.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | type ParsedSecrets = { 8 | parsed: Record; 9 | }; 10 | 11 | type SecretsPayload = 12 | | ParsedSecrets 13 | | { 14 | error: string; 15 | }; 16 | 17 | export const hasSecrets = (data: SecretsPayload): data is ParsedSecrets => { 18 | return "parsed" in data; 19 | }; 20 | 21 | export class SecretsManager { 22 | #error: string | null = null; 23 | #secrets: Record | null = null; 24 | 25 | async load(path: string) { 26 | const data = (await (await fetch(path)).json()) as SecretsPayload; 27 | if (hasSecrets(data)) { 28 | this.#secrets = data.parsed; 29 | return true; 30 | } else { 31 | this.#error = data.error; 32 | return false; 33 | } 34 | } 35 | 36 | get(key: string): string { 37 | if (this.#error) { 38 | throw new Error(this.#error); 39 | } 40 | if (!this.#secrets) { 41 | throw new Error("Secrets haven't yet been loaded"); 42 | } 43 | return this.#secrets[key]; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/ui/utils/asBase64.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | export function asBase64(file: File): Promise { 8 | return new Promise((resolve, reject) => { 9 | const reader = new FileReader(); 10 | reader.onload = () => { 11 | if (typeof reader.result !== "string") { 12 | reject("Reader result is not a string"); 13 | return; 14 | } 15 | 16 | const [, content] = reader.result.split(","); 17 | resolve(content); 18 | }; 19 | reader.onerror = (err) => reject(err); 20 | reader.readAsDataURL(file); 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/ui/utils/clamp.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | export function clamp( 8 | value: number, 9 | min = Number.NEGATIVE_INFINITY, 10 | max = Number.POSITIVE_INFINITY 11 | ) { 12 | return Math.max(min, Math.min(max, value)); 13 | } 14 | -------------------------------------------------------------------------------- /seeds/team-experiments/src/ui/utils/toRelativeTime.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2024 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | import { HOUR, MINUTE, SECOND } from "../../constants/constants"; 8 | 9 | const formatter = new Intl.RelativeTimeFormat("en", { 10 | style: "short", 11 | }); 12 | 13 | export function toRelativeTime(datetime: Date) { 14 | const now = new Date(Date.now()); 15 | const diffInMilliseconds = now.getTime() - datetime.getTime(); 16 | 17 | if (Math.abs(diffInMilliseconds) < MINUTE) { 18 | return formatter.format(-diffInMilliseconds / SECOND, "second"); 19 | } else if (Math.abs(diffInMilliseconds) < HOUR) { 20 | return formatter.format(-Math.floor(diffInMilliseconds / MINUTE), "minute"); 21 | } 22 | 23 | return formatter.format(-Math.floor(diffInMilliseconds / HOUR), "hour"); 24 | } 25 | -------------------------------------------------------------------------------- /seeds/team-experiments/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "declarationMap": true, 5 | "incremental": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "inlineSources": false, 9 | "allowJs": true, 10 | 11 | "target": "ES2020", 12 | "module": "ESNext", 13 | "lib": ["ES2022", "DOM", "DOM.Iterable"], 14 | "skipLibCheck": true, 15 | "experimentalDecorators": true, 16 | "useDefineForClassFields": false, 17 | "outDir": "build", 18 | 19 | /* Bundler mode */ 20 | "moduleResolution": "bundler", 21 | "resolveJsonModule": true, 22 | "isolatedModules": true, 23 | 24 | /* Linting */ 25 | "strict": true, 26 | "noUnusedLocals": true, 27 | "noUnusedParameters": true, 28 | "noFallthroughCasesInSwitch": true 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /seeds/team-experiments/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import vercel from "vite-plugin-vercel"; 3 | 4 | export default defineConfig({ 5 | plugins: [vercel()], 6 | optimizeDeps: { esbuildOptions: { target: "esnext" } }, 7 | build: { target: "esnext" }, 8 | }); 9 | -------------------------------------------------------------------------------- /templates/blank/.npmignore: -------------------------------------------------------------------------------- 1 | .env 2 | tsconfig.tsbuildinfo 3 | -------------------------------------------------------------------------------- /templates/blank/README.md: -------------------------------------------------------------------------------- 1 | # Your README goes here -------------------------------------------------------------------------------- /templates/blank/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@google-labs/{{name}}", 3 | "private": true, 4 | "version": "0.0.1", 5 | "description": "{{description}}", 6 | "main": "./dist/src/index.js", 7 | "exports": "./dist/src/index.js", 8 | "types": "dist/src/index.d.ts", 9 | "type": "module", 10 | "scripts": { 11 | "test": "FORCE_COLOR=1 ava", 12 | "build": "FORCE_COLOR=1 tsc --b", 13 | "watch": "FORCE_COLOR=1 tsc --b --watch", 14 | "lint": "FORCE_COLOR=1 eslint . --ext .ts" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/google/labs-prototypes" 19 | }, 20 | "files": [ 21 | "dist/src" 22 | ], 23 | "ava": { 24 | "timeout": "30s", 25 | "files": [ 26 | "tests/**/*.ts" 27 | ], 28 | "workerThreads": false, 29 | "typescript": { 30 | "rewritePaths": { 31 | "./": "dist/" 32 | }, 33 | "compile": false 34 | } 35 | }, 36 | "keywords": [], 37 | "author": "Google Labs Team", 38 | "license": "Apache-2.0", 39 | "bugs": { 40 | "url": "https://github.com/google/labs-prototypes/issues" 41 | }, 42 | "homepage": "https://github.com/google/labs-prototypes#readme", 43 | "devDependencies": { 44 | "@ava/typescript": "^4.0.0", 45 | "@typescript-eslint/eslint-plugin": "^5.56.0", 46 | "@typescript-eslint/parser": "^5.56.0", 47 | "@types/node": "^18.16.3", 48 | "ava": "^5.2.0", 49 | "typescript": "^5.0.4", 50 | "@google-labs/tsconfig": "*" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /templates/blank/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2023 Google LLC 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | console.log("code goes here"); 8 | -------------------------------------------------------------------------------- /templates/blank/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "outDir": "./dist" 5 | }, 6 | "include": ["src/**/*", "tests/**/*"], 7 | "extends": "@google-labs/tsconfig/base.json" 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./core/tsconfig/base.json", 3 | "files": [], 4 | "references": [ 5 | { "path": "seeds/chunker" }, 6 | { "path": "seeds/discovery-types" }, 7 | { "path": "seeds/gemini-guide" }, 8 | { "path": "seeds/palm-lite" } 9 | ] 10 | } 11 | --------------------------------------------------------------------------------