Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: rsync docs
uses: burnett01/rsync-deployments@master
with:
switches: -vzr
switches: -vzr --chown=":sauna"
path: docs/build/
remote_path: ${{ secrets.DEPLOY_DOCS_PATH }}
remote_host: ${{ secrets.DEPLOY_HOST }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/rsync-download-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
- name: rsync download config
uses: burnett01/rsync-deployments@master
with:
switches: -vzr
switches: -vzr --chown=":sauna"
path: download_config.json
remote_path: ${{ secrets.BASE_DIRECTORY_PATH }}
remote_host: ${{ secrets.DEPLOY_HOST }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/website.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: rsync homepage files
uses: burnett01/rsync-deployments@master
with:
switches: -vzr
switches: -vzr --chown=":sauna"
path: website/docs/build/
remote_path: ${{ secrets.DEPLOY_WEBSITE_PATH }}
remote_host: ${{ secrets.DEPLOY_HOST }}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
[![license](https://img.shields.io/badge/license-MIT-green)](https://github.com/CornellNLP/ConvoKit/blob/master/LICENSE.md)
[![Discord Community](https://img.shields.io/static/v1?logo=discord&style=flat&color=red&label=discord&message=community)](https://discord.gg/WMFqMWgz6P)

This toolkit contains tools to extract conversational features and analyze social phenomena in conversations, using a [single unified interface](https://convokit.cornell.edu/documentation/architecture.html) inspired by (and compatible with) scikit-learn. Several large [conversational datasets](https://github.com/CornellNLP/ConvoKit#datasets) are included together with scripts exemplifying the use of the toolkit on these datasets. The latest version is [4.1.0](https://github.com/CornellNLP/ConvoKit/releases/tag/v4.1.0) (released Mar. 10, 2026); follow the [project on GitHub](https://github.com/CornellNLP/ConvoKit) to keep track of updates.
This toolkit contains tools to extract conversational features and analyze social phenomena in conversations, using a [single unified interface](https://convokit.cornell.edu/documentation/architecture.html) inspired by (and compatible with) scikit-learn. Several large [conversational datasets](https://github.com/CornellNLP/ConvoKit#datasets) are included together with scripts exemplifying the use of the toolkit on these datasets. The latest version is [4.1.1](https://github.com/CornellNLP/ConvoKit/releases/tag/v4.1.1) (released May 1, 2026); follow the [project on GitHub](https://github.com/CornellNLP/ConvoKit) to keep track of updates.

Join our [Discord community](https://discord.gg/WMFqMWgz6P) to stay informed, connect with fellow developers, and be part of an engaging space where we share progress, discuss features, and tackle issues together.

Expand Down
112 changes: 100 additions & 12 deletions convokit/genai/example/example.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,19 @@
},
{
"cell_type": "code",
"execution_count": 23,
"execution_count": 1,
"id": "be24454d",
"metadata": {},
"outputs": [],
"source": [
"from convokit.genai.genai_config import GenAIConfigManager"
"from convokit.genai.genai_config import GenAIConfigManager\n",
"config = GenAIConfigManager()\n",
"from convokit.genai import get_llm_client"
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"id": "5666dc72",
"metadata": {},
"outputs": [
Expand All @@ -45,7 +47,6 @@
}
],
"source": [
"config = GenAIConfigManager()\n",
"config.set_api_key(\"gpt\", \"YOUR API KEY\")\n",
"print(f\"Successfully set OpenAI API key in config.\")"
]
Expand All @@ -62,13 +63,11 @@
},
{
"cell_type": "code",
"execution_count": 25,
"execution_count": null,
"id": "220c33fe",
"metadata": {},
"outputs": [],
"source": [
"from convokit.genai import get_llm_client\n",
"\n",
"MODEL_PROVIDER = \"gpt\"\n",
"client = get_llm_client(MODEL_PROVIDER, config)"
]
Expand Down Expand Up @@ -96,6 +95,95 @@
"print(\"Latency:\", response.latency)"
]
},
{
"cell_type": "markdown",
"id": "417c22b9",
"metadata": {},
"source": [
"# Setup ConvoKit GenAI with Google Gemini Through Gemini Developer API"
]
},
{
"cell_type": "markdown",
"id": "94aede45",
"metadata": {},
"source": [
"Checkout Google Gemini Developer API: https://ai.google.dev/gemini-api/docs/"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0a4c8e31",
"metadata": {},
"outputs": [],
"source": [
"MODEL_PROVIDER = \"gemini\"\n",
"MODEL = \"gemini-2.5-flash\"\n",
"config.set_api_key(\"gemini\", \"YOUR API KEY\")"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "88eef33f",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Text: ConvoKit is a powerful Python library designed for the **systematic analysis of conversational data**. It provides a unified framework to represent, transform, and analyze conversations, moving beyond simple text analysis to focus on the rich structure and dynamics inherent in human (and human-like) interactions.\n",
"\n",
"Here's a breakdown of what you can do with ConvoKit:\n",
"\n",
"1. **Represent Conversational Data:**\n",
" * **Standardized Structure:** ConvoKit allows you to load diverse conversational datasets (chat logs, forum posts, emails, transcripts, etc.) into a standardized `Corpus` object, which consists of `Utterance` and `Speaker` objects. This makes it easy to work with different datasets consistently.\n",
" * **Metadata Storage:** You can attach arbitrary metadata to conversations, utterances, and speakers (e.g., speaker demographics, conversation topics, timestamps, sentiment scores).\n",
"\n",
"2. **Preprocess and Enrich Conversational Data:**\n",
" * **Tokenization & Linguistic Features:** Integrate with spaCy to perform tokenization, part-of-speech tagging, named entity recognition, and dependency parsing on utterances.\n",
" * **Sentiment Analysis:** Apply pre-trained sentiment models to utterances to understand emotional tone.\n",
" * **Dialog Act Classification:** Use models to classify the communicative function of an utterance (e.g., question, statement, agreement, disagreement).\n",
" * **Speaker Attributes:** Extract features related to speakers, such as their average utterance length, lexical diversity, or frequency of certain dialog acts.\n",
"\n",
"3. **Analyze Conversational Dynamics and Structure:**\n",
" * **Turn-Taking Patterns:** Investigate how speakers take turns, who initiates conversations, and who responds.\n",
" * **Interaction Networks:** Build and analyze networks of who talks to whom, identifying central speakers or conversational hubs.\n",
" * **Topic Modeling:** Discover latent topics within conversations and track how topics shift over time or across different speakers.\n",
" * **Power and Dominance:** Analyze linguistic cues and interaction patterns that might indicate power dynamics or dominance within a conversation (e.g., interruption patterns, question-asking behavior).\n",
" * **Coherence and Cohesion:** Study how utterances relate to each other to form coherent conversations.\n",
"\n",
"4. **Extract Features for Machine Learning:**\n",
" * **Linguistic Features:** Extract features like word counts, TF-IDF, n-grams, lexical diversity, specific part-of-speech frequencies.\n",
" * **Social Features:** Features related to speaker roles, interaction frequency, or network centrality.\n",
" * **Structural Features:** Features related to turn-taking, utterance position in a conversation, or response time.\n",
" * These features can then be used to train models for tasks like speaker classification, conversation summarization, or predicting conversation outcomes.\n",
"\n",
"5. **Conduct Comparative Studies:**\n",
" * **Compare Groups:** Analyze differences in communication styles, sentiment, or interaction patterns between different groups of speakers (e.g., male vs. female, expert vs. novice, different customer segments).\n",
" * **Compare Contexts:** Study how conversations differ across various contexts (e.g., formal vs. informal, online vs. offline, different platforms).\n",
"\n",
"6. **Specific Use Cases:**\n",
"\n",
" * **Social Science Research:** Studying group dynamics, power structures, communication styles, and social phenomena in online communities, political debates, or interviews.\n",
" * **Customer Service Analytics:** Identifying common customer issues, evaluating agent performance, detecting customer frustration, and optimizing chatbot interactions.\n",
" * **Product Analytics:** Understanding how users interact with a product through chat, forums, or reviews; identifying pain points or feature requests.\n",
" * **Content Moderation:** Detecting toxic language, harassment, or hate speech by analyzing conversational context and patterns, not just isolated words.\n",
" * **Chatbot Development:** Analyzing user input to improve chatbot understanding, evaluating dialog flow, and benchmarking chatbot responses against human conversations.\n",
" * **Digital Humanities:** Analyzing historical texts, interviews, or literary dialogues to uncover linguistic and social insights.\n",
" * **Linguistic Research:** Investigating specific linguistic phenomena, such as politeness strategies, code-switching, or the use of discourse markers in natural conversation.\n",
"\n",
"In essence, ConvoKit empowers researchers and data scientists to move beyond simple text analysis and delve into the rich, structured world of conversations, enabling deeper insights into human communication.\n"
]
}
],
"source": [
"client = get_llm_client(model=MODEL, provider=MODEL_PROVIDER, config_manager=config)\n",
"response = client.generate(\"What can you do with ConvoKit.\")\n",
"print(\"Text:\", response.text)"
]
},
{
"cell_type": "markdown",
"id": "33b72969",
Expand All @@ -114,13 +202,13 @@
"outputs": [],
"source": [
"MODEL_PROVIDER = \"gemini\"\n",
"MODEL = \"gemini-2.0-flash-001\"\n",
"MODEL = \"gemini-2.5-flash\"\n",
"config.set_google_cloud_config(\"YOUR PROJECT\", \"YOUR LOCATION\")"
]
},
{
"cell_type": "code",
"execution_count": 28,
"execution_count": null,
"id": "32fad57a",
"metadata": {},
"outputs": [
Expand All @@ -136,7 +224,7 @@
}
],
"source": [
"client = get_llm_client(MODEL_PROVIDER, config)\n",
"client = get_llm_client(model=MODEL, provider=MODEL_PROVIDER, config_manager=config, use_vertex_ai=True)\n",
"response = client.generate(\"Tell me a fun fact about Cornell University.\")\n",
"print(\"Text:\", response.text)"
]
Expand Down Expand Up @@ -310,7 +398,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"display_name": "convokit",
"language": "python",
"name": "python3"
},
Expand All @@ -324,7 +412,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.5"
"version": "3.12.11"
}
},
"nbformat": 4,
Expand Down
47 changes: 29 additions & 18 deletions convokit/genai/gemini_client.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import os
from google import genai
from google.genai.types import GenerateContentConfig, HttpOptions
from .base import LLMClient, LLMResponse
Expand All @@ -7,35 +6,48 @@


class GeminiClient(LLMClient):
"""Client for interacting with Google Gemini models via Vertex AI.
"""Client for interacting with Google Gemini models.

This client is configured to use Vertex AI and requires Google Cloud project and location
to be set. Configuration can be provided via the GenAI config system or environment variables.
This client uses the Gemini Developer API with an API key by default. If no API key
is configured, or if ``use_vertex_ai`` is set, it falls back to Vertex AI with Google
Cloud project and location configuration.

:param model: Name of the Gemini model to use (default: "gemini-2.0-flash-001")
:param model: Name of the Gemini model to use
:param config_manager: GenAIConfigManager instance (optional, will create one if not provided)
:param use_vertex_ai: Force Vertex AI authentication instead of API key authentication
"""

def __init__(
self,
model: str = "gemini-2.0-flash-001",
model: str,
config_manager: GenAIConfigManager = None,
use_vertex_ai: bool = False,
):
if config_manager is None:
config_manager = GenAIConfigManager()

self.config_manager = config_manager
self.model = model

api_key = config_manager.get_api_key("gemini")
if api_key and not use_vertex_ai:
self.client = genai.Client(api_key=api_key)
else:
self.client = self._create_vertex_ai_client(config_manager)

# Get required Vertex AI configuration
@staticmethod
def _create_vertex_ai_client(config_manager: GenAIConfigManager):
"""Create a Gemini client authenticated through Vertex AI."""
google_cloud_project = config_manager.get_google_cloud_project()
google_cloud_location = config_manager.get_google_cloud_location()

# Validate required fields
if not google_cloud_project:
raise ValueError(
"Google Cloud project is required for Vertex AI. "
"Set it using config_manager.set_google_cloud_config(project, location) "
"or via GOOGLE_CLOUD_PROJECT environment variable."
"Gemini API key or Google Cloud project is required. "
"Set an API key using config_manager.set_api_key('gemini', 'your-key'), "
"or via GEMINI_API_KEY. For Vertex AI, set project and location using "
"config_manager.set_google_cloud_config(project, location) or via "
"GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_LOCATION."
)

if not google_cloud_location:
Expand All @@ -45,13 +57,12 @@ def __init__(
"or via GOOGLE_CLOUD_LOCATION environment variable."
)

# Set up Vertex AI environment
os.environ["GOOGLE_GENAI_USE_VERTEXAI"] = "true"
os.environ["GOOGLE_CLOUD_PROJECT"] = google_cloud_project
os.environ["GOOGLE_CLOUD_LOCATION"] = google_cloud_location

self.client = genai.Client(http_options=HttpOptions(api_version="v1"))
self.model = model
return genai.Client(
vertexai=True,
project=google_cloud_project,
location=google_cloud_location,
http_options=HttpOptions(api_version="v1"),
)

def generate(self, prompt, temperature=0.0, times_retried=0) -> LLMResponse:
"""Generate text using the Gemini model.
Expand Down
4 changes: 2 additions & 2 deletions convokit/genai/gpt_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ class GPTClient(LLMClient):
Handles authentication, request formatting, and error retry logic. API key is managed
through the GenAI config system.

:param model: Name of the GPT model to use (default: "gpt-4o-mini")
:param model: Name of the GPT model to use
:param config_manager: GenAIConfigManager instance (optional, will create one if not provided)
"""

def __init__(self, model: str = "gpt-4o-mini", config_manager: GenAIConfigManager = None):
def __init__(self, model: str, config_manager: GenAIConfigManager = None):
if config_manager is None:
config_manager = GenAIConfigManager()

Expand Down
2 changes: 1 addition & 1 deletion convokit/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ def _get_wikiconv_year_info(language: str, year: str = None) -> str:

# base directory of wikicon corpuses
wikiconv_base = "http://zissou.infosci.cornell.edu/convokit/datasets/wikiconv-corpus/"
data_dir = wikiconv_base + "corpus-zipped/"
data_dir = wikiconv_base + "corpus_zipped/"
final_dir = (
data_dir + language + "/wikiconv-" + year + "/full.corpus.zip"
if year is not None
Expand Down
4 changes: 2 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@

# General information about the project.
project = "convokit"
copyright = "2017-2025 The ConvoKit Developers"
copyright = "2017-2026 The ConvoKit Developers"
author = "The ConvoKit Developers"

# The version info for the project you're documenting, acts as replacement for
Expand All @@ -66,7 +66,7 @@
# The short X.Y version.
version = "4.1"
# The full version, including alpha/beta/rc tags.
release = "4.1.0"
release = "4.1.1"

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
9 changes: 6 additions & 3 deletions docs/source/genai.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Supported Providers
Currently supported LLM providers:

* **OpenAI GPT**: Access to OpenAI GPT models through the OpenAI API. See `OpenAI API setup <https://platform.openai.com/docs/quickstart>`_.
* **Google Gemini**: Access to Google Gemini models via Vertex AI. See `Vertex AI setup guide <https://cloud.google.com/vertex-ai/docs/start/cloud-environment>`_.
* **Google Gemini**: Access to Google Gemini models via the Gemini Developer API by default, or via Vertex AI. See `Gemini API key setup <https://ai.google.dev/gemini-api/docs/api-key>`_ and `Vertex AI setup guide <https://cloud.google.com/vertex-ai/docs/start/cloud-environment>`_.
* **Local Models**: Template implementation for local LLM models (requires custom implementation)

GPT Client
Expand Down Expand Up @@ -79,7 +79,7 @@ Configuration
The GenAIConfigManager handles API key storage and retrieval for different LLM providers. It supports:

* **File-based storage**: Configuration is stored in `~/.convokit/config.yml`
* **Environment variables**: API keys can be set via environment variables (e.g., `GPT_API_KEY`)
* **Environment variables**: API keys can be set via environment variables (e.g., `GPT_API_KEY` or `GEMINI_API_KEY`)
* **Secure storage**: API keys are stored locally and not exposed in code
* **Provider-specific settings**: Support for different configuration requirements per provider (e.g., Google Cloud project settings for Gemini)

Expand All @@ -94,7 +94,10 @@ The GenAIConfigManager handles API key storage and retrieval for different LLM p
# Set OpenAI API key
config.set_api_key("gpt", "your-openai-api-key")

# Set Google Cloud configuration for Gemini
# Set Gemini API key
config.set_api_key("gemini", "your-gemini-api-key")

# Or set Google Cloud configuration for Gemini on Vertex AI
config.set_google_cloud_config("your-project-id", "your-location")

# Configuration is automatically saved and can be reused
Expand Down
2 changes: 1 addition & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Cornell Conversational Analysis Toolkit (ConvoKit) Documentation
This toolkit contains tools to extract conversational features and analyze social phenomena in conversations, using a `single unified interface <https://convokit.cornell.edu/documentation/architecture.html>`_ inspired by (and compatible with) scikit-learn.
Several large `conversational datasets <https://github.com/CornellNLP/ConvoKit#datasets>`_ are included together with scripts exemplifying the use of the toolkit on these datasets.

More information can be found at our `website <https://convokit.cornell.edu>`_. The latest version is `4.1.0 <https://github.com/CornellNLP/ConvoKit/releases/tag/v4.1.0>`_ (released Mar. 10, 2026).
More information can be found at our `website <https://convokit.cornell.edu>`_. The latest version is `4.1.1 <https://github.com/CornellNLP/ConvoKit/releases/tag/v4.1.1>`_ (released May 1, 2026).

Contents
--------
Expand Down
Loading
Loading