Note: this repo is under very active construction with a new separate Python server for LLM calls—details below are likely to change! Please create a GitHub Issue for anything you encounter.
Familiar with this repo? See the local dev quickstart
Talk to the City (T3C) is an open-source LLM-enabled interface for improving collective deliberation and decision-making by analyzing detailed, qualitative data. It aggregates responses and organizes similar claims into a nested tree of main topics and subtopics.
This repo will allow you to setup your own instance of T3C. The basic workflow is
- Submit a CSV file or Google Sheet with your survey data, either through the NextJS client in a browser, the Express API, or the Python FastAPI (coming soon)
- The backend app will use an LLM to parse your data.
- The backend app will upload a JSON file to a Google Cloud Storage Bucket that you provide.
- Your report can be viewed by going to
http://[NextJS client url]/report/[encoded url for your JSON file]
.
If you want to use Talk to the City without any setup, you can go to our website at TBD and follow the instructions on how to use T3C
- Clone this repo
- Set up dependencies: Google Cloud, Firebase, Redis
- Configure Pyserver and your environment via .env files
- Launch a local instance via
npm run dev
Clone the repo to your local computer:
git clone https://github.com/AIObjectives/tttc-light-js.git
or if you have git ssh
git clone git@github.com:AIObjectives/tttc-light-js.git
T3C currently only supports using Google Cloud for storing report data. First create a new storage bucket:
- Create a Google Cloud project and a Google Cloud Storage bucket
- When you get to the section "Choose how to control access to objects", uncheck "Enforce public access prevention"
- Make sure this bucket has public access so that anyone can read from it (to
make your reports accessible from your browser):
- Turn off "Prevent public access" protect.
- In the "Permissions" tab, click "Grant access." Add the principal
allUsers
and assign the roleStorage Object User
.
Then create a service account for this bucket:
- In the "IAM & Admin" view, select "Service Accounts" from the left menu, and then click "Create service account"
- Give this account the "Editor" role
- Create keys for this account and download them as a json file:
- Save this file as
./google-credentials.json
, it will be used in the next step.
Set up gcloud SDK on your machine
- install
gcloud
(see https://cloud.google.com/sdk/docs/install-sdk) gcloud auth login
gcloud config set project your-project-name
gcloud auth configure-docker
To use T3C, you'll need to create a Firebase project.
- Go to the Firebase Console and click "Create a project" or "Add project"
- Enter a project name
- Click "Create project"
- Once your project is created, you'll need to register your app. In the project overview:
- Click on web
- Register app with a nickname
- Copy the provided Firebase configuration object
- Optional: we suggest adding this object to
/express-server/configuration
. This folder is not tracked by git and will make the configuration easier to import later.
- TODO setup Auth and Firestore
For local development, you can install Redis by following these instructions. Make sure to start the Redis server on your computer if you want to run it locally. If you're working on a Mac, the steps are
brew install redis
redis-server
- Go to
/pyserver
and run:python -m venv .venv
- Run
source ./.venv/bin/activate
to run the virtual environment - Install the project requirements by running
pip install -r requirements.txt
- You can test to see if it worked by running
fastapi dev main.py
and see if the server spins up.
You will need to add two .env files, one in express-server
and one in next-client
. You can find example .env files at the root of those directories.
Encode your Google Credentials using the service account key you downloaded earlier, by running the command base64 -i ./google-credentials.json
. (You do need both the path to the json file and the base-64 encoded version.)
export OPENAI_API_KEY=
export GCLOUD_STORAGE_BUCKET= name of your bucket
export CLIENT_BASE_URL= for dev: http://localhost:3000
export GOOGLE_CREDENTIALS_ENCODED=copy & paste the base64 encoding of your credentials, made above
export PYSERVER_URL= for dev: http://localhost:8000
export FIREBASE_DATABASE_URL= found in your firebase project
export REDIS_HOST= for dev: localhost
export REDIS_PORT= for dev: 6379
export GOOGLE_APPLICATION_CREDENTIALS=./credentials
export NODE_ENV= dev | prod
export PIPELINE_EXPRESS_URL= # This is by default localhost:8080 on dev
# Firebase keys below should be found on your firebase project. These are not sensitive and can be shared with the client.
export NEXT_PUBLIC_FIREBASE_API_KEY=
export NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=
export NEXT_PUBLIC_FIREBASE_PROJECT_ID=
export NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=
export NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=
export NEXT_PUBLIC_FIREBASE_APP_ID=
Copy this file to .env.local in the same directory if you plan to run the dev server (npm run dev
).
You can add different types of .env files based on your needs for testing, dev, prod, etc. You can read more in the NextJS docs
Note: There is a bug that prevents /common
from being built correctly. For your first time, before doing anything else, go to /common
and run npm i && npm run build
. After this, you should be able to follow the other steps. If the project fails to start in dev, try rebuilding common first.
To launch a local instance:
- Make sure you have completed the setup steps above
- From the root of the repo, run
npm run dev
. - This will launch three servers:
- the
next-client
frontend onlocalhost:3000
- the
express-server
backend onlocalhost:8080
and - the
pyserver
Python FastAPI server for the LLM calls onlocalhost:8000
. Additionally, a watcher will spawn that rebuildscommon
when changes are made to it.
- the
There should be no need to use docker for local development, except when working on the Dockerfile or testing something docker-related, in which case you might want to use these scripts:
./bin/docker-build-local.sh # build
./bin/docker-run.sh # run
- Run
./bin/docker-build-gcloud.sh
, which will build and upload an image to the cloud. - Open the google console and search for gloud cloud run.
- Click "EDIT AND DEPLOY NEW VERSION".
- Find the new docker image that you just pushed from the list of available images.
- Allow unauthorised access ("unauthenticated invocations" -- like for public APIs).
- Select "CPU is only allocated during request processing" (no need to keep this running at all time)
Note: the first deploy with fail if you haven't set the .env variables as described above.
Your cloud instance is now ready to use!
To upload a new image (e.g. after a fresh git pull), deploy a new docker image to the same instance:
See here for how to deploy your NextJS app.
This process should work, regardless of whether the app is built locally or remotely. However, the NextJS client can only take CSVs. To submit a Google Sheet, use the API directly.
You can generate your data and view your reports using the NextJS client.
To do so:
- Navigate to wherever your NextJS client is hosted.
- On the [hosting location]/create, you should see a form to submit your data. For local development, this defaults to
http://localhost:3000/create
. - Enter the title, description, your api key, and add the CSV file.
- Optionally, click on the advanced settings for further customization.
- Click submit, and you will shortly see a url for where your JSON data will be stored and the url to view the report.
- Depending on how large your file was, it should take anywhere from 30 seconds to 15 minutes to finish. So bookmark the link and check on it periodically.
- Once the JSON data has been uploaded to Google Cloud, you can view the report by going to
http://[client url]/report/[encoded URI for your stored JSON object]
. In local development, this will have thehttp://localhost:3000/report/https%3A%2F%2Fstorage.googleapis.com%2F[GCLOUD_STORAGE_BUCKET]%2F[generated report id]
. You can copy & paste and substitute in the values for the generated report id (different for each report you create) and the GCLOUD_STORAGE_BUCKET (likely the same for all testing sessions). Keep in mind that the separator is %2F and not the traditional URL slash. - You can then save the report from your browser or add it to your webpage using an iframe. Additionally, if you are signed in, it will save a link to your report at /myReports
Note: The backend Express app does not save your API keys on the server. The NextJS app will save your API keys (and other inputs) in your browser's session storage, which should be secure, and will delete when you close your browser tab.
You can submit your data directly to the Express API using whatever method you're comfortable with. Note: You must have the NextJS client running to view your report. Otherwise, it will just generate the JSON data.
The enpoint to generate reports is POST /create
and it expects a JSON body of the following type:
export type Options = {
userConfig: {
apiKey: string,
title: string,
description: string,
systemInstructions: string,
clusteringInstructions: string,
extractionInstructions: string,
dedupInstructions: string,
},
data: ['csv', {
comment: string,
id: string,
interview: string | undefined,
video: string | undefined,
timestamp: string | undefined,
}[]] | ['googlesheet', {
url: string,
pieChartColumns: string[],
filterEmails: string[],
oneSubmissionPerEmail: boolean,
}]
};
The enpoint is implemented in express-server/src/server.ts
. You can see an example of it being used in next-client/src/features/actions/SubmitAction.ts
and in the examples/
folder.
The data field must contain an array of objects of the following type:
export type SourceRow = {
id: string; // unique id per raw
comment: string; // main content
// optional fields for video interviews:
interview?: string; // name of participants
video?: string; // link to a video hosted on Vimeo
timestamp?: string; // timestamp in the video
};
If your organization does not have a key for ChatGPT or Claude, you can obtain one by:
- Go to OpenAI's website or Anthropic's Website and signup or login.
- Navigate to the API section, accessible from the dashboard or user menu.
- Choose a plan if you are not already subscribed.
- Go the API keys section and press the button to generate a new API key.
- Save this key and not share it.
Some work in progress—please see the contributor guide!