chore: import upstream snapshot with attribution
Test Suites / Build CI Environment (push) Has been cancelled
Test Suites / Basic Tests (push) Has been cancelled
Test Suites / End-to-End Tests (push) Has been cancelled
Test Suites / CLI Tests (push) Has been cancelled
Test Suites / Slow End-to-End Tests (push) Has been cancelled
Test Suites / Graph Database Tests (push) Has been cancelled
Test Suites / Vector DB Tests (push) Has been cancelled
Test Suites / Temporal Graph Test (push) Has been cancelled
Test Suites / Search Test on Different DBs (push) Has been cancelled
Test Suites / Example Tests (push) Has been cancelled
Test Suites / Notebook Tests (push) Has been cancelled
Test Suites / OS and Python Tests Ubuntu (push) Has been cancelled
Test Suites / OS and Python Tests Extended (push) Has been cancelled
Test Suites / LLM Test Suite (push) Has been cancelled
Test Suites / S3 File Storage Test (push) Has been cancelled
Test Suites / Run Integration Tests (push) Has been cancelled
Test Suites / MCP Tests (push) Has been cancelled
Test Suites / Docker Compose Test (push) Has been cancelled
Test Suites / Docker CI test (push) Has been cancelled
Test Suites / Relational DB Migration Tests (push) Has been cancelled
Test Suites / Distributed Cognee Test (push) Has been cancelled
Test Suites / DB Examples Tests (push) Has been cancelled
Test Suites / Test Completion Status (push) Has been cancelled
Test Suites / Claude Code Review (push) Has been cancelled
Test Suites / basic checks (push) Has been cancelled
build | Build and Push Cognee MCP Docker Image to dockerhub / docker-build-and-push (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
build | Build and Push Docker Image to dockerhub / docker-build-and-push (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Core Functionality (3.11) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Core Functionality (3.12) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges with Different Graph Databases (kuzu, kuzu) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges with Different Graph Databases (neo4j, neo4j) (push) Has been cancelled
Weighted Edges Tests / Test Weighted Edges Examples (push) Has been cancelled
Weighted Edges Tests / Code Quality for Weighted Edges (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 13:02:24 +08:00
commit c889a57b6b
2544 changed files with 402845 additions and 0 deletions
+71
View File
@@ -0,0 +1,71 @@
# Code owners for the cognee repository.
#
# GitHub auto-requests reviews from these owners when a PR touches their paths.
# Order matters: the LAST matching pattern wins. Keep most-specific rules at the
# bottom.
#
# To update this file, please confirm the change with the affected owners
# before merging. Tracking ticket: COG-4900.
# -----------------------------------------------------------------------------
# Default fallback — picked when no other rule matches.
# -----------------------------------------------------------------------------
* @Vasilije1990
# -----------------------------------------------------------------------------
# Public API surface (V1 + V2)
# -----------------------------------------------------------------------------
/cognee/api/v1/ @dexters1 @Vasilije1990
/cognee/api/v1/cognify/ @dexters1
/cognee/api/v1/remember/ @dexters1 @Vasilije1990
/cognee/api/v1/recall/ @dexters1 @Vasilije1990
# -----------------------------------------------------------------------------
# Retrieval / memory tasks (V2 memory + agentic retrievers)
# -----------------------------------------------------------------------------
/cognee/modules/retrieval/ @hajdul88 @lxobr
/cognee/tasks/memify/ @lxobr @hajdul88
/cognee/tasks/temporal_awareness/ @lxobr @hajdul88
/cognee/tasks/temporal_graph/ @lxobr @hajdul88
# -----------------------------------------------------------------------------
# Pipelines & tasks (the cognify ECL pipeline + composable tasks)
# -----------------------------------------------------------------------------
/cognee/pipelines/ @Vasilije1990
/cognee/tasks/ @Vasilije1990 @siillee
# -----------------------------------------------------------------------------
# Infrastructure adapters
# -----------------------------------------------------------------------------
/cognee/infrastructure/databases/vector/ @siillee @dexters1
/cognee/infrastructure/databases/graph/ @siillee
/cognee/infrastructure/databases/graph/ladybug/ @siillee @hajdul88
/cognee/infrastructure/databases/cache/ @Vasilije1990
# -----------------------------------------------------------------------------
# MCP server
# -----------------------------------------------------------------------------
/cognee-mcp/ @Vasilije1990 @dexters1
# -----------------------------------------------------------------------------
# Frontend (Next.js UI)
# -----------------------------------------------------------------------------
/cognee-frontend/ @LStromann
# -----------------------------------------------------------------------------
# Build, packaging, CI
# -----------------------------------------------------------------------------
/Dockerfile @Vasilije1990
/distributed/Dockerfile @Vasilije1990
/.github/workflows/ @dexters1 @siillee
/.github/actions/ @dexters1
/pyproject.toml @Vasilije1990 @dexters1
/uv.lock @Vasilije1990 @dexters1
# -----------------------------------------------------------------------------
# Contributor experience (this file, CONTRIBUTING.md, AGENTS.md, CLAUDE.md)
# -----------------------------------------------------------------------------
/.github/CODEOWNERS @Vasilije1990
/CONTRIBUTING.md @Vasilije1990
/AGENTS.md @Vasilije1990
/CLAUDE.md @Vasilije1990
+97
View File
@@ -0,0 +1,97 @@
name: 🐛 Bug Report
description: Report a bug or unexpected behavior
title: "[Bug]: "
labels: ["bug", "needs-triage"]
assignees: []
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report! Please provide a clear and detailed description.
- type: textarea
id: description
attributes:
label: Bug Description
description: Please provide a clear and concise description of the bug. What happened vs what you expected?
placeholder: Describe the bug in detail...
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Steps to Reproduce
description: Please provide detailed steps to reproduce the issue
placeholder: |
1. Go to...
2. Click on...
3. See error...
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected Behavior
description: What did you expect to happen?
placeholder: Describe what you expected...
validations:
required: true
- type: textarea
id: actual
attributes:
label: Actual Behavior
description: What actually happened?
placeholder: Describe what actually happened...
validations:
required: true
- type: textarea
id: environment
attributes:
label: Environment
description: Please provide your environment details
placeholder: |
- OS: [e.g. macOS 13.0, Ubuntu 20.04]
- Python version: [e.g. 3.9.0]
- Cognee version: [e.g. 0.1.0]
- LLM Provider: [e.g. OpenAI, Ollama]
- Database: [e.g. Neo4j]
validations:
required: true
- type: textarea
id: logs
attributes:
label: Logs/Error Messages
description: Please include any relevant logs or error messages
placeholder: Paste logs here...
render: shell
validations:
required: false
- type: textarea
id: additional
attributes:
label: Additional Context
description: Add any other context about the problem here
placeholder: Any additional information...
validations:
required: false
- type: checkboxes
id: checklist
attributes:
label: Pre-submission Checklist
description: Please confirm the following before submitting
options:
- label: I have searched existing issues to ensure this bug hasn't been reported already
required: true
- label: I have provided a clear and detailed description of the bug
required: true
- label: I have included steps to reproduce the issue
required: true
- label: I have included my environment details
required: true
+8
View File
@@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: 💬 Discord Community
url: https://discord.gg/NQtRemgQVD
about: Join our Discord community for questions, discussions, and support
- name: 📖 Documentation
url: https://docs.cognee.ai
about: Check our documentation for guides and API references
+73
View File
@@ -0,0 +1,73 @@
name: 📚 Documentation Issue
description: Report an issue with documentation or suggest documentation improvements
title: "[Docs]: "
labels: ["documentation", "needs-triage"]
assignees: []
body:
- type: markdown
attributes:
value: |
Thanks for helping improve our documentation! Please provide details about the documentation issue or improvement.
- type: dropdown
id: doc-type
attributes:
label: Documentation Type
description: What type of documentation issue is this?
options:
- Missing documentation
- Incorrect documentation
- Unclear documentation
- Documentation improvement
- New documentation request
validations:
required: true
- type: textarea
id: location
attributes:
label: Documentation Location
description: Where is the documentation issue located? (URL, file path, section, etc.)
placeholder: https://cognee.ai/docs/... or specific file/section
validations:
required: true
- type: textarea
id: issue
attributes:
label: Issue Description
description: Please describe the documentation issue or improvement needed
placeholder: The documentation is unclear about...
validations:
required: true
- type: textarea
id: suggestion
attributes:
label: Suggested Improvement
description: How would you improve this documentation?
placeholder: I suggest changing this to...
validations:
required: false
- type: textarea
id: additional
attributes:
label: Additional Context
description: Add any other context about the documentation issue
placeholder: Additional context...
validations:
required: false
- type: checkboxes
id: checklist
attributes:
label: Pre-submission Checklist
description: Please confirm the following before submitting
options:
- label: I have searched existing issues to ensure this documentation issue hasn't been reported already
required: true
- label: I have provided a clear description of the documentation issue
required: true
- label: I have specified the location of the documentation issue
required: true
@@ -0,0 +1,77 @@
name: 🚀 Feature Request
description: Suggest a new feature or enhancement
title: "[Feature]: "
labels: ["enhancement", "needs-triage"]
assignees: []
body:
- type: markdown
attributes:
value: |
Thanks for suggesting a new feature! Please provide a clear and detailed description of your idea.
- type: textarea
id: problem
attributes:
label: Problem Statement
description: Is your feature request related to a problem? Please describe the problem you're trying to solve.
placeholder: I'm always frustrated when...
validations:
required: true
- type: textarea
id: solution
attributes:
label: Proposed Solution
description: Describe the solution you'd like to see implemented
placeholder: I would like to see...
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives Considered
description: Describe any alternative solutions or features you've considered
placeholder: I have also considered...
validations:
required: false
- type: textarea
id: use-case
attributes:
label: Use Case
description: Describe your specific use case and how this feature would help
placeholder: This feature would help me...
validations:
required: true
- type: textarea
id: implementation
attributes:
label: Implementation Ideas
description: If you have ideas about how this could be implemented, please share them
placeholder: This could be implemented by...
validations:
required: false
- type: textarea
id: additional
attributes:
label: Additional Context
description: Add any other context, screenshots, or examples about the feature request
placeholder: Additional context...
validations:
required: false
- type: checkboxes
id: checklist
attributes:
label: Pre-submission Checklist
description: Please confirm the following before submitting
options:
- label: I have searched existing issues to ensure this feature hasn't been requested already
required: true
- label: I have provided a clear problem statement and proposed solution
required: true
- label: I have described my specific use case
required: true
+97
View File
@@ -0,0 +1,97 @@
# Workflow Migration to Test Suites
This document explains how to ensure all test workflows are only run through the central test-suites.yml workflow.
## Why Migrate to Test Suites?
1. **Prevent Duplicate Runs**: Avoid running the same tests multiple times
2. **Sequential Execution**: Ensure tests run in the correct order
3. **Centralized Control**: Manage all tests from a single place
4. **Resource Efficiency**: Run tests only when needed
## Automated Migration
We've provided a script to automatically convert individual workflows to only run when called by the test-suites.yml file:
```bash
# Make the script executable
chmod +x .github/workflows/disable_independent_workflows.sh
# Run the script
.github/workflows/disable_independent_workflows.sh
```
## Manual Migration
For each workflow file that should only run through test-suites.yml:
1. Open the workflow file
2. Find the `on:` section, which typically looks like:
```yaml
on:
workflow_dispatch:
pull_request:
types: [labeled, synchronize]
```
3. Replace it with:
```yaml
on:
workflow_call:
secrets:
inherit: true
```
4. Save the file
## Verification
After modifying the workflows, verify that:
1. The workflows no longer trigger on pushes or PRs
2. The workflows still run correctly when called by test-suites.yml
3. No tests are left out of the test-suites.yml orchestrator
## Example Conversion
**Before:**
```yaml
name: test | chromadb
on:
workflow_dispatch:
pull_request:
types: [labeled, synchronize]
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: false
jobs:
run_chromadb_integration_test:
name: chromadb test
runs-on: ubuntu-22.04
# ...rest of workflow...
```
**After:**
```yaml
name: test | chromadb
on:
workflow_call:
secrets:
inherit: true
jobs:
run_chromadb_integration_test:
name: chromadb test
runs-on: ubuntu-22.04
# ...rest of workflow...
```
## Special Cases
- **CI/CD Workflows**: Don't modify workflows for CI/CD pipelines like cd.yaml and cd_prd.yaml
- **Shared Workflows**: Keep reusable_*.yml workflows as they are, since they're already designed to be called by other workflows
- **Infrastructure Workflows**: Don't modify workflows that handle infrastructure or deployments
+80
View File
@@ -0,0 +1,80 @@
name: cognee-setup
description: "Sets up Python, installs uv, and installs dependencies for Cognee."
inputs:
python-version:
description: "Which Python version to use"
required: false
default: "3.11.x"
extra-dependencies:
description: "Additional extra dependencies to install (space-separated)"
required: false
default: ""
rebuild-lockfile:
description: "Whether to rebuild the uv lockfile"
required: false
default: "false"
runs:
using: "composite"
steps:
- name: Detect CI container
id: detect-env
shell: bash
run: |
if [ -f "/app/.anon_id" ] && command -v uv &> /dev/null && [ -d "/app/.venv" ]; then
echo "in-container=true" >> "$GITHUB_OUTPUT"
else
echo "in-container=false" >> "$GITHUB_OUTPUT"
fi
- name: Set up Python
if: steps.detect-env.outputs.in-container != 'true'
uses: actions/setup-python@v5
with:
python-version: ${{ inputs.python-version }}
- name: Install uv
if: steps.detect-env.outputs.in-container != 'true'
uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- name: Rebuild uv lockfile
if: ${{ inputs.rebuild-lockfile == 'true' }}
shell: bash
run: |
rm uv.lock
uv lock
- name: Install dependencies (bare runner)
if: steps.detect-env.outputs.in-container != 'true'
shell: bash
run: |
EXTRA_ARGS=""
if [ -n "${{ inputs.extra-dependencies }}" ]; then
IFS=' ' read -r -a deps <<< "${{ inputs.extra-dependencies }}"
for extra in "${deps[@]}"; do
EXTRA_ARGS="$EXTRA_ARGS --extra $extra"
done
fi
uv sync --extra api --extra docs --extra evals --extra codegraph --extra ollama --extra dev --extra neo4j --extra redis --extra tracing $EXTRA_ARGS
- name: Install dependencies (container - link project only)
if: steps.detect-env.outputs.in-container == 'true'
shell: bash
env:
UV_PROJECT_ENVIRONMENT: /app/.venv
run: |
# Persist for all subsequent steps so uv run uses /app/.venv
echo "UV_PROJECT_ENVIRONMENT=/app/.venv" >> "$GITHUB_ENV"
# Install project into the pre-built venv; --inexact keeps pre-installed extras intact
uv sync --frozen --inexact
# Prevent uv run from re-syncing and stripping extras
echo "UV_NO_SYNC=true" >> "$GITHUB_ENV"
- name: Add telemetry identifier for telemetry test and in case telemetry is enabled by accident
shell: bash
run: |
echo "test-machine" > .anon_id
+35
View File
@@ -0,0 +1,35 @@
name: 'Build Docker images for Cognee'
description: 'Build cognee-related Docker images and push to the Docker registry (AWS ECR)'
inputs:
stage:
description: 'The stage of the pipeline, such as "dev" or "prd", for the Cognee app'
required: true
aws_account_id:
description: 'The AWS account ID for the Cognee app'
required: true
should_publish:
description: 'Whether to publish the Cognee Docker image to AWS ECR; should be either "true" or "false"'
required: true
ecr_image_repo_name:
description: 'The Docker image ECR repository name for the Cognee app, such as "workflows"'
required: true
dockerfile_location:
description: 'The directory location of the Dockerfile for the Cognee app'
required: true
runs:
using: "composite"
steps:
- name: Build PromethAI App Docker image
shell: bash
env:
STAGE: ${{ inputs.stage }}
run: |
export SHA_SHORT="$(git rev-parse --short HEAD)"
export CUR_DATE="$(date +%Y%m%d%H%M%S)"
export VERSION="${{ inputs.stage }}-$CUR_DATE-$SHA_SHORT"
export STAGE="${{ inputs.stage }}"
export APP_DIR="$PWD/${{ inputs.dockerfile_location }}"
image_name="${{ inputs.ecr_image_repo_name }}" version="$VERSION" account="${{ inputs.aws_account_id }}" app_dir="$APP_DIR" publish="${{ inputs.should_publish }}" ./bin/dockerize
echo "Docker tag is: $VERSION"
echo $VERSION > /tmp/.DOCKER_IMAGE_VERSION
+55
View File
@@ -0,0 +1,55 @@
name: install_cognee
description: "Installs Cognee from local source or PyPI depending on specified version"
inputs:
python-version:
description: "Which Python version to use"
required: false
default: "3.11.x"
cognee_version:
description: "Pypi-compatible version of cognee to use. For example, 0.5.2.dev0. `local` (default) - Installing Cognee from local source"
required: false
default: "local"
runs:
using: "composite"
steps:
- name: Detect CI container
id: detect-env
shell: bash
run: |
if [ -f "/app/.anon_id" ] && command -v uv &> /dev/null && [ -d "/app/.venv" ]; then
echo "in-container=true" >> "$GITHUB_OUTPUT"
else
echo "in-container=false" >> "$GITHUB_OUTPUT"
fi
- name: Set up Python
if: steps.detect-env.outputs.in-container != 'true'
uses: actions/setup-python@v5
with:
python-version: ${{ inputs.python-version }}
- name: Install uv
if: steps.detect-env.outputs.in-container != 'true'
uses: astral-sh/setup-uv@v4
with:
enable-cache: true
- name: (Re)Install Cognee
shell: bash
working-directory: cognee-mcp
env:
VIRTUAL_ENV: ${{ steps.detect-env.outputs.in-container == 'true' && '/app/.venv' || '' }}
run: |
uv pip uninstall cognee
if [ "${{ inputs.cognee_version }}" = "local" ]; then
echo "Installing Cognee from local source ..."
uv pip install --force-reinstall -e ../
else
echo "Installing Cognee version ${{ inputs.cognee_version }} from PyPI..."
uv pip install --force-reinstall "cognee==${{ inputs.cognee_version }}"
fi
echo "Installed Cognee version:"
uv pip show cognee | grep Version
+67
View File
@@ -0,0 +1,67 @@
name: 'Setup Neo4j with Graph Data Science'
description: 'Sets up a Neo4j instance with APOC and Graph Data Science plugins for testing'
inputs:
neo4j-version:
description: 'Neo4j version to use'
required: false
default: '5.21'
neo4j-password:
description: 'Password for Neo4j'
required: false
default: 'cognee_test_password'
outputs:
neo4j-url:
description: 'Neo4j connection URL'
value: 'bolt://localhost:7687'
neo4j-username:
description: 'Neo4j username'
value: 'neo4j'
neo4j-password:
description: 'Neo4j password'
value: ${{ inputs.neo4j-password }}
runs:
using: 'composite'
steps:
- name: Start Neo4j with GDS
shell: bash
run: |
docker run -d \
--name neo4j-test \
-p 7474:7474 -p 7687:7687 \
-e NEO4J_AUTH="neo4j/${{ inputs.neo4j-password }}" \
-e NEO4J_PLUGINS='["apoc", "graph-data-science"]' \
-e NEO4J_dbms_security_procedures_unrestricted="apoc.*,gds.*" \
-e NEO4J_apoc_export_file_enabled=true \
-e NEO4J_apoc_import_file_enabled=true \
neo4j:${{ inputs.neo4j-version }}
- name: Wait for Neo4j to be ready
shell: bash
run: |
echo "Waiting for Neo4j to start..."
timeout=60
counter=0
while [ $counter -lt $timeout ]; do
if docker exec neo4j-test cypher-shell -u neo4j -p "${{ inputs.neo4j-password }}" "RETURN 1" > /dev/null 2>&1; then
echo "Neo4j is ready!"
break
fi
echo "Waiting... ($counter/$timeout)"
sleep 2
counter=$((counter + 2))
done
if [ $counter -ge $timeout ]; then
echo "Neo4j failed to start within $timeout seconds"
docker logs neo4j-test
exit 1
fi
- name: Verify GDS is available
shell: bash
run: |
echo "Verifying Graph Data Science library is available..."
docker exec neo4j-test cypher-shell -u neo4j -p "${{ inputs.neo4j-password }}" \
"CALL gds.version() YIELD gdsVersion RETURN gdsVersion"
echo "GDS verification complete!"
+11
View File
@@ -0,0 +1,11 @@
# Core team GitHub logins (one per line). Lines may begin with @; case-insensitive.
borisarzentar
daukadolt
dexters1
hajdul88
hande-k
lxobr
pazone
siillee
vasilije1990
NMZivkovic
+33
View File
@@ -0,0 +1,33 @@
## How to make a release
### Dev release
#### Prepare release
1. Set the project version that will be released in [pyproject.toml](https://github.com/topoteretes/cognee/blob/dev/pyproject.toml#L4)
2. Update `uv.lock` with `uv lock` lock command
3. Update `poetry.lock` by deleting the `poetry.lock` file first and then running the `poetry lock` command. This is required to update the `poetry.lock` file with the new version of the dependencies, otherwise it does not properly update and mostly uses the cached dependency versions in the existing `poetry.lock` file.
4. Create a PR with the changes mentioned above to `dev` and merge it.
#### Perform Release
1. Go to [Release action](https://github.com/topoteretes/cognee/actions/workflows/release.yml)
2. Select `dev` branch and run the workflow.
3. Watch the logs and make sure that everything goes well
### Main release
#### Prepare release
1. Set the project version that will be released in [pyproject.toml](https://github.com/topoteretes/cognee/blob/dev/pyproject.toml#L4)
2. Update `uv.lock` with `uv lock` lock command
3. Update `poetry.lock` by deleting the `poetry.lock` file first and then running the `poetry lock` command. This is required to update the `poetry.lock` file with the new version of the dependencies, otherwise it does not properly update and mostly uses the cached dependency versions in the existing `poetry.lock` file.
4. Create a PR with the changes mentioned above to `main` and merge it.
#### Perform Release
1. Go to [Release action](https://github.com/topoteretes/cognee/actions/workflows/release.yml)
2. Select `main` branch and run the workflow.
3. Watch the logs and make sure that everything goes well
### Release validation
1. Make sure that the correct image is published to [Docker Hub](https://hub.docker.com/r/cognee/cognee)
2. Python package is published to [PyPi](https://pypi.org/project/cognee/)
3. Find the created github release in [GitHub releases](https://github.com/topoteretes/cognee/releases). Edit/prettify the release notes if required.
+34
View File
@@ -0,0 +1,34 @@
You are a documentation improvement agent for the Cognee project.
Update the existing Cognee documentation to reflect this merged PR. Your job is to document the actual behavior and API changes introduced by this PR, not to make adjacent or generic documentation improvements.
## Required inputs
Read these first:
- Documentation scope plan
- Branch notes
- Documentation assessment
## Available resources
- **Documentation repo** (`./docs-repo`): Contains the documentation pages. Use existing `.md` and `.mdx` pages as the primary targets for edits. Read `./docs-repo/docs.json` only if the scope plan requires navigation context.
- **Cognee source code** (current workspace root): Use the source code to verify actual implementation details, defaults, supported options, function signatures, env vars, and behavior.
## Editing rules
1. Follow the documentation scope plan.
2. If the scope plan says `Docs Needed` is `false`, make no documentation edits and print the reason.
3. Inspect only the source files listed in the scope plan unless they are insufficient to verify a specific planned edit.
4. Edit only docs files listed in the scope plan unless they are clearly the wrong target; if so, choose the smallest better existing docs target.
5. Document only user-facing behavior, public API changes, examples, or developer-facing semantics that actually changed in this PR.
6. If a proposed docs edit cannot be traced back to a concrete source diff in this PR, do not make that edit.
7. Do not present pre-existing behavior as if this PR introduced it.
8. Do not make unrelated cleanup edits, style edits, or generic improvements.
9. Edit at most 3 documentation files unless the scope plan explicitly justifies more.
10. Prefer updating existing pages over creating new ones.
11. Do not edit `docs.json` unless the scope plan says a new docs page is strictly required.
12. Only edit documentation files inside `./docs-repo`. Do NOT modify the source repository files, workflow files, or non-documentation assets.
13. Do NOT create git commits.
When done, print a short summary of what you changed and which existing documentation pages you updated.
+46
View File
@@ -0,0 +1,46 @@
You are a documentation scope planner for the Cognee project.
Analyze this merged PR and produce a small documentation edit plan. Do not edit documentation files.
## Available resources
- **Documentation repo** (`./docs-repo`): Contains the documentation pages. Use existing `.md` and `.mdx` pages as the primary targets for edits. Read `./docs-repo/docs.json` if it exists to understand the documentation structure.
- **Cognee source code** (current workspace root): Use the source code to verify actual implementation details, defaults, supported options, function signatures, env vars, and behavior.
- **Prepared documentation edit scope**: Curated source files, docs candidates, documentation signals, assessment summary, and out-of-scope files produced by the workflow.
## Planning task
1. Read the prepared documentation edit scope first.
2. Use the prepared scope as your primary evidence. Do not re-classify the full PR changed-file list.
3. Read only the source files listed in `Source Files To Inspect` unless one listed file is insufficient to verify a specific planned edit.
4. Read only the documentation files listed in `Candidate Documentation Files` unless they are clearly the wrong target.
5. Do not run shell commands or inspect the full diff. If the prepared scope is still too broad, produce a conservative small plan instead of exploring further.
6. Treat files listed in `Out Of Scope Files` as skipped unless one is explicitly needed to verify a planned edit.
7. Identify the smallest docs edit surface that could cover the public-facing changes.
Write the final plan to the scope plan output path provided by the workflow prompt.
The plan must be Markdown with these exact sections:
# Documentation Scope Plan
## Docs Needed
`true` or `false`
## Reason
One concise paragraph.
## Documentation-Worthy Changes
Bullets. Each bullet must name the change, the source files proving it, and the recommended docs page type.
## Files To Edit
Bullets of existing docs files to edit. Use paths relative to `docs-repo`. Leave empty if none.
## Source Files To Inspect During Editing
Bullets of source files the editing step should inspect. Keep this list short and exclude tests/assets/lockfiles.
## Out Of Scope
Bullets for changes intentionally skipped.
Do not edit files inside `./docs-repo`.
Do not create commits.
+38
View File
@@ -0,0 +1,38 @@
<!-- .github/pull_request_template.md -->
## Description
<!--
Please provide a clear, human-generated description of the changes in this PR.
DO NOT use AI-generated descriptions. We want to understand your thought process and reasoning.
-->
## Acceptance Criteria
<!--
* Key requirements to the new feature or modification;
* Proof that the changes work and meet the requirements;
-->
## Type of Change
<!-- Please check the relevant option -->
- [ ] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Code refactoring
- [ ] Other (please specify):
## Screenshots
<!-- ADD SCREENSHOT OF LOCAL TESTS PASSING-->
## Pre-submission Checklist
<!-- Please check all boxes that apply before submitting your PR -->
- [ ] **I have tested my changes thoroughly before submitting this PR** (See `CONTRIBUTING.md`)
- [ ] **This PR contains minimal changes necessary to address the issue/feature**
- [ ] My code follows the project's coding standards and style guidelines
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] I have added necessary documentation (if applicable)
- [ ] All new and existing tests pass
- [ ] I have searched existing PRs to ensure this change hasn't been submitted already
- [ ] I have linked any relevant issues in the description
- [ ] My commits have clear and descriptive messages
## DCO Affirmation
I affirm that all code in every commit of this pull request conforms to the terms of the Topoteretes Developer Certificate of Origin.
+20
View File
@@ -0,0 +1,20 @@
name-template: 'v$NEXT_PATCH_VERSION'
tag-template: 'v$NEXT_PATCH_VERSION'
categories:
- title: 'Features'
labels: ['feature', 'enhancement']
- title: 'Bug Fixes'
labels: ['bug', 'fix']
- title: 'Maintenance'
labels: ['chore', 'refactor', 'ci']
change-template: '- $TITLE (#$NUMBER) @$AUTHOR'
template: |
## Whats Changed
$CHANGES
## Contributors
$CONTRIBUTORS
+291
View File
@@ -0,0 +1,291 @@
name: Reusable Adapter Caching Tests
permissions:
contents: read
packages: read
on:
workflow_call:
inputs:
databases:
required: false
type: string
default: "all"
description: "Which provider combos to test (comma-separated list or 'all')"
python-version:
required: false
type: string
default: '3.11.x'
description: "Python version to test"
ci-image:
required: false
type: string
default: ''
description: "Container image for CI (empty string means no container)"
secrets:
LLM_MODEL:
required: true
LLM_ENDPOINT:
required: true
LLM_API_KEY:
required: true
LLM_ARGS:
required: false
LLM_API_VERSION:
required: true
EMBEDDING_MODEL:
required: true
EMBEDDING_API_KEY:
required: true
jobs:
run-ladybug-lance-sqlite-caching:
name: Adapter caching — Ladybug + LanceDB + Sqlite
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'ladybug/lance/sqlite') }}
steps:
- name: Check out
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
- name: Run adapter caching test
env:
ENV: 'dev'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
GRAPH_DATABASE_PROVIDER: 'ladybug'
VECTOR_DB_PROVIDER: 'lancedb'
DB_PROVIDER: 'sqlite'
run: uv run python ./cognee/tests/test_adapter_object_caching.py
run-neo4j-lance-sqlite-caching:
name: Adapter caching — Neo4j + LanceDB + Sqlite
runs-on: ubuntu-22.04
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'neo4j/lance/sqlite') }}
steps:
- name: Check out
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
- name: Setup Neo4j with GDS
uses: ./.github/actions/setup_neo4j
id: neo4j
- name: Run adapter caching test
env:
ENV: 'dev'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
GRAPH_DATABASE_PROVIDER: 'neo4j'
VECTOR_DB_PROVIDER: 'lancedb'
DB_PROVIDER: 'sqlite'
ENABLE_BACKEND_ACCESS_CONTROL: 'false'
GRAPH_DATABASE_URL: ${{ steps.neo4j.outputs.neo4j-url }}
GRAPH_DATABASE_USERNAME: ${{ steps.neo4j.outputs.neo4j-username }}
GRAPH_DATABASE_PASSWORD: ${{ steps.neo4j.outputs.neo4j-password }}
run: uv run python ./cognee/tests/test_adapter_object_caching.py
run-ladybug-pgvector-postgres-caching:
name: Adapter caching — Ladybug + PGVector + Postgres
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'ladybug/pgvector/postgres') }}
services:
postgres:
image: ghcr.io/topoteretes/pgvector:pg17
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
POSTGRES_USER: cognee
POSTGRES_PASSWORD: cognee
POSTGRES_DB: cognee_db
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Check out
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
extra-dependencies: "postgres"
- name: Run adapter caching test
env:
ENV: 'dev'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
GRAPH_DATABASE_PROVIDER: 'ladybug'
VECTOR_DB_PROVIDER: 'pgvector'
ENABLE_BACKEND_ACCESS_CONTROL: 'false'
DB_PROVIDER: 'postgres'
DB_NAME: 'cognee_db'
DB_HOST: ${{ inputs.ci-image != '' && 'postgres' || '127.0.0.1' }}
DB_PORT: 5432
DB_USERNAME: cognee
DB_PASSWORD: cognee
run: uv run python ./cognee/tests/test_adapter_object_caching.py
run-neo4j-pgvector-postgres-caching:
name: Adapter caching — Neo4j + PGVector + Postgres
runs-on: ubuntu-22.04
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'neo4j/pgvector/postgres') }}
services:
postgres:
image: ghcr.io/topoteretes/pgvector:pg17
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
POSTGRES_USER: cognee
POSTGRES_PASSWORD: cognee
POSTGRES_DB: cognee_db
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries=5
steps:
- name: Check out
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
extra-dependencies: "postgres"
- name: Setup Neo4j with GDS
uses: ./.github/actions/setup_neo4j
id: neo4j
- name: Run adapter caching test
env:
ENV: 'dev'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
GRAPH_DATABASE_PROVIDER: 'neo4j'
VECTOR_DB_PROVIDER: 'pgvector'
DB_PROVIDER: 'postgres'
ENABLE_BACKEND_ACCESS_CONTROL: 'false'
GRAPH_DATABASE_URL: ${{ steps.neo4j.outputs.neo4j-url }}
GRAPH_DATABASE_USERNAME: ${{ steps.neo4j.outputs.neo4j-username }}
GRAPH_DATABASE_PASSWORD: ${{ steps.neo4j.outputs.neo4j-password }}
DB_NAME: cognee_db
DB_HOST: 127.0.0.1
DB_PORT: 5432
DB_USERNAME: cognee
DB_PASSWORD: cognee
run: uv run python ./cognee/tests/test_adapter_object_caching.py
run-postgres-pgvector-postgres-caching:
name: Adapter caching — Postgres graph + PGVector + Postgres (access control)
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'postgres/pgvector/postgres') }}
services:
postgres:
image: ghcr.io/topoteretes/pgvector:pg17
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
POSTGRES_USER: cognee
POSTGRES_PASSWORD: cognee
POSTGRES_DB: cognee_db
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Check out
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
extra-dependencies: "postgres"
- name: Run adapter caching test
env:
ENV: 'dev'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
# Access control mode: every dataset gets its own physical Postgres
# database (named after the deterministic dataset id) that is created
# on add and dropped on delete — the engine-cache lifecycle across
# that drop/recreate boundary is what this job guards.
ENABLE_BACKEND_ACCESS_CONTROL: 'true'
DB_PROVIDER: 'postgres'
DB_NAME: 'cognee_db'
DB_HOST: ${{ inputs.ci-image != '' && 'postgres' || '127.0.0.1' }}
DB_PORT: 5432
DB_USERNAME: cognee
DB_PASSWORD: cognee
VECTOR_DB_PROVIDER: 'pgvector'
VECTOR_DB_NAME: 'cognee_db'
VECTOR_DB_HOST: ${{ inputs.ci-image != '' && 'postgres' || '127.0.0.1' }}
VECTOR_DB_PORT: 5432
VECTOR_DB_USERNAME: cognee
VECTOR_DB_PASSWORD: cognee
VECTOR_DATASET_DATABASE_HANDLER: 'pgvector'
GRAPH_DATABASE_PROVIDER: 'postgres'
GRAPH_DATABASE_NAME: 'cognee_db'
GRAPH_DATABASE_HOST: ${{ inputs.ci-image != '' && 'postgres' || '127.0.0.1' }}
GRAPH_DATABASE_PORT: 5432
GRAPH_DATABASE_USERNAME: cognee
GRAPH_DATABASE_PASSWORD: cognee
GRAPH_DATASET_DATABASE_HANDLER: 'postgres_graph'
run: uv run python ./cognee/tests/test_adapter_object_caching.py
+40
View File
@@ -0,0 +1,40 @@
name: community | DCO Check
on:
pull_request:
types: [opened, edited, reopened, synchronize, ready_for_review]
jobs:
check-dco:
runs-on: ubuntu-latest
steps:
- name: Validate Developer Certificate of Origin statement
uses: actions/github-script@v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const prUser = context.payload.pull_request.user.login;
const prBody = context.payload.pull_request.body || '';
const authorAssociation = context.payload.pull_request.author_association;
// Exact text you require in the PR body
const requiredStatement = "I affirm that all code in every commit of this pull request conforms to the terms of the Topoteretes Developer Certificate of Origin";
// 1. Check if user is an org member via author_association
// (available on the PR payload without extra API calls or permissions)
// OWNER, MEMBER, and COLLABORATOR are trusted roles.
const trustedRoles = ['OWNER', 'MEMBER', 'COLLABORATOR', 'CONTRIBUTOR'];
const isTrusted = trustedRoles.includes(authorAssociation);
if (isTrusted) {
console.log(`${prUser} has association '${authorAssociation}'. Skipping DCO check.`);
} else {
console.log(`${prUser} has association '${authorAssociation}'. Enforcing DCO check.`);
// 2. If user is not trusted, enforce the DCO statement
if (!prBody.includes(requiredStatement)) {
core.setFailed(
`DCO check failed. The PR body must include the following statement:\n\n${requiredStatement}`
);
}
}
@@ -0,0 +1,27 @@
name: build test | Docker image
on:
workflow_call:
env:
AWS_ACCOUNT_ID_DEV: "463722570299"
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
build_docker:
name: Build Cognee Backend Docker App Image
runs-on: ubuntu-22.04
steps:
- name: Check out Cognee code
uses: actions/checkout@v6
- name: Build Cognee Docker image
id: cognee-docker-tag
run: |
export SHA_SHORT="$(git rev-parse --short HEAD)"
export CUR_DATE="$(date +%Y%m%d%H%M%S)"
export VERSION="dev-$CUR_DATE-$SHA_SHORT"
image_name="cognee" docker_login="false" version="$VERSION" account="${{ env.AWS_ACCOUNT_ID_DEV }}" app_dir="." publish="false" ./bin/dockerize
export DOCKER_TAG=$(cat /tmp/.DOCKER_IMAGE_VERSION)
echo "Successfully built cognee Docker image. Tag is: $DOCKER_TAG"
+139
View File
@@ -0,0 +1,139 @@
name: Reusable Basic Tests
on:
workflow_call:
inputs:
python-version:
required: false
type: string
default: '3.11.x'
ci-image:
required: false
type: string
default: ''
secrets:
LLM_PROVIDER:
required: true
LLM_MODEL:
required: true
LLM_ENDPOINT:
required: true
LLM_API_KEY:
required: true
LLM_ARGS:
required: false
LLM_API_VERSION:
required: true
EMBEDDING_PROVIDER:
required: true
EMBEDDING_MODEL:
required: true
EMBEDDING_API_KEY:
required: true
env:
RUNTIME__LOG_LEVEL: ERROR
ENV: 'dev'
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
unit-tests:
name: Run Unit Tests
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
env:
ENV: 'dev'
LLM_PROVIDER: openai
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_PROVIDER: openai
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
- name: Run Unit Tests
run: uv run pytest cognee/tests/unit/ --timeout=300 --timeout-method=thread
simple-examples:
name: Run Simple Examples
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
env:
ENV: 'dev'
LLM_PROVIDER: openai
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_PROVIDER: openai
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
- name: Run Simple Examples
run: uv run python ./examples/demos/simple_cognee_example.py
simple-examples-baml:
name: Run Simple Examples BAML
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
env:
ENV: 'dev'
STRUCTURED_OUTPUT_FRAMEWORK: "BAML"
BAML_LLM_PROVIDER: openai
BAML_LLM_MODEL: ${{ secrets.OPENAI_MODEL }}
BAML_LLM_ENDPOINT: ${{ secrets.OPENAI_ENDPOINT }}
BAML_LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }}
# BAML_LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
LLM_PROVIDER: openai
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_PROVIDER: openai
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
extra-dependencies: "baml"
- name: Run Simple Examples
run: uv run python ./examples/demos/simple_cognee_example.py
+32
View File
@@ -0,0 +1,32 @@
name: clean | remove stale PRs
on:
# Run this action periodically (daily at 0:00 UTC).
schedule:
- cron: "0 0 * * *"
# Optionally, also run when pull requests are labeled, unlabeled, synchronized, or reopened
# to update the stale timer as needed. Uncomment if desired.
# pull_request:
# types: [labeled, unlabeled, synchronize, reopened]
jobs:
stale:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Mark and Close Stale PRs
uses: actions/stale@v10
with:
# Number of days of inactivity before the pull request is marked stale
days-before-stale: 60
# Number of days of inactivity after being marked stale before the pull request is closed
days-before-close: 7
# Comment to post when marking as stale
stale-pr-message: "This pull request has been automatically marked as stale due to inactivity. It will be closed in 7 days if no further activity occurs."
# Comment to post when closing a stale pull request
close-pr-message: "This pull request has been closed due to prolonged inactivity."
# Labels for stale and closed PRs
stale-pr-label: "stale"
exempt-pr-labels: "keep-open"
+171
View File
@@ -0,0 +1,171 @@
name: test | cli
on:
workflow_call:
inputs:
python-version:
required: false
type: string
default: '3.11.x'
cognee_version:
required: false
type: string
default: "local"
description: "Pypi-compatible version of cognee to use. For example, 0.5.2.dev0. `local` (default) - Installing Cognee from local source"
ci-image:
required: false
type: string
default: ''
secrets:
LLM_PROVIDER:
required: true
LLM_MODEL:
required: true
LLM_ENDPOINT:
required: true
LLM_API_KEY:
required: true
LLM_ARGS:
required: false
LLM_API_VERSION:
required: true
EMBEDDING_PROVIDER:
required: true
EMBEDDING_MODEL:
required: true
EMBEDDING_API_KEY:
required: true
env:
RUNTIME__LOG_LEVEL: ERROR
ENV: 'dev'
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
cli-unit-tests:
name: CLI Unit Tests
if: ${{ inputs.cognee_version == 'local' }}
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
env:
ENV: 'dev'
LLM_PROVIDER: openai
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
- name: Run CLI Unit Tests
run: uv run pytest cognee/tests/cli_tests/cli_unit_tests/ -v
cli-integration-tests:
name: CLI Integration Tests
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
env:
ENV: 'dev'
LLM_PROVIDER: openai
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
- name: Install Cognee
uses: ./.github/actions/install_cognee
with:
python-version: ${{ inputs.python-version }}
cognee_version: ${{ inputs.cognee_version }}
- name: Run CLI Integration Tests
run: uv run pytest cognee/tests/cli_tests/cli_integration_tests/ -v
cli-functionality-tests:
name: CLI Functionality Tests
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
env:
ENV: 'dev'
LLM_PROVIDER: openai
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
- name: Install Cognee
uses: ./.github/actions/install_cognee
with:
python-version: ${{ inputs.python-version }}
cognee_version: ${{ inputs.cognee_version }}
- name: Test CLI Help Commands
run: |
uv run python -m cognee.cli._cognee --help
uv run python -m cognee.cli._cognee --version
uv run python -m cognee.cli._cognee add --help
uv run python -m cognee.cli._cognee search --help
uv run python -m cognee.cli._cognee cognify --help
uv run python -m cognee.cli._cognee delete --help
uv run python -m cognee.cli._cognee config --help
- name: Test CLI Config Subcommands
run: |
uv run python -m cognee.cli._cognee config get --help
uv run python -m cognee.cli._cognee config set --help
uv run python -m cognee.cli._cognee config list --help
uv run python -m cognee.cli._cognee config unset --help
uv run python -m cognee.cli._cognee config reset --help
- name: Test CLI Error Handling
run: |
# Test invalid command (should fail gracefully)
! uv run python -m cognee.cli._cognee invalid_command
# Test missing required arguments (should fail gracefully)
! uv run python -m cognee.cli._cognee search
# Test invalid search type (should fail gracefully)
! uv run python -m cognee.cli._cognee search "test" --query-type INVALID_TYPE
# Test invalid chunker (should fail gracefully)
! uv run python -m cognee.cli._cognee cognify --chunker InvalidChunker
+25
View File
@@ -0,0 +1,25 @@
name: community | Greetings
on:
issues:
types: [opened]
pull_request_target:
types: [opened]
permissions:
issues: write
pull-requests: write
jobs:
greeting:
if: github.actor != 'github-actions[bot]' && github.actor != 'dependabot[bot]' && !contains(github.event.pull_request.body, 'Generated with [Claude Code]')
runs-on: ubuntu-22.04
steps:
- uses: actions/first-interaction@v3
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
pr_message: 'Hello @${{ github.actor }}, thank you for submitting a PR! We will respond as soon as possible.'
issue_message: |
Hello @${{ github.actor }}, thank you for your interest in our work!
If this is a bug report, please provide screenshots and **minimum viable code to reproduce your issue**, otherwise we can not help you.
+180
View File
@@ -0,0 +1,180 @@
name: Community Tests (No Secrets)
# Runs on ALL pull requests, including forks.
# No secrets required — only fully mocked unit tests and code quality checks.
# This gives community contributors fast feedback on their changes.
on:
pull_request:
branches: [ main, dev ]
types: [opened, synchronize, reopened]
permissions:
contents: read
concurrency:
group: community-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
env:
RUNTIME__LOG_LEVEL: ERROR
ENV: 'dev'
jobs:
code-quality:
name: Code Quality
runs-on: ubuntu-22.04
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Validate uv lockfile
run: uv lock --check || { echo "'uv lock --check' failed. Run 'uv lock' and push your changes."; exit 1; }
- name: Run pre-commit hooks
uses: pre-commit/action@v3.0.1
- name: Install dependencies
run: uv sync --extra dev
- name: Ruff check
run: uv run ruff check .
- name: Ruff format check
run: uv run ruff format --check .
- name: Ty type check
run: uv run ty check .
unit-tests:
name: Unit Tests (Mocked, No Secrets)
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
python-version: ['3.11.x']
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Install dependencies
# postgres is needed so the SQL cache adapter tests run instead of skipping.
run: uv sync --extra dev --extra postgres
- name: Run mocked unit tests
run: |
uv run pytest \
cognee/tests/unit/processing/ \
cognee/tests/unit/entity_extraction/ \
cognee/tests/unit/modules/graph/ \
cognee/tests/unit/modules/chunking/ \
cognee/tests/unit/modules/data/ \
cognee/tests/unit/modules/retrieval/ \
--ignore=cognee/tests/unit/modules/retrieval/graph_completion_retriever_cot_test.py \
--ignore=cognee/tests/unit/modules/retrieval/temporal_retriever_test.py \
--ignore=cognee/tests/unit/modules/retrieval/triplet_retriever_test.py \
cognee/tests/unit/modules/search/ \
cognee/tests/unit/modules/pipelines/ \
cognee/tests/unit/modules/visualization/ \
cognee/tests/unit/modules/ontology/ \
cognee/tests/unit/modules/observability/ \
cognee/tests/unit/modules/users/ \
cognee/tests/unit/modules/memify_tasks/ \
cognee/tests/unit/interfaces/graph/ \
cognee/tests/unit/infrastructure/databases/cache/ \
cognee/tests/unit/infrastructure/databases/vector/test_vector_db_config.py \
cognee/tests/unit/infrastructure/databases/relational/ \
cognee/tests/unit/infrastructure/databases/test_unified_store_engine.py \
cognee/tests/unit/infrastructure/session/ \
cognee/tests/unit/infrastructure/llm/ \
cognee/tests/unit/infrastructure/test_rate_limiting_retry.py \
cognee/tests/unit/tasks/storage/test_add_data_points.py \
cognee/tests/unit/shared/ \
-v --tb=short
cli-unit-tests:
name: CLI Unit Tests (Mocked, No Secrets)
runs-on: ubuntu-22.04
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11.x'
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Install dependencies
run: uv sync --extra dev
- name: Run CLI unit tests
run: uv run pytest cognee/tests/cli_tests/cli_unit_tests/ -v --tb=short
telemetry-test:
name: Telemetry Test (Mocked, No Secrets)
runs-on: ubuntu-22.04
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11.x'
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Install dependencies
run: uv sync --extra dev
- name: Run telemetry test
run: uv run pytest cognee/tests/test_telemetry.py -v --tb=short
notify:
name: Community Tests Status
needs: [code-quality, unit-tests, cli-unit-tests, telemetry-test]
runs-on: ubuntu-latest
if: ${{ !cancelled() }}
steps:
- name: Check Status
run: |
if [[ "${{ needs.code-quality.result }}" == "success" &&
"${{ needs.unit-tests.result }}" == "success" &&
"${{ needs.cli-unit-tests.result }}" == "success" &&
"${{ needs.telemetry-test.result }}" == "success" ]]; then
echo "All community tests passed!"
else
echo "One or more community tests failed."
exit 1
fi
+165
View File
@@ -0,0 +1,165 @@
name: Reusable DB Examples Tests
on:
workflow_call:
inputs:
databases:
required: false
type: string
default: "all"
description: "Which databases to run (comma-separated or 'all')"
python-version:
required: false
type: string
default: "3.11.x"
ci-image:
required: false
type: string
default: ''
secrets:
LLM_MODEL:
required: true
LLM_ENDPOINT:
required: true
LLM_API_KEY:
required: true
LLM_ARGS:
required: false
LLM_API_VERSION:
required: true
EMBEDDING_MODEL:
required: true
EMBEDDING_API_KEY:
required: true
POSTGRES_PASSWORD:
required: false
NEO4J_API_URL:
required: false
NEO4J_API_KEY:
required: false
env:
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
run-db-example-neo4j:
name: "Neo4j DB Example Test"
runs-on: ubuntu-22.04
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'neo4j') }}
steps:
- name: Check out
uses: actions/checkout@master
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
- name: Setup Neo4j with GDS
uses: ./.github/actions/setup_neo4j
id: neo4j
- name: Run Neo4j Example
env:
ENV: 'dev'
ENABLE_BACKEND_ACCESS_CONTROL: 'false'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
GRAPH_DATABASE_PROVIDER: "neo4j"
GRAPH_DATABASE_URL: ${{ steps.neo4j.outputs.neo4j-url }}
GRAPH_DATABASE_USERNAME: ${{ steps.neo4j.outputs.neo4j-username }}
GRAPH_DATABASE_PASSWORD: ${{ steps.neo4j.outputs.neo4j-password }}
run: |
uv run python examples/database_examples/neo4j_example.py
run-db-example-ladybug:
name: "Ladybug DB Example Test"
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'ladybug') || contains(inputs.databases, 'kuzu') }}
steps:
- name: Check out
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
- name: Dependencies already installed
run: echo "Dependencies already installed in setup"
- name: Run Ladybug Example
env:
ENV: 'dev'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
GRAPH_DATABASE_PROVIDER: "ladybug"
run: |
uv run python examples/database_examples/ladybug_example.py
run-db-example-pgvector:
name: "PostgreSQL PGVector DB Example Test"
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'postgres') }}
services:
postgres:
image: ghcr.io/topoteretes/pgvector:pg17
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
POSTGRES_USER: cognee
POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
POSTGRES_DB: cognee_db
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
extra-dependencies: "postgres"
- name: Run PGVector Example
env:
ENV: 'dev'
ENABLE_BACKEND_ACCESS_CONTROL: 'false'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
DB_HOST: ${{ inputs.ci-image != '' && 'postgres' || '127.0.0.1' }}
run: |
uv run python examples/database_examples/pgvector_example.py
+123
View File
@@ -0,0 +1,123 @@
name: Dev Canary Release
on:
schedule:
# Every Monday at 06:00 UTC
- cron: "0 6 * * 1"
workflow_dispatch:
workflow_call:
concurrency:
group: dev-canary-release
cancel-in-progress: true
permissions:
contents: read
packages: write
jobs:
# ── Gate: run core test suites before publishing ────────────────────
test-gate:
name: Canary Test Gate
uses: ./.github/workflows/basic_tests.yml
with:
ci-image: ""
secrets: inherit
# ── Compute canary version ──────────────────────────────────────────
prepare:
name: Prepare Canary Version
runs-on: ubuntu-latest
needs: test-gate
outputs:
version: ${{ steps.version.outputs.version }}
canary_version: ${{ steps.version.outputs.canary_version }}
steps:
- name: Check out dev
uses: actions/checkout@v6
with:
ref: dev
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install Python
run: uv python install
- name: Compute canary version
id: version
run: |
BASE_VERSION="$(uv version --short)"
# Strip any existing .devN suffix to get the base
CLEAN_VERSION="${BASE_VERSION%%\.dev*}"
# PEP 440 dev release: 0.5.4.dev20260309
CANARY_VERSION="${CLEAN_VERSION}.dev$(date -u +%Y%m%d)"
echo "version=${CLEAN_VERSION}" >> "$GITHUB_OUTPUT"
echo "canary_version=${CANARY_VERSION}" >> "$GITHUB_OUTPUT"
echo "Canary version: ${CANARY_VERSION}"
# ── Publish to PyPI ─────────────────────────────────────────────────
release-pypi:
name: Publish Dev Canary to PyPI
needs: prepare
runs-on: ubuntu-latest
steps:
- name: Check out dev
uses: actions/checkout@v6
with:
ref: dev
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install Python
run: uv python install
- name: Set canary version in pyproject.toml
run: uv version "${{ needs.prepare.outputs.canary_version }}"
- name: Install dependencies
run: uv sync --all-extras
- name: Build distributions
run: uv build
- name: Publish to PyPI
env:
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }}
run: uv publish
# ── Publish Docker image ────────────────────────────────────────────
release-docker:
name: Publish Dev Canary Docker Image
needs: prepare
runs-on: ubuntu-latest
steps:
- name: Check out dev
uses: actions/checkout@v6
with:
ref: dev
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
cognee/cognee:dev-canary
cognee/cognee:${{ needs.prepare.outputs.canary_version }}
labels: |
version=${{ needs.prepare.outputs.canary_version }}
flavour=dev-canary
cache-from: type=registry,ref=cognee/cognee:buildcache
cache-to: type=registry,ref=cognee/cognee:buildcache,mode=max
@@ -0,0 +1,351 @@
name: automation | Draft Docs PRs For Previous Day Dev PRs
on:
workflow_dispatch:
inputs:
lookback_days:
description: Number of UTC calendar days to look back when scanning merged PRs
required: false
default: "1"
anchor_date:
description: Optional UTC date to scan, in YYYY-MM-DD format
required: false
default: ""
schedule:
- cron: "59 23 * * *"
permissions:
contents: read
pull-requests: read
env:
lookback_days: ${{ github.event.inputs.lookback_days || vars.lookback_days || '1' }}
jobs:
prepare-merged-branches:
runs-on: ubuntu-22.04
timeout-minutes: 10
outputs:
start_date: ${{ steps.prepare.outputs.start_date }}
end_date: ${{ steps.prepare.outputs.end_date }}
has_merges: ${{ steps.prepare.outputs.has_merges }}
merge_summary: ${{ steps.prepare.outputs.merge_summary }}
matrix: ${{ steps.prepare.outputs.matrix }}
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Fetch latest dev branch
run: git fetch origin dev:refs/remotes/origin/dev --no-tags
- name: Prepare merged PRs
id: prepare
shell: bash
env:
INPUT_ANCHOR_DATE: ${{ github.event.inputs.anchor_date || '' }}
GITHUB_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
args=(
--branch origin/dev
--lookback-days "${lookback_days}"
)
anchor_date="${INPUT_ANCHOR_DATE}"
if [ "${{ github.event_name }}" = "schedule" ]; then
anchor_date="$(date -u -d 'yesterday' +%F)"
fi
if [ -n "${anchor_date}" ]; then
echo "Using anchor date ${anchor_date}"
args+=(--anchor-date "${anchor_date}")
fi
python3 tools/prepare_merged_branches.py "${args[@]}"
create-docs-prs:
needs:
- prepare-merged-branches
if: ${{ needs.prepare-merged-branches.outputs.has_merges == 'true' }}
runs-on: ubuntu-22.04
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
include: ${{ fromJSON(needs.prepare-merged-branches.outputs.matrix) }}
steps:
- name: Check out core repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Set up uv
uses: astral-sh/setup-uv@v7
- name: Install workflow dependencies
run: uv sync --locked
- name: Fetch latest dev branch
run: git fetch origin dev:refs/remotes/origin/dev --no-tags
- name: Prepare branch note paths
id: branch_paths
run: |
OUTPUT_DIR="branch-dev-notes/${{ matrix.safe_branch }}-${{ matrix.short_sha }}"
mkdir -p "${OUTPUT_DIR}"
echo "output_dir=${OUTPUT_DIR}" >> "${GITHUB_OUTPUT}"
echo "notes_json=${OUTPUT_DIR}/branch_notes.json" >> "${GITHUB_OUTPUT}"
echo "notes_markdown=${OUTPUT_DIR}/branch_notes.md" >> "${GITHUB_OUTPUT}"
echo "assessment_json=${OUTPUT_DIR}/docs_assessment.json" >> "${GITHUB_OUTPUT}"
echo "assessment_markdown=${OUTPUT_DIR}/docs_assessment.md" >> "${GITHUB_OUTPUT}"
echo "docs_edit_scope_json=${OUTPUT_DIR}/docs_edit_scope.json" >> "${GITHUB_OUTPUT}"
echo "docs_edit_scope_markdown=${OUTPUT_DIR}/docs_edit_scope.md" >> "${GITHUB_OUTPUT}"
echo "docs_scope_plan=${OUTPUT_DIR}/docs_scope_plan.md" >> "${GITHUB_OUTPUT}"
- name: Generate branch notes
env:
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY || secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_MODEL: ${{ vars.LLM_MODEL || secrets.LLM_MODEL || 'openai/gpt-4o-mini' }}
NOTES_JSON: ${{ steps.branch_paths.outputs.notes_json }}
NOTES_MARKDOWN: ${{ steps.branch_paths.outputs.notes_markdown }}
PR_NUMBER: ${{ matrix.pr_number }}
PR_TITLE: ${{ matrix.pr_title }}
PR_BODY_B64: ${{ matrix.pr_body_b64 }}
PR_URL: ${{ matrix.pr_url }}
run: |
uv run python tools/generate_branch_notes.py \
--branch-name "${{ matrix.branch_name }}" \
--merge-sha "${{ matrix.merge_sha }}" \
--first-parent "${{ matrix.first_parent }}" \
--second-parent "${{ matrix.second_parent }}" \
--pr-number "${PR_NUMBER}" \
--pr-title "${PR_TITLE}" \
--pr-body-base64 "${PR_BODY_B64}" \
--pr-url "${PR_URL}" \
--json-output "${NOTES_JSON}" \
--markdown-output "${NOTES_MARKDOWN}"
- name: Assess documentation impact for branch
id: assessment
env:
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY || secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_MODEL: ${{ vars.LLM_MODEL || secrets.LLM_MODEL || 'openai/gpt-4o-mini' }}
NOTES_JSON: ${{ steps.branch_paths.outputs.notes_json }}
NOTES_MARKDOWN: ${{ steps.branch_paths.outputs.notes_markdown }}
ASSESSMENT_JSON: ${{ steps.branch_paths.outputs.assessment_json }}
ASSESSMENT_MARKDOWN: ${{ steps.branch_paths.outputs.assessment_markdown }}
run: |
uv run python tools/assess_branch_notes.py \
--notes-json "${NOTES_JSON}" \
--notes-markdown "${NOTES_MARKDOWN}" \
--json-output "${ASSESSMENT_JSON}" \
--markdown-output "${ASSESSMENT_MARKDOWN}"
python3 tools/write_docs_assessment_outputs.py \
--assessment-json "${ASSESSMENT_JSON}" \
--branch-slug "${{ matrix.safe_branch }}" \
--short-sha "${{ matrix.short_sha }}" \
--pr-number "${{ matrix.pr_number }}"
- name: Check out docs repository
if: ${{ steps.assessment.outputs.needs_update == 'true' }}
uses: actions/checkout@v6
with:
repository: topoteretes/cognee-docs
token: ${{ secrets.REPO_DISPATCH_PAT_TOKEN }}
ref: main
path: docs-repo
- name: Prepare docs branch
if: ${{ steps.assessment.outputs.needs_update == 'true' }}
working-directory: docs-repo
run: |
git fetch origin "${{ steps.assessment.outputs.docs_branch }}" || true
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
if git show-ref --verify --quiet "refs/remotes/origin/${{ steps.assessment.outputs.docs_branch }}"; then
git checkout -B "${{ steps.assessment.outputs.docs_branch }}" "origin/${{ steps.assessment.outputs.docs_branch }}"
else
git checkout -B "${{ steps.assessment.outputs.docs_branch }}"
fi
- name: Prepare docs edit scope
if: ${{ steps.assessment.outputs.needs_update == 'true' }}
id: docs_scope
env:
GITHUB_TOKEN: ${{ github.token }}
run: |
python3 tools/prepare_docs_edit_scope.py \
--repo "${{ github.repository }}" \
--pr-number "${{ matrix.pr_number }}" \
--docs-root docs-repo \
--notes-json "${{ steps.branch_paths.outputs.notes_json }}" \
--assessment-json "${{ steps.branch_paths.outputs.assessment_json }}" \
--scope-json-output "${{ steps.branch_paths.outputs.docs_edit_scope_json }}" \
--scope-markdown-output "${{ steps.branch_paths.outputs.docs_edit_scope_markdown }}"
- name: Plan docs changes with Claude
if: ${{ steps.assessment.outputs.needs_update == 'true' }}
id: claude_scope
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
prompt: |
Read and follow `.github/prompts/docs_scope_plan.md`.
- Branch: `${{ matrix.branch_name }}`
- PR: `#${{ matrix.pr_number }} ${{ matrix.pr_title }}`
- Merge SHA: `${{ matrix.merge_sha }}`
- Short SHA: `${{ matrix.short_sha }}`
- First parent: `${{ matrix.first_parent }}`
- Second parent: `${{ matrix.second_parent }}`
- Scope plan output: `./${{ steps.branch_paths.outputs.docs_scope_plan }}`
- **Prepared documentation edit scope** (`./${{ steps.branch_paths.outputs.docs_edit_scope_markdown }}`): Curated source files, docs candidates, assessment summary, and out-of-scope files.
- **Prepared documentation edit scope JSON** (`./${{ steps.branch_paths.outputs.docs_edit_scope_json }}`): Machine-readable copy of the prepared scope.
claude_args: "--allowed-tools Read,Write,Glob,Grep --max-turns 35"
- name: Validate docs scope plan
if: ${{ steps.assessment.outputs.needs_update == 'true' }}
run: |
test -s "${{ steps.branch_paths.outputs.docs_scope_plan }}"
if [ -n "$(git -C docs-repo status --short)" ]; then
echo "The docs planning step modified docs-repo, but planning must not edit documentation." >&2
git -C docs-repo status --short >&2
exit 1
fi
- name: Read docs scope plan outputs
if: ${{ steps.assessment.outputs.needs_update == 'true' }}
id: scope_plan
run: |
python3 tools/write_docs_scope_plan_outputs.py \
--scope-plan "${{ steps.branch_paths.outputs.docs_scope_plan }}"
- name: Generate docs changes with Claude
if: ${{ steps.assessment.outputs.needs_update == 'true' && steps.scope_plan.outputs.docs_needed == 'true' }}
id: claude
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
prompt: |
Read and follow `.github/prompts/docs_edit.md`.
- Branch: `${{ matrix.branch_name }}`
- PR: `#${{ matrix.pr_number }} ${{ matrix.pr_title }}`
- Merge SHA: `${{ matrix.merge_sha }}`
- Short SHA: `${{ matrix.short_sha }}`
- First parent: `${{ matrix.first_parent }}`
- Second parent: `${{ matrix.second_parent }}`
## Required inputs
Read these first:
- **Documentation scope plan** (`./${{ steps.branch_paths.outputs.docs_scope_plan }}`)
- **Branch notes** (`./${{ steps.branch_paths.outputs.notes_markdown }}`)
- **Documentation assessment** (`./${{ steps.branch_paths.outputs.assessment_markdown }}`)
claude_args: "--allowed-tools Read,Edit,Write,Glob,Grep,Bash --max-turns 50"
- name: Prepare docs PR content
if: ${{ steps.assessment.outputs.needs_update == 'true' && steps.scope_plan.outputs.docs_needed == 'true' }}
id: pr_content
env:
NOTES_JSON: ${{ steps.branch_paths.outputs.notes_json }}
ASSESSMENT_JSON: ${{ steps.branch_paths.outputs.assessment_json }}
BRANCH_NAME: ${{ matrix.branch_name }}
SHORT_SHA: ${{ matrix.short_sha }}
DEFAULT_PR_TITLE: ${{ steps.assessment.outputs.pr_title }}
run: |
python3 tools/prepare_docs_pr_content.py \
--notes-json "${NOTES_JSON}" \
--assessment-json "${ASSESSMENT_JSON}" \
--branch-name "${BRANCH_NAME}" \
--short-sha "${SHORT_SHA}" \
--default-pr-title "${DEFAULT_PR_TITLE}" \
--docs-root docs-repo
- name: Create docs draft commit
if: ${{ steps.assessment.outputs.needs_update == 'true' && steps.scope_plan.outputs.docs_needed == 'true' }}
id: commit_docs
working-directory: docs-repo
run: |
git add -A
if git diff --cached --quiet; then
echo "changes_made=false" >> "$GITHUB_OUTPUT"
exit 0
fi
git commit -m "${{ steps.pr_content.outputs.pr_title }}"
echo "changes_made=true" >> "$GITHUB_OUTPUT"
- name: Push docs draft branch
if: ${{ steps.assessment.outputs.needs_update == 'true' && steps.scope_plan.outputs.docs_needed == 'true' && steps.commit_docs.outputs.changes_made == 'true' }}
working-directory: docs-repo
run: git push --force-with-lease origin "${{ steps.assessment.outputs.docs_branch }}"
- name: Create or update docs pull request
if: ${{ steps.assessment.outputs.needs_update == 'true' && steps.scope_plan.outputs.docs_needed == 'true' }}
id: manage_pr
env:
GH_TOKEN: ${{ secrets.REPO_DISPATCH_PAT_TOKEN }}
HEAD_BRANCH: ${{ steps.assessment.outputs.docs_branch }}
PR_TITLE: ${{ steps.pr_content.outputs.pr_title }}
PR_BODY: ${{ steps.pr_content.outputs.pr_body }}
CHANGES_MADE: ${{ steps.commit_docs.outputs.changes_made }}
run: |
python3 tools/manage_docs_pr.py \
--target-repo topoteretes/cognee-docs \
--head-branch "${HEAD_BRANCH}" \
--pr-title "${PR_TITLE}" \
--pr-body "${PR_BODY}" \
--changes-made "${CHANGES_MADE}"
- name: Summarize docs PR result
if: ${{ steps.assessment.outputs.needs_update == 'true' && steps.scope_plan.outputs.docs_needed == 'true' }}
env:
CHANGED_FILES: ${{ steps.pr_content.outputs.changed_files }}
run: |
{
echo "## PR docs review: #${{ matrix.pr_number }} ${{ matrix.pr_title }}"
echo
echo "- Branch: \`${{ matrix.branch_name }}\`"
echo "- Merge commit: \`${{ matrix.merge_sha }}\`"
echo "- Needs documentation update: \`${{ steps.assessment.outputs.needs_update }}\`"
if [ "${{ steps.assessment.outputs.needs_update }}" = "true" ]; then
echo "- Docs branch: \`${{ steps.assessment.outputs.docs_branch }}\`"
if [ -n "${CHANGED_FILES}" ]; then
echo "- Updated docs files:"
printf '%s\n' "${CHANGED_FILES}" | while IFS= read -r changed_file; do
[ -n "${changed_file}" ] || continue
echo " - \`${changed_file}\`"
done
else
echo "- Updated docs files: none"
fi
if [ -n "${{ steps.manage_pr.outputs.pr_url }}" ]; then
echo "- Pull request: ${{ steps.manage_pr.outputs.pr_url }}"
else
echo "- Pull request: not created"
fi
fi
echo
echo "### Documentation assessment"
echo
cat "${{ steps.branch_paths.outputs.assessment_markdown }}"
} >> "${GITHUB_STEP_SUMMARY}"
+83
View File
@@ -0,0 +1,83 @@
#!/bin/bash
# Navigate to the workflows directory
cd "$(dirname "$0")"
# List of workflows that should only be triggered via test-suites.yml
WORKFLOWS=(
"test_weaviate.yml"
"test_kuzu.yml"
"test_multimetric_qa_eval_run.yaml"
"test_graphrag_vs_rag_notebook.yml"
"test_llms.yml"
"test_multimedia_example.yaml"
"test_deduplication.yml"
"test_eval_framework.yml"
"test_descriptive_graph_metrics.yml"
"test_llama_index_cognee_integration_notebook.yml"
"test_cognee_llama_index_notebook.yml"
"test_cognee_multimedia_notebook.yml"
"test_cognee_server_start.yml"
"test_telemetry.yml"
"test_neo4j.yml"
"test_pgvector.yml"
"test_ollama.yml"
"test_notebook.yml"
"test_simple_example.yml"
"test_code_graph_example.yml"
)
for workflow in "${WORKFLOWS[@]}"; do
if [ -f "$workflow" ]; then
echo "Processing $workflow..."
# Create a backup
cp "$workflow" "${workflow}.bak"
# Check if the file begins with a workflow_call trigger
if grep -q "workflow_call:" "$workflow"; then
echo "$workflow already has workflow_call trigger, skipping..."
continue
fi
# Get the content after the 'on:' section
on_line=$(grep -n "^on:" "$workflow" | cut -d ':' -f1)
if [ -z "$on_line" ]; then
echo "Warning: No 'on:' section found in $workflow, skipping..."
continue
fi
# Create a new file with the modified content
{
# Copy the part before 'on:'
head -n $((on_line-1)) "$workflow"
# Add the new on: section that only includes workflow_call
echo "on:"
echo " workflow_call:"
echo " secrets:"
echo " inherit: true"
# Find where to continue after the original 'on:' section
next_section=$(awk "NR > $on_line && /^[a-z]/ {print NR; exit}" "$workflow")
if [ -z "$next_section" ]; then
next_section=$(wc -l < "$workflow")
next_section=$((next_section+1))
fi
# Copy the rest of the file starting from the next section
tail -n +$next_section "$workflow"
} > "${workflow}.new"
# Replace the original with the new version
mv "${workflow}.new" "$workflow"
echo "Modified $workflow to only run when called from test-suites.yml"
else
echo "Warning: $workflow not found, skipping..."
fi
done
echo "Finished modifying workflows!"
+81
View File
@@ -0,0 +1,81 @@
name: Distributed Cognee test with modal
permissions:
contents: read
packages: read
on:
workflow_call:
inputs:
python-version:
required: false
type: string
default: '3.13.x'
ci-image:
required: false
type: string
default: ''
secrets:
LLM_MODEL:
required: true
LLM_ENDPOINT:
required: true
LLM_API_KEY:
required: true
LLM_ARGS:
required: false
LLM_API_VERSION:
required: true
EMBEDDING_MODEL:
required: true
EMBEDDING_API_KEY:
required: true
OPENAI_API_KEY:
required: true
env:
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
run-server-start-test:
name: Distributed Cognee test (Modal)
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.13.x'
extra-dependencies: "distributed postgres"
- name: Run Distributed Cognee (Modal)
env:
ENV: 'dev'
ENABLE_BACKEND_ACCESS_CONTROL: 'false'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
MODAL_TOKEN_ID: ${{ secrets.MODAL_TOKEN_ID }}
MODAL_TOKEN_SECRET: ${{ secrets.MODAL_TOKEN_SECRET }}
MODAL_SECRET_NAME: ${{ secrets.MODAL_SECRET_NAME }}
GRAPH_DATABASE_PROVIDER: "neo4j"
GRAPH_DATABASE_URL: ${{ secrets.AZURE_NEO4j_URL }}
GRAPH_DATABASE_USERNAME: ${{ secrets.AZURE_NEO4J_USERNAME }}
GRAPH_DATABASE_PASSWORD: ${{ secrets.AZURE_NEO4J_PW }}
DB_PROVIDER: "postgres"
DB_NAME: ${{ secrets.AZURE_POSTGRES_DB_NAME }}
DB_HOST: ${{ secrets.AZURE_POSTGRES_HOST }}
DB_PORT: ${{ secrets.AZURE_POSTGRES_PORT }}
DB_USERNAME: ${{ secrets.AZURE_POSTGRES_USERNAME }}
DB_PASSWORD: ${{ secrets.AZURE_POSTGRES_PW }}
VECTOR_DB_PROVIDER: "pgvector"
COGNEE_DISTRIBUTED: "true"
run: uv run modal run ./distributed/entrypoint.py
+108
View File
@@ -0,0 +1,108 @@
name: test | docker compose
on:
workflow_call:
env:
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
docker-compose-test:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@master
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build Docker images
env:
ENV: dev
run: |
docker compose -f docker-compose.yml build
- name: Create container .env
# docker-compose.yml bind-mounts ./.env into the container; CI has no
# checked-in .env, so provide the runtime credentials the server needs.
# Secrets flow through the env block so the script body never renders
# secret material (GitHub's log masking then only has exact values to hide).
env:
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: |
printenv | grep -E '^(LLM_|EMBEDDING_)' > .env
echo "EMBEDDING_DIMENSIONS=300" >> .env
echo "COGNEE_SKIP_CONNECTION_TEST=true" >> .env
- name: Run Docker Compose
env:
ENV: dev
run: |
docker compose -f docker-compose.yml up -d
- name: Wait for server health
run: |
for attempt in $(seq 1 60); do
if curl -sf http://localhost:8000/health >/dev/null; then
echo "server healthy after ~$((attempt * 3))s"
exit 0
fi
if [ "$(docker inspect -f '{{.State.Running}}' cognee 2>/dev/null)" != "true" ]; then
echo "cognee container is not running"
docker compose -f docker-compose.yml logs cognee | tail -60
exit 1
fi
sleep 3
done
echo "server did not become healthy in time"
docker compose -f docker-compose.yml logs cognee | tail -60
exit 1
- name: Verify remember and recall round-trip
run: |
TOKEN=$(curl -sf -X POST http://localhost:8000/api/v1/auth/login \
-d "username=default_user@example.com&password=default_password" | jq -r .access_token)
[ -n "$TOKEN" ] && [ "$TOKEN" != "null" ] || { echo "login failed"; exit 1; }
FACT="The glassblower Odene Marsk crafted the twin cobalt lanterns of the Vellinge lighthouse in 1931."
echo "$FACT" > fact.txt
REMEMBERED=$(curl -sf -X POST http://localhost:8000/api/v1/remember \
-H "Authorization: Bearer $TOKEN" \
-F "datasetName=compose_smoke" \
-F "data=@fact.txt;type=text/plain")
echo "$REMEMBERED" | jq -e '.dataset_id != null' >/dev/null \
|| { echo "remember returned no dataset_id"; echo "$REMEMBERED"; exit 1; }
echo "remember: ingested into $(echo "$REMEMBERED" | jq -r .dataset_id)"
# Deterministic check: CHUNKS recall returns the raw stored text, no
# LLM involved — the full stored fact must come back verbatim.
CHUNKS=$(curl -sf -X POST http://localhost:8000/api/v1/recall \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"query":"cobalt lanterns lighthouse","searchType":"CHUNKS","datasets":["compose_smoke"]}')
echo "$CHUNKS" | grep -qF "$FACT" || { echo "CHUNKS recall missing stored fact"; echo "$CHUNKS"; exit 1; }
echo "recall (CHUNKS): stored fact retrieved verbatim"
# End-to-end answer check: the graph-grounded completion must name the entity.
ANSWER=$(curl -sf -X POST http://localhost:8000/api/v1/recall \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"query":"Who crafted the twin cobalt lanterns of the Vellinge lighthouse, and in which year?","searchType":"GRAPH_COMPLETION","datasets":["compose_smoke"]}')
echo "recall (GRAPH_COMPLETION): $ANSWER"
echo "$ANSWER" | grep -qi "Marsk" || { echo "graph completion did not mention the remembered entity"; exit 1; }
- name: Show server logs on failure
if: failure()
# Filter key-shaped lines: GitHub masks exact secret values, but partial
# or transformed echoes (e.g. provider auth errors) would slip through.
run: docker compose -f docker-compose.yml logs cognee | grep -viE "api[-_]?key|authorization|bearer" | tail -100
- name: Shut down Docker Compose
if: always()
run: |
docker compose -f docker-compose.yml down
+65
View File
@@ -0,0 +1,65 @@
name: build | Build and Push Cognee MCP Docker Image to dockerhub
on:
push:
branches:
- main
jobs:
docker-build-and-push:
runs-on:
group: Default
labels:
- docker_build_runner
steps:
- name: Check and free disk space before build
run: |
echo "=== Before cleanup ==="
df -h
echo "Removing unused preinstalled SDKs to free space..."
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc || true
docker system prune -af || true
echo "=== After cleanup ==="
df -h
- name: Checkout repository
uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
buildkitd-flags: --root /tmp/buildkit
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: cognee/cognee-mcp
tags: |
type=ref,event=branch
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push
id: build
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
file: cognee-mcp/Dockerfile
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=cognee/cognee-mcp:buildcache
cache-to: type=registry,ref=cognee/cognee-mcp:buildcache,mode=max
- name: Image digest
run: echo ${{ steps.build.outputs.digest }}
+48
View File
@@ -0,0 +1,48 @@
name: build | Build and Push Docker Image to dockerhub
on:
push:
branches:
- main
jobs:
docker-build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: cognee/cognee
tags: |
type=ref,event=branch
type=sha,prefix={{branch}}-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push
id: build
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=cognee/cognee:buildcache
cache-to: type=registry,ref=cognee/cognee:buildcache,mode=max
- name: Image digest
run: echo ${{ steps.build.outputs.digest }}
File diff suppressed because it is too large Load Diff
+384
View File
@@ -0,0 +1,384 @@
name: Reusable Examples Tests
permissions:
contents: read
packages: read
on:
workflow_call:
inputs:
ci-image:
required: false
type: string
default: ''
env:
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
test-multimedia-example:
name: Run Multimedia Example
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
- name: Run Multimedia Example
env:
ENV: 'dev'
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: uv run python ./examples/demos/multimedia_processing/multimedia_audio_image_processing_example.py
test-eval-example:
name: Run Eval Example
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
extra-dependencies: "deepeval"
- name: Run Evaluation Framework Example
env:
ENV: 'dev'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./cognee/eval_framework/run_eval.py
test-descriptive-metrics:
name: Run Descriptive Metrics Example
runs-on: ubuntu-22.04
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
- name: Setup Neo4j with GDS
uses: ./.github/actions/setup_neo4j
id: neo4j
- name: Run Descriptive Graph Metrics Example
env:
ENV: 'dev'
ENABLE_BACKEND_ACCESS_CONTROL: 'false'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
GRAPH_DATABASE_PROVIDER: "neo4j"
GRAPH_DATABASE_URL: ${{ steps.neo4j.outputs.neo4j-url }}
GRAPH_DATABASE_USERNAME: ${{ steps.neo4j.outputs.neo4j-username }}
GRAPH_DATABASE_PASSWORD: ${{ steps.neo4j.outputs.neo4j-password }}
run: uv run python ./cognee/tests/tasks/descriptive_metrics/neo4j_metrics_test.py
test-temporal-example:
name: Run Temporal Tests
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
- name: Run Temporal Example
env:
ENV: 'dev'
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./examples/demos/temporal_awareness_example/temporal_awareness_example.py
test-ontology-example:
name: Run Ontology Tests
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
- name: Run Ontology Demo Example
env:
ENV: 'dev'
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./examples/demos/ontology_reference_vocabulary/ontology_as_reference_vocabulary_example.py
test-feedback-score-shifting-example:
name: Run Feedback Score Shifting Example
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
- name: Run Feedback Score Shifting Example
env:
ENV: 'dev'
CACHING: 'true'
CACHE_BACKEND: 'fs'
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./examples/demos/feedback_score_shifting_example.py
test-agentic-reasoning:
name: Run Agentic Reasoning Tests
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
- name: Run Agentic Reasoning Example
env:
ENV: 'dev'
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./examples/custom_pipelines/agentic_reasoning_procurement_example.py
test-memify:
name: Run Memify Example
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
- name: Run Memify Tests
env:
ENV: 'dev'
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./examples/custom_pipelines/memify_coding_agent_rule_extraction_example.py
test-custom-pipeline:
name: Run Custom Pipeline Example
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
- name: Run Custom Pipeline Example
env:
ENV: 'dev'
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./examples/custom_pipelines/custom_cognify_pipeline_example.py
test-permissions-example:
name: Run Permissions Example
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
- name: Run Permissions Example
env:
ENV: 'dev'
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./examples/configurations/permissions_example/user_permissions_and_access_control_example.py
test-s3-permissions-example: # Make sure permission and multi-user mode work with S3 file system
name: Run Permissions Example
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
defaults:
run:
shell: bash
services:
postgres: # Using postgres to avoid storing and using SQLite from S3
image: ghcr.io/topoteretes/pgvector:pg17
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
POSTGRES_USER: cognee
POSTGRES_PASSWORD: cognee
POSTGRES_DB: cognee_db
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
extra-dependencies: "postgres aws"
- name: Run S3 Permissions Example
env:
ENV: 'dev'
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
STORAGE_BACKEND: 's3'
AWS_REGION: eu-west-1
AWS_ENDPOINT_URL: https://s3-eu-west-1.amazonaws.com
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_S3_DEV_USER_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_S3_DEV_USER_SECRET_KEY }}
STORAGE_BUCKET_NAME: github-runner-cognee-tests
DATA_ROOT_DIRECTORY: "s3://github-runner-cognee-tests/cognee/data"
SYSTEM_ROOT_DIRECTORY: "s3://github-runner-cognee-tests/cognee/system"
DB_PROVIDER: 'postgres'
DB_NAME: 'cognee_db'
DB_HOST: ${{ inputs.ci-image != '' && 'postgres' || '127.0.0.1' }}
DB_PORT: 5432
DB_USERNAME: cognee
DB_PASSWORD: cognee
run: uv run python ./examples/configurations/permissions_example/user_permissions_and_access_control_example.py
# Docling test - NO container (runs on macOS, container only works on Linux)
test_docling_add:
name: Run Add with Docling Test
runs-on: macos-15
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
extra-dependencies: 'docling'
- name: Run Docling Test
env:
ENV: 'dev'
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: |
uv sync --extra docling
uv run python ./cognee/tests/test_add_docling_document.py
+225
View File
@@ -0,0 +1,225 @@
name: Reusable Graph DB Tests
permissions:
contents: read
packages: read
on:
workflow_call:
inputs:
databases:
required: false
type: string
default: "all"
description: "Which vector databases to test (comma-separated list or 'all')"
python-version:
required: false
type: string
default: "3.11.x"
description: "Python version to use for testing"
ci-image:
required: false
type: string
default: ''
env:
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
run-kuzu-tests:
name: Kuzu Tests
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'kuzu') }}
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
- name: Dependencies already installed
run: echo "Dependencies already installed in setup"
- name: Run Kuzu Tests
env:
ENV: 'dev'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./cognee/tests/test_kuzu.py
- name: Run Weighted Edges Tests with Kuzu
env:
ENV: 'dev'
GRAPH_DATABASE_PROVIDER: "kuzu"
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run pytest cognee/tests/unit/interfaces/graph/test_weighted_edges.py -v
run-postgres-tests:
name: Postgres Graph Tests
runs-on: ubuntu-22.04
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'postgres') }}
services:
postgres:
image: ghcr.io/topoteretes/pgvector:pg17
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
POSTGRES_USER: cognee
POSTGRES_PASSWORD: cognee
POSTGRES_DB: cognee_db
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
extra-dependencies: postgres
- name: Run Postgres Adapter Unit Tests
env:
DB_PROVIDER: postgres
DB_HOST: localhost
DB_PORT: 5432
DB_USERNAME: cognee
DB_PASSWORD: cognee
DB_NAME: cognee_db
run: uv run pytest cognee/tests/e2e/postgres/test_postgres_adapter.py -v
- name: Run Postgres Graph E2E Test
env:
ENV: 'dev'
GRAPH_DATABASE_PROVIDER: "postgres"
GRAPH_DATABASE_URL: "postgresql+asyncpg://cognee:cognee@localhost:5432/cognee_db"
DB_PROVIDER: postgres
DB_HOST: localhost
DB_PORT: 5432
DB_USERNAME: cognee
DB_PASSWORD: cognee
DB_NAME: cognee_db
ENABLE_BACKEND_ACCESS_CONTROL: 'false'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./cognee/tests/e2e/postgres/test_graphdb_postgres.py
# - name: Run Postgres Hybrid Adapter Tests
# env:
# ENV: 'dev'
# DB_PROVIDER: postgres
# DB_HOST: localhost
# DB_PORT: 5432
# DB_USERNAME: cognee
# DB_PASSWORD: cognee
# DB_NAME: cognee_db
# EMBEDDING_DIMENSIONS: 300
# EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
# EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
# run: uv run pytest cognee/tests/e2e/postgres/test_postgres_hybrid_adapter.py -v
#
# - name: Run Postgres Hybrid E2E Test
# env:
# ENV: 'dev'
# USE_UNIFIED_PROVIDER: "pghybrid"
# DB_PROVIDER: postgres
# DB_HOST: localhost
# DB_PORT: 5432
# DB_USERNAME: cognee
# DB_PASSWORD: cognee
# DB_NAME: cognee_db
# ENABLE_BACKEND_ACCESS_CONTROL: 'false'
# LLM_MODEL: ${{ secrets.LLM_MODEL }}
# LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
# LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
# LLM_ARGS: ${{ secrets.LLM_ARGS }}
# LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
# EMBEDDING_DIMENSIONS: 300
# EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
# EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
# run: uv run python ./cognee/tests/e2e/postgres/test_pghybrid.py
run-neo4j-tests:
name: Neo4j Tests
runs-on: ubuntu-22.04
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'neo4j') }}
steps:
- name: Check out
uses: actions/checkout@master
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
- name: Setup Neo4j with GDS
uses: ./.github/actions/setup_neo4j
id: neo4j
- name: Run default Neo4j
env:
ENV: 'dev'
ENABLE_BACKEND_ACCESS_CONTROL: 'false'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
GRAPH_DATABASE_PROVIDER: "neo4j"
GRAPH_DATABASE_URL: ${{ steps.neo4j.outputs.neo4j-url }}
GRAPH_DATABASE_USERNAME: ${{ steps.neo4j.outputs.neo4j-username }}
GRAPH_DATABASE_PASSWORD: ${{ steps.neo4j.outputs.neo4j-password }}
run: uv run python ./cognee/tests/test_neo4j.py
- name: Run Weighted Edges Tests with Neo4j
env:
ENV: 'dev'
GRAPH_DATABASE_PROVIDER: "neo4j"
GRAPH_DATABASE_URL: ${{ secrets.NEO4J_API_URL }}
GRAPH_DATABASE_PASSWORD: ${{ secrets.NEO4J_API_KEY }}
GRAPH_DATABASE_USERNAME: "neo4j"
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run pytest cognee/tests/unit/interfaces/graph/test_weighted_edges.py -v
+192
View File
@@ -0,0 +1,192 @@
name: Reusable Integration Tests
permissions:
contents: read
packages: read
on:
workflow_call:
inputs:
ci-image:
required: false
type: string
default: ''
env:
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
integration-retrieval:
name: Integration - Retrieval (${{ matrix.split-group }}/4)
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
split-group: [1, 2, 3, 4]
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
env:
ENV: 'dev'
LLM_PROVIDER: openai
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
extra-dependencies: "scraping fastembed"
- name: Run Retrieval Tests
run: uv run pytest cognee/tests/integration/retrieval/ --splits 4 --group ${{ matrix.split-group }}
integration-documents-tasks:
name: Integration - Documents & Tasks (${{ matrix.split-group }}/2)
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
split-group: [1, 2]
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
env:
ENV: 'dev'
LLM_PROVIDER: openai
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
extra-dependencies: "scraping"
- name: Run Document & Task Tests
run: uv run pytest cognee/tests/integration/documents/ cognee/tests/integration/tasks/ --splits 2 --group ${{ matrix.split-group }}
integration-infra:
name: Integration - Infrastructure (${{ matrix.split-group }}/3)
runs-on: ubuntu-22.04
strategy:
fail-fast: false
matrix:
split-group: [1, 2, 3]
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
env:
ENV: 'dev'
LLM_PROVIDER: openai
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
# fastembed so the embedding tokenizer delegation tests can import
# FastembedEmbeddingEngine.
extra-dependencies: "scraping fastembed"
- name: Run Infrastructure Tests
run: uv run pytest cognee/tests/integration/infrastructure/ --splits 3 --group ${{ matrix.split-group }}
integration-web:
name: Integration - Web
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
env:
ENV: 'dev'
LLM_PROVIDER: openai
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
extra-dependencies: "scraping"
- name: Run Web Integration Tests
run: uv run pytest cognee/tests/integration/web_url_crawler/
integration-other:
name: Integration - Deletion & Misc
runs-on: ubuntu-22.04
services:
redis:
image: redis:7
ports:
- 6379:6379
options: >-
--health-cmd "redis-cli ping"
--health-interval 5s
--health-timeout 3s
--health-retries 5
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
env:
ENV: 'dev'
LLM_PROVIDER: openai
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
CACHE_HOST: redis
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
extra-dependencies: "scraping redis"
- name: Run Deletion & Misc Tests
run: uv run pytest cognee/tests/integration/test_delete_edge_cases.py cognee/tests/integration/shared/
+74
View File
@@ -0,0 +1,74 @@
name: Label PRs from core team
on:
pull_request_target:
types: [opened, reopened, synchronize, ready_for_review, edited]
permissions:
contents: read
issues: write
jobs:
label-core-team:
if: ${{ !github.event.pull_request.draft }}
runs-on: ubuntu-latest
steps:
- name: Check out base repository
uses: actions/checkout@v6
with:
repository: ${{ github.repository }}
ref: ${{ github.event.pull_request.base.ref }}
- name: Determine if PR author is a core team member
id: check_core
shell: bash
run: |
AUTHOR="${{ github.event.pull_request.user.login }}"
LIST_FILE=".github/core-team.txt"
if [ ! -f "$LIST_FILE" ]; then
echo "core=false" >> "$GITHUB_OUTPUT"
exit 0
fi
# Normalize author to lowercase and strip leading '@'
AUTHOR_NORM="$(echo "$AUTHOR" | tr '[:upper:]' '[:lower:]' | sed 's/^@//')"
# Compare against normalized list values (ignore comments/blank lines)
if awk -v author="$AUTHOR_NORM" '
BEGIN { found=0 }
{
line=$0
sub(/^[ \t]+|[ \t]+$/, "", line)
if (line ~ /^#/ || line == "") next
sub(/^@/, "", line)
line=tolower(line)
if (line == author) { found=1; exit }
}
END { exit(found ? 0 : 1) }
' "$LIST_FILE"; then
echo "core=true" >> "$GITHUB_OUTPUT"
else
echo "core=false" >> "$GITHUB_OUTPUT"
fi
- name: Add core-team label
if: steps.check_core.outputs.core == 'true'
uses: actions/github-script@v8
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const label = 'core-team';
const { owner, repo } = context.repo;
const prNumber = context.payload.pull_request.number;
try {
await github.rest.issues.addLabels({
owner,
repo,
issue_number: prNumber,
labels: [label],
});
core.info(`Label '${label}' added to PR #${prNumber}`);
} catch (error) {
core.warning(`Failed to add label: ${error.message}`);
}
+73
View File
@@ -0,0 +1,73 @@
name: Load tests
permissions:
contents: read
packages: read
on:
workflow_dispatch:
workflow_call:
inputs:
ci-image:
required: false
type: string
default: ''
secrets:
LLM_MODEL:
required: true
LLM_ENDPOINT:
required: true
LLM_API_KEY:
required: true
LLM_ARGS:
required: false
LLM_API_VERSION:
required: true
EMBEDDING_MODEL:
required: true
EMBEDDING_API_KEY:
required: true
OPENAI_API_KEY:
required: true
AWS_ACCESS_KEY_ID:
required: true
AWS_SECRET_ACCESS_KEY:
required: true
jobs:
test-load:
name: Test Load
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
timeout-minutes: 60
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
extra-dependencies: "aws"
- name: Verify File Descriptor Limit
run: ulimit -n
- name: Run Load Test
env:
ENV: 'dev'
ENABLE_BACKEND_ACCESS_CONTROL: True
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
STORAGE_BACKEND: s3
AWS_REGION: eu-west-1
AWS_ENDPOINT_URL: https://s3-eu-west-1.amazonaws.com
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_S3_DEV_USER_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_S3_DEV_USER_SECRET_KEY }}
run: uv run python ./cognee/tests/test_load.py
+54
View File
@@ -0,0 +1,54 @@
name: Mirror external images to GHCR
# Copies the pinned third-party images CI depends on (pgvector) into GHCR, so the
# PR / test hot path never pulls from Docker Hub — which is rate-limited and flaky
# from GitHub Actions (intermittent `registry-1.docker.io ... timeout` on service
# container setup). The test workflows reference ghcr.io/<owner>/pgvector:pg17.
#
# Runs weekly for freshness and on-demand. IMPORTANT: run this once (Actions ->
# "Mirror external images to GHCR" -> Run workflow) BEFORE the GHCR references go
# live, so the image exists. Ensure the resulting GHCR package is accessible to
# this repo (public, or repo-linked) so service pulls with GITHUB_TOKEN succeed.
on:
schedule:
- cron: "0 6 * * 1" # Mondays 06:00 UTC
workflow_dispatch: {}
permissions:
contents: read
packages: write
jobs:
mirror:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
image:
- pgvector/pgvector:pg17
steps:
- name: Log in to Docker Hub (authenticated source pulls)
uses: docker/login-action@v3
continue-on-error: true # best-effort: fall back to anonymous if unset
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Mirror ${{ matrix.image }} -> GHCR
run: |
set -euo pipefail
SRC="${{ matrix.image }}"
DST="ghcr.io/${{ github.repository_owner }}/${SRC##*/}"
echo "Mirroring $SRC -> $DST"
docker pull "$SRC"
docker tag "$SRC" "$DST"
docker push "$DST"
echo "Done: $DST"
+246
View File
@@ -0,0 +1,246 @@
name: Nightly Tests
permissions:
contents: read
packages: write
on:
schedule:
- cron: '0 3 * * *'
workflow_dispatch:
# Note: Run Nightly CI on change to any of the following files.
pull_request:
paths:
- '.github/workflows/nightly_tests.yml'
- '.github/workflows/performance_report.yml'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
RUNTIME__LOG_LEVEL: ERROR
ENV: 'dev'
jobs:
ollama-tests:
name: Ollama Tests
uses: ./.github/workflows/test_ollama.yml
secrets: inherit
llamacpp-tests:
name: Llama-cpp Tests
uses: ./.github/workflows/test_llamacpp.yml
secrets: inherit
# ══ Performance: each caller runs BOTH file_based and postgres backends ════
perf-small-llm:
name: Performance — 50 Small Documents (real LLM)
uses: ./.github/workflows/performance_report.yml
with:
mode: llm
label: 50_small_documents
runs: '3'
num_memories: '50'
memories_key: nightly_ci_artifacts/performance_test_artifacts/memories.json
secrets: inherit
perf-small-mock:
name: Performance — 50 Small Documents (mock LLM)
uses: ./.github/workflows/performance_report.yml
with:
mode: mock_llm
label: 50_small_documents
runs: '3'
num_memories: '50'
memories_key: nightly_ci_artifacts/performance_test_artifacts/memories.json
mock_memories_key: nightly_ci_artifacts/performance_test_artifacts/mock_memories.json
secrets: inherit
perf-wap-llm:
name: Performance — War and Peace (real LLM)
uses: ./.github/workflows/performance_report.yml
with:
mode: llm
label: war_and_peace
runs: '3'
memories_key: nightly_ci_artifacts/performance_test_artifacts/war_and_peace.json
secrets: inherit
perf-wap-mock:
name: Performance — War and Peace (mock LLM)
uses: ./.github/workflows/performance_report.yml
with:
mode: mock_llm
label: war_and_peace
runs: '3'
memories_key: nightly_ci_artifacts/performance_test_artifacts/war_and_peace.json
mock_memories_key: nightly_ci_artifacts/performance_test_artifacts/mock_war_and_peace.json
secrets: inherit
notify:
name: Test Completion Status
needs: [
ollama-tests,
llamacpp-tests,
perf-small-llm,
perf-small-mock,
perf-wap-llm,
perf-wap-mock,
]
runs-on: ubuntu-latest
if: ${{ !cancelled() }}
steps:
- name: Determine status
id: status
run: |
if [[ "${{ needs.ollama-tests.result }}" == "success" &&
"${{ needs.llamacpp-tests.result }}" == "success" &&
"${{ needs.perf-small-llm.result }}" == "success" &&
"${{ needs.perf-small-mock.result }}" == "success" &&
"${{ needs.perf-wap-llm.result }}" == "success" &&
"${{ needs.perf-wap-mock.result }}" == "success" ]]; then
echo "passed=true" >> "$GITHUB_OUTPUT"
echo "emoji=✅" >> "$GITHUB_OUTPUT"
echo "summary=All nightly test suites completed successfully!" >> "$GITHUB_OUTPUT"
else
echo "passed=false" >> "$GITHUB_OUTPUT"
echo "emoji=❌" >> "$GITHUB_OUTPUT"
echo "summary=One or more nightly test suites failed." >> "$GITHUB_OUTPUT"
fi
echo "ran_at=$(date -u '+%Y-%m-%d %H:%M UTC')" >> "$GITHUB_OUTPUT"
- name: Presign performance report links
id: presign
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_S3_DEV_USER_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_S3_DEV_USER_SECRET_KEY }}
AWS_DEFAULT_REGION: eu-west-1
BUCKET: github-runner-cognee-tests
# "<slack-output-name> <s3-key>" per line. The key already encodes the
# backend (file_based/ or postgres/), so presigning is fully generic.
REPORT_KEYS: |
url_file_small_llm ${{ needs.perf-small-llm.outputs.file_based_html_key }}
url_file_small_mock ${{ needs.perf-small-mock.outputs.file_based_html_key }}
url_file_wap_llm ${{ needs.perf-wap-llm.outputs.file_based_html_key }}
url_file_wap_mock ${{ needs.perf-wap-mock.outputs.file_based_html_key }}
url_pg_small_llm ${{ needs.perf-small-llm.outputs.postgres_html_key }}
url_pg_small_mock ${{ needs.perf-small-mock.outputs.postgres_html_key }}
url_pg_wap_llm ${{ needs.perf-wap-llm.outputs.postgres_html_key }}
url_pg_wap_mock ${{ needs.perf-wap-mock.outputs.postgres_html_key }}
run: |
set -euo pipefail
# 7 days = 604800s is the maximum lifetime for an IAM-user presigned URL.
# Skip empty keys (a failed perf job produces no report).
while read -r name key; do
[ -n "${key:-}" ] || continue
echo "$name=$(aws s3 presign "s3://$BUCKET/$key" --expires-in 604800)" >> "$GITHUB_OUTPUT"
done <<< "$REPORT_KEYS"
- name: Post status to Slack
uses: slackapi/slack-github-action@v2.1.0
with:
method: chat.postMessage
token: ${{ secrets.SLACK_NIGHTLY_BOT_TOKEN }}
payload: |
channel: ${{ secrets.SLACK_NIGHTLY_CHANNEL_ID }}
text: "${{ steps.status.outputs.emoji }} Nightly Tests (${{ steps.status.outputs.ran_at }}): ${{ steps.status.outputs.summary }}"
blocks:
- type: "section"
text:
type: "mrkdwn"
text: |
${{ steps.status.outputs.emoji }} *Nightly Tests* — ${{ steps.status.outputs.summary }}
*Ran at:* `${{ steps.status.outputs.ran_at }}`
*Ollama:* `${{ needs.ollama-tests.result }}` • *Llama-cpp:* `${{ needs.llamacpp-tests.result }}`
- type: "section"
text:
type: "mrkdwn"
text: |
*📊 File Based — 50 Small Documents — Real LLM* (`${{ needs.perf-small-llm.result }}`) • runs `${{ fromJSON(needs.perf-small-llm.outputs.file_based_metrics || '{}').success }}`
add p50 `${{ fromJSON(needs.perf-small-llm.outputs.file_based_metrics || '{}').add.p50 }}s` • p90 `${{ fromJSON(needs.perf-small-llm.outputs.file_based_metrics || '{}').add.p90 }}s` • p99 `${{ fromJSON(needs.perf-small-llm.outputs.file_based_metrics || '{}').add.p99 }}s`
cognify p50 `${{ fromJSON(needs.perf-small-llm.outputs.file_based_metrics || '{}').cognify.p50 }}s` • p90 `${{ fromJSON(needs.perf-small-llm.outputs.file_based_metrics || '{}').cognify.p90 }}s` • p99 `${{ fromJSON(needs.perf-small-llm.outputs.file_based_metrics || '{}').cognify.p99 }}s`
search p50 `${{ fromJSON(needs.perf-small-llm.outputs.file_based_metrics || '{}').search.p50 }}s` • p90 `${{ fromJSON(needs.perf-small-llm.outputs.file_based_metrics || '{}').search.p90 }}s` • p99 `${{ fromJSON(needs.perf-small-llm.outputs.file_based_metrics || '{}').search.p99 }}s`
total p50 `${{ fromJSON(needs.perf-small-llm.outputs.file_based_metrics || '{}').total.p50 }}s` • p90 `${{ fromJSON(needs.perf-small-llm.outputs.file_based_metrics || '{}').total.p90 }}s` • p99 `${{ fromJSON(needs.perf-small-llm.outputs.file_based_metrics || '{}').total.p99 }}s`
<${{ steps.presign.outputs.url_file_small_llm }}|HTML report>
- type: "section"
text:
type: "mrkdwn"
text: |
*📊 File Based — 50 Small Documents — Mock LLM* (`${{ needs.perf-small-mock.result }}`) • runs `${{ fromJSON(needs.perf-small-mock.outputs.file_based_metrics || '{}').success }}`
add p50 `${{ fromJSON(needs.perf-small-mock.outputs.file_based_metrics || '{}').add.p50 }}s` • p90 `${{ fromJSON(needs.perf-small-mock.outputs.file_based_metrics || '{}').add.p90 }}s` • p99 `${{ fromJSON(needs.perf-small-mock.outputs.file_based_metrics || '{}').add.p99 }}s`
cognify p50 `${{ fromJSON(needs.perf-small-mock.outputs.file_based_metrics || '{}').cognify.p50 }}s` • p90 `${{ fromJSON(needs.perf-small-mock.outputs.file_based_metrics || '{}').cognify.p90 }}s` • p99 `${{ fromJSON(needs.perf-small-mock.outputs.file_based_metrics || '{}').cognify.p99 }}s`
search p50 `${{ fromJSON(needs.perf-small-mock.outputs.file_based_metrics || '{}').search.p50 }}s` • p90 `${{ fromJSON(needs.perf-small-mock.outputs.file_based_metrics || '{}').search.p90 }}s` • p99 `${{ fromJSON(needs.perf-small-mock.outputs.file_based_metrics || '{}').search.p99 }}s`
total p50 `${{ fromJSON(needs.perf-small-mock.outputs.file_based_metrics || '{}').total.p50 }}s` • p90 `${{ fromJSON(needs.perf-small-mock.outputs.file_based_metrics || '{}').total.p90 }}s` • p99 `${{ fromJSON(needs.perf-small-mock.outputs.file_based_metrics || '{}').total.p99 }}s`
<${{ steps.presign.outputs.url_file_small_mock }}|HTML report>
- type: "section"
text:
type: "mrkdwn"
text: |
*📚 File Based — War and Peace — Real LLM* (`${{ needs.perf-wap-llm.result }}`) • runs `${{ fromJSON(needs.perf-wap-llm.outputs.file_based_metrics || '{}').success }}`
add p50 `${{ fromJSON(needs.perf-wap-llm.outputs.file_based_metrics || '{}').add.p50 }}s` • p90 `${{ fromJSON(needs.perf-wap-llm.outputs.file_based_metrics || '{}').add.p90 }}s` • p99 `${{ fromJSON(needs.perf-wap-llm.outputs.file_based_metrics || '{}').add.p99 }}s`
cognify p50 `${{ fromJSON(needs.perf-wap-llm.outputs.file_based_metrics || '{}').cognify.p50 }}s` • p90 `${{ fromJSON(needs.perf-wap-llm.outputs.file_based_metrics || '{}').cognify.p90 }}s` • p99 `${{ fromJSON(needs.perf-wap-llm.outputs.file_based_metrics || '{}').cognify.p99 }}s`
search p50 `${{ fromJSON(needs.perf-wap-llm.outputs.file_based_metrics || '{}').search.p50 }}s` • p90 `${{ fromJSON(needs.perf-wap-llm.outputs.file_based_metrics || '{}').search.p90 }}s` • p99 `${{ fromJSON(needs.perf-wap-llm.outputs.file_based_metrics || '{}').search.p99 }}s`
total p50 `${{ fromJSON(needs.perf-wap-llm.outputs.file_based_metrics || '{}').total.p50 }}s` • p90 `${{ fromJSON(needs.perf-wap-llm.outputs.file_based_metrics || '{}').total.p90 }}s` • p99 `${{ fromJSON(needs.perf-wap-llm.outputs.file_based_metrics || '{}').total.p99 }}s`
<${{ steps.presign.outputs.url_file_wap_llm }}|HTML report>
- type: "section"
text:
type: "mrkdwn"
text: |
*📚 File Based — War and Peace — Mock LLM* (`${{ needs.perf-wap-mock.result }}`) • runs `${{ fromJSON(needs.perf-wap-mock.outputs.file_based_metrics || '{}').success }}`
add p50 `${{ fromJSON(needs.perf-wap-mock.outputs.file_based_metrics || '{}').add.p50 }}s` • p90 `${{ fromJSON(needs.perf-wap-mock.outputs.file_based_metrics || '{}').add.p90 }}s` • p99 `${{ fromJSON(needs.perf-wap-mock.outputs.file_based_metrics || '{}').add.p99 }}s`
cognify p50 `${{ fromJSON(needs.perf-wap-mock.outputs.file_based_metrics || '{}').cognify.p50 }}s` • p90 `${{ fromJSON(needs.perf-wap-mock.outputs.file_based_metrics || '{}').cognify.p90 }}s` • p99 `${{ fromJSON(needs.perf-wap-mock.outputs.file_based_metrics || '{}').cognify.p99 }}s`
search p50 `${{ fromJSON(needs.perf-wap-mock.outputs.file_based_metrics || '{}').search.p50 }}s` • p90 `${{ fromJSON(needs.perf-wap-mock.outputs.file_based_metrics || '{}').search.p90 }}s` • p99 `${{ fromJSON(needs.perf-wap-mock.outputs.file_based_metrics || '{}').search.p99 }}s`
total p50 `${{ fromJSON(needs.perf-wap-mock.outputs.file_based_metrics || '{}').total.p50 }}s` • p90 `${{ fromJSON(needs.perf-wap-mock.outputs.file_based_metrics || '{}').total.p90 }}s` • p99 `${{ fromJSON(needs.perf-wap-mock.outputs.file_based_metrics || '{}').total.p99 }}s`
<${{ steps.presign.outputs.url_file_wap_mock }}|HTML report>
- type: "section"
text:
type: "mrkdwn"
text: |
*📊 Full Postgres — 50 Small Documents — Real LLM* (`${{ needs.perf-small-llm.result }}`) • runs `${{ fromJSON(needs.perf-small-llm.outputs.postgres_metrics || '{}').success }}`
add p50 `${{ fromJSON(needs.perf-small-llm.outputs.postgres_metrics || '{}').add.p50 }}s` • p90 `${{ fromJSON(needs.perf-small-llm.outputs.postgres_metrics || '{}').add.p90 }}s` • p99 `${{ fromJSON(needs.perf-small-llm.outputs.postgres_metrics || '{}').add.p99 }}s`
cognify p50 `${{ fromJSON(needs.perf-small-llm.outputs.postgres_metrics || '{}').cognify.p50 }}s` • p90 `${{ fromJSON(needs.perf-small-llm.outputs.postgres_metrics || '{}').cognify.p90 }}s` • p99 `${{ fromJSON(needs.perf-small-llm.outputs.postgres_metrics || '{}').cognify.p99 }}s`
search p50 `${{ fromJSON(needs.perf-small-llm.outputs.postgres_metrics || '{}').search.p50 }}s` • p90 `${{ fromJSON(needs.perf-small-llm.outputs.postgres_metrics || '{}').search.p90 }}s` • p99 `${{ fromJSON(needs.perf-small-llm.outputs.postgres_metrics || '{}').search.p99 }}s`
total p50 `${{ fromJSON(needs.perf-small-llm.outputs.postgres_metrics || '{}').total.p50 }}s` • p90 `${{ fromJSON(needs.perf-small-llm.outputs.postgres_metrics || '{}').total.p90 }}s` • p99 `${{ fromJSON(needs.perf-small-llm.outputs.postgres_metrics || '{}').total.p99 }}s`
<${{ steps.presign.outputs.url_pg_small_llm }}|HTML report>
- type: "section"
text:
type: "mrkdwn"
text: |
*📊 Full Postgres — 50 Small Documents — Mock LLM* (`${{ needs.perf-small-mock.result }}`) • runs `${{ fromJSON(needs.perf-small-mock.outputs.postgres_metrics || '{}').success }}`
add p50 `${{ fromJSON(needs.perf-small-mock.outputs.postgres_metrics || '{}').add.p50 }}s` • p90 `${{ fromJSON(needs.perf-small-mock.outputs.postgres_metrics || '{}').add.p90 }}s` • p99 `${{ fromJSON(needs.perf-small-mock.outputs.postgres_metrics || '{}').add.p99 }}s`
cognify p50 `${{ fromJSON(needs.perf-small-mock.outputs.postgres_metrics || '{}').cognify.p50 }}s` • p90 `${{ fromJSON(needs.perf-small-mock.outputs.postgres_metrics || '{}').cognify.p90 }}s` • p99 `${{ fromJSON(needs.perf-small-mock.outputs.postgres_metrics || '{}').cognify.p99 }}s`
search p50 `${{ fromJSON(needs.perf-small-mock.outputs.postgres_metrics || '{}').search.p50 }}s` • p90 `${{ fromJSON(needs.perf-small-mock.outputs.postgres_metrics || '{}').search.p90 }}s` • p99 `${{ fromJSON(needs.perf-small-mock.outputs.postgres_metrics || '{}').search.p99 }}s`
total p50 `${{ fromJSON(needs.perf-small-mock.outputs.postgres_metrics || '{}').total.p50 }}s` • p90 `${{ fromJSON(needs.perf-small-mock.outputs.postgres_metrics || '{}').total.p90 }}s` • p99 `${{ fromJSON(needs.perf-small-mock.outputs.postgres_metrics || '{}').total.p99 }}s`
<${{ steps.presign.outputs.url_pg_small_mock }}|HTML report>
- type: "section"
text:
type: "mrkdwn"
text: |
*📚 Full Postgres — War and Peace — Real LLM* (`${{ needs.perf-wap-llm.result }}`) • runs `${{ fromJSON(needs.perf-wap-llm.outputs.postgres_metrics || '{}').success }}`
add p50 `${{ fromJSON(needs.perf-wap-llm.outputs.postgres_metrics || '{}').add.p50 }}s` • p90 `${{ fromJSON(needs.perf-wap-llm.outputs.postgres_metrics || '{}').add.p90 }}s` • p99 `${{ fromJSON(needs.perf-wap-llm.outputs.postgres_metrics || '{}').add.p99 }}s`
cognify p50 `${{ fromJSON(needs.perf-wap-llm.outputs.postgres_metrics || '{}').cognify.p50 }}s` • p90 `${{ fromJSON(needs.perf-wap-llm.outputs.postgres_metrics || '{}').cognify.p90 }}s` • p99 `${{ fromJSON(needs.perf-wap-llm.outputs.postgres_metrics || '{}').cognify.p99 }}s`
search p50 `${{ fromJSON(needs.perf-wap-llm.outputs.postgres_metrics || '{}').search.p50 }}s` • p90 `${{ fromJSON(needs.perf-wap-llm.outputs.postgres_metrics || '{}').search.p90 }}s` • p99 `${{ fromJSON(needs.perf-wap-llm.outputs.postgres_metrics || '{}').search.p99 }}s`
total p50 `${{ fromJSON(needs.perf-wap-llm.outputs.postgres_metrics || '{}').total.p50 }}s` • p90 `${{ fromJSON(needs.perf-wap-llm.outputs.postgres_metrics || '{}').total.p90 }}s` • p99 `${{ fromJSON(needs.perf-wap-llm.outputs.postgres_metrics || '{}').total.p99 }}s`
<${{ steps.presign.outputs.url_pg_wap_llm }}|HTML report>
- type: "section"
text:
type: "mrkdwn"
text: |
*📚 Full Postgres — War and Peace — Mock LLM* (`${{ needs.perf-wap-mock.result }}`) • runs `${{ fromJSON(needs.perf-wap-mock.outputs.postgres_metrics || '{}').success }}`
add p50 `${{ fromJSON(needs.perf-wap-mock.outputs.postgres_metrics || '{}').add.p50 }}s` • p90 `${{ fromJSON(needs.perf-wap-mock.outputs.postgres_metrics || '{}').add.p90 }}s` • p99 `${{ fromJSON(needs.perf-wap-mock.outputs.postgres_metrics || '{}').add.p99 }}s`
cognify p50 `${{ fromJSON(needs.perf-wap-mock.outputs.postgres_metrics || '{}').cognify.p50 }}s` • p90 `${{ fromJSON(needs.perf-wap-mock.outputs.postgres_metrics || '{}').cognify.p90 }}s` • p99 `${{ fromJSON(needs.perf-wap-mock.outputs.postgres_metrics || '{}').cognify.p99 }}s`
search p50 `${{ fromJSON(needs.perf-wap-mock.outputs.postgres_metrics || '{}').search.p50 }}s` • p90 `${{ fromJSON(needs.perf-wap-mock.outputs.postgres_metrics || '{}').search.p90 }}s` • p99 `${{ fromJSON(needs.perf-wap-mock.outputs.postgres_metrics || '{}').search.p99 }}s`
total p50 `${{ fromJSON(needs.perf-wap-mock.outputs.postgres_metrics || '{}').total.p50 }}s` • p90 `${{ fromJSON(needs.perf-wap-mock.outputs.postgres_metrics || '{}').total.p90 }}s` • p99 `${{ fromJSON(needs.perf-wap-mock.outputs.postgres_metrics || '{}').total.p99 }}s`
<${{ steps.presign.outputs.url_pg_wap_mock }}|HTML report>
- type: "section"
text:
type: "mrkdwn"
text: |
<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|View run>
- name: Fail if any suite failed
if: ${{ steps.status.outputs.passed != 'true' }}
run: |
echo "One or more nightly test suites failed."
exit 1
+28
View File
@@ -0,0 +1,28 @@
name: Reusable Notebook Tests
on:
workflow_call:
inputs:
ci-image:
required: false
type: string
default: ''
env:
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
# run-main-notebook:
# name: Main Notebook Test
# uses: ./.github/workflows/reusable_notebook.yml
# with:
# notebook-location: notebooks/cognee_demo.ipynb
# secrets: inherit
run-cognee-multimedia:
name: Cognee Multimedia Notebook
uses: ./.github/workflows/reusable_notebook.yml
with:
notebook-location: notebooks/cognee_multimedia_demo.ipynb
ci-image: ${{ inputs.ci-image }}
secrets: inherit
+298
View File
@@ -0,0 +1,298 @@
name: performance report
# Reusable workflow: runs the percentile performance report once for a given
# dataset + mode, uploads the JSON + HTML artifacts to S3, and exposes the
# headline metrics + HTML object key as outputs for the caller (the Slack bot in
# nightly_tests.yml).
#
# Both backends run on every call, as two separate jobs:
# - file_based : cognee defaults (SQLite + Kuzu + LanceDB), no services.
# - postgres : full Postgres (relational + PGVector + Postgres graph) via a
# `services: postgres` container (mirrors e2e_tests.yml).
# Each job exposes its own metrics + html_key outputs (file_based_* / postgres_*).
on:
workflow_call:
inputs:
mode:
description: "Run mode: 'mock_llm' (no API calls) or 'llm' (real LLM)."
required: true
type: string
label:
description: "Dataset label, used in the S3 output path and display name."
required: true
type: string
runs:
description: "Number of sequential benchmark runs."
required: false
type: string
default: '10'
num_memories:
description: "If set, forwarded as --num-memories (limit input documents)."
required: false
type: string
default: ''
memories_key:
description: "S3 object key (under the bucket) downloaded and used as --memories."
required: true
type: string
mock_memories_key:
description: "If set, S3 object key downloaded and used as --mock-memories."
required: false
type: string
default: ''
outputs:
file_based_metrics:
description: "File-based run: success + add/cognify/search/total p50/p90/p99."
value: ${{ jobs.file_based.outputs.metrics }}
file_based_html_key:
description: "File-based run: S3 object key of the HTML report."
value: ${{ jobs.file_based.outputs.html_key }}
postgres_metrics:
description: "Postgres run: success + add/cognify/search/total p50/p90/p99."
value: ${{ jobs.postgres.outputs.metrics }}
postgres_html_key:
description: "Postgres run: S3 object key of the HTML report."
value: ${{ jobs.postgres.outputs.html_key }}
env:
ENV: 'dev'
COGNEE_SKIP_CONNECTION_TEST: 'true'
RUNTIME__LOG_LEVEL: ERROR
BUCKET: github-runner-cognee-tests
jobs:
# ── File-based backend: SQLite + Kuzu + LanceDB (cognee defaults) ────────────
file_based:
name: file_based — ${{ inputs.label }} (${{ inputs.mode }})
runs-on: ubuntu-22.04
outputs:
metrics: ${{ steps.parse.outputs.metrics }}
html_key: ${{ steps.upload.outputs.html_key }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
- name: Download dataset from S3
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_S3_DEV_USER_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_S3_DEV_USER_SECRET_KEY }}
AWS_DEFAULT_REGION: eu-west-1
MEMORIES_KEY: ${{ inputs.memories_key }}
MOCK_MEMORIES_KEY: ${{ inputs.mock_memories_key }}
run: |
set -euo pipefail
mkdir -p performance_datasets
aws s3 cp "s3://$BUCKET/$MEMORIES_KEY" performance_datasets/memories.json
echo "MEMORIES_FILE=$PWD/performance_datasets/memories.json" >> "$GITHUB_ENV"
if [ -n "$MOCK_MEMORIES_KEY" ]; then
aws s3 cp "s3://$BUCKET/$MOCK_MEMORIES_KEY" performance_datasets/mock_memories.json
echo "MOCK_MEMORIES_FILE=$PWD/performance_datasets/mock_memories.json" >> "$GITHUB_ENV"
fi
- name: Run performance report
id: run
env:
PYTHONFAULTHANDLER: 1
# LLM + embedding config via the standard CI secrets (see e2e_tests.yml).
# Only exercised for mode == 'llm'; the mock run hits no external APIs.
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: |
set -euo pipefail
TS="$(date -u '+%Y-%m-%d_%H-%M-%SZ')"
JSON_PATH="performance_results/file_based/${{ inputs.label }}/${{ inputs.mode }}_${TS}.json"
HTML_PATH="performance_results/file_based/${{ inputs.label }}/${{ inputs.mode }}_${TS}.html"
mkdir -p "$(dirname "$JSON_PATH")"
echo "JSON_PATH=$JSON_PATH" >> "$GITHUB_ENV"
echo "HTML_PATH=$HTML_PATH" >> "$GITHUB_ENV"
ARGS=(--runs "${{ inputs.runs }}" --memories "$MEMORIES_FILE")
if [ -n "${MOCK_MEMORIES_FILE:-}" ]; then
ARGS+=(--mock-memories "$MOCK_MEMORIES_FILE")
fi
if [ "${{ inputs.mode }}" = "mock_llm" ]; then
ARGS+=(--mock-llm)
fi
if [ -n "${{ inputs.num_memories }}" ]; then
ARGS+=(--num-memories "${{ inputs.num_memories }}")
fi
uv run python cognee/tests/performance/statistics_percentile_report.py \
"${ARGS[@]}" \
--output "$JSON_PATH" \
--html "$HTML_PATH"
- name: Upload reports to S3
id: upload
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_S3_DEV_USER_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_S3_DEV_USER_SECRET_KEY }}
AWS_DEFAULT_REGION: eu-west-1
run: |
set -euo pipefail
aws s3 cp "$JSON_PATH" "s3://$BUCKET/$JSON_PATH" --content-type application/json
aws s3 cp "$HTML_PATH" "s3://$BUCKET/$HTML_PATH" --content-type text/html
# Presigning is done by the caller (the Slack job), NOT here: a presigned URL
# embeds the AWS access key id, and GitHub scrubs registered secrets from
# reusable-workflow outputs — which would blank the link. Pass only the
# (non-secret) object key across the boundary.
echo "html_key=$HTML_PATH" >> "$GITHUB_OUTPUT"
- name: Parse headline metrics
id: parse
run: |
set -euo pipefail
METRICS="$(jq -c '{
success: "\(.succeeded)/\(.num_runs)",
add: {p50: .stats.add_time_s.p50, p90: .stats.add_time_s.p90, p99: .stats.add_time_s.p99},
cognify: {p50: .stats.cognify_time_s.p50, p90: .stats.cognify_time_s.p90, p99: .stats.cognify_time_s.p99},
search: {p50: .stats.search_time.p50, p90: .stats.search_time.p90, p99: .stats.search_time.p99},
total: {p50: .stats.total_ingest_time_s.p50, p90: .stats.total_ingest_time_s.p90, p99: .stats.total_ingest_time_s.p99}
}' "$JSON_PATH")"
echo "metrics=$METRICS" >> "$GITHUB_OUTPUT"
# ── Postgres backend: Postgres relational + PGVector + Postgres graph ────────
postgres:
name: postgres — ${{ inputs.label }} (${{ inputs.mode }})
runs-on: ubuntu-22.04
defaults:
run:
shell: bash
services:
postgres:
image: ghcr.io/topoteretes/pgvector:pg17
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
POSTGRES_USER: cognee
POSTGRES_PASSWORD: cognee
POSTGRES_DB: cognee_db
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
outputs:
metrics: ${{ steps.parse.outputs.metrics }}
html_key: ${{ steps.upload.outputs.html_key }}
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
extra-dependencies: "postgres"
- name: Download dataset from S3
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_S3_DEV_USER_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_S3_DEV_USER_SECRET_KEY }}
AWS_DEFAULT_REGION: eu-west-1
MEMORIES_KEY: ${{ inputs.memories_key }}
MOCK_MEMORIES_KEY: ${{ inputs.mock_memories_key }}
run: |
set -euo pipefail
mkdir -p performance_datasets
aws s3 cp "s3://$BUCKET/$MEMORIES_KEY" performance_datasets/memories.json
echo "MEMORIES_FILE=$PWD/performance_datasets/memories.json" >> "$GITHUB_ENV"
if [ -n "$MOCK_MEMORIES_KEY" ]; then
aws s3 cp "s3://$BUCKET/$MOCK_MEMORIES_KEY" performance_datasets/mock_memories.json
echo "MOCK_MEMORIES_FILE=$PWD/performance_datasets/mock_memories.json" >> "$GITHUB_ENV"
fi
- name: Run performance report
id: run
env:
PYTHONFAULTHANDLER: 1
# LLM + embedding config via the standard CI secrets (see e2e_tests.yml).
# Only exercised for mode == 'llm'; the mock run hits no external APIs.
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
# Full Postgres stack (creds match the postgres service above; mirrors e2e_tests.yml).
DB_PROVIDER: 'postgres'
DB_HOST: '127.0.0.1'
DB_PORT: '5432'
DB_USERNAME: cognee
DB_PASSWORD: cognee
DB_NAME: cognee_db
VECTOR_DB_PROVIDER: 'pgvector'
VECTOR_DB_HOST: '127.0.0.1'
VECTOR_DB_PORT: '5432'
VECTOR_DB_USERNAME: cognee
VECTOR_DB_PASSWORD: cognee
VECTOR_DATASET_DATABASE_HANDLER: 'pgvector'
GRAPH_DATABASE_PROVIDER: 'postgres'
GRAPH_DATABASE_HOST: '127.0.0.1'
GRAPH_DATABASE_PORT: '5432'
GRAPH_DATABASE_USERNAME: cognee
GRAPH_DATABASE_PASSWORD: cognee
GRAPH_DATABASE_NAME: cognee_db
run: |
set -euo pipefail
TS="$(date -u '+%Y-%m-%d_%H-%M-%SZ')"
JSON_PATH="performance_results/postgres/${{ inputs.label }}/${{ inputs.mode }}_${TS}.json"
HTML_PATH="performance_results/postgres/${{ inputs.label }}/${{ inputs.mode }}_${TS}.html"
mkdir -p "$(dirname "$JSON_PATH")"
echo "JSON_PATH=$JSON_PATH" >> "$GITHUB_ENV"
echo "HTML_PATH=$HTML_PATH" >> "$GITHUB_ENV"
ARGS=(--runs "${{ inputs.runs }}" --memories "$MEMORIES_FILE")
if [ -n "${MOCK_MEMORIES_FILE:-}" ]; then
ARGS+=(--mock-memories "$MOCK_MEMORIES_FILE")
fi
if [ "${{ inputs.mode }}" = "mock_llm" ]; then
ARGS+=(--mock-llm)
fi
if [ -n "${{ inputs.num_memories }}" ]; then
ARGS+=(--num-memories "${{ inputs.num_memories }}")
fi
uv run python cognee/tests/performance/statistics_percentile_report.py \
"${ARGS[@]}" \
--output "$JSON_PATH" \
--html "$HTML_PATH"
- name: Upload reports to S3
id: upload
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_S3_DEV_USER_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_S3_DEV_USER_SECRET_KEY }}
AWS_DEFAULT_REGION: eu-west-1
run: |
set -euo pipefail
aws s3 cp "$JSON_PATH" "s3://$BUCKET/$JSON_PATH" --content-type application/json
aws s3 cp "$HTML_PATH" "s3://$BUCKET/$HTML_PATH" --content-type text/html
# Presigning is done by the caller (the Slack job), NOT here: a presigned URL
# embeds the AWS access key id, and GitHub scrubs registered secrets from
# reusable-workflow outputs — which would blank the link. Pass only the
# (non-secret) object key across the boundary.
echo "html_key=$HTML_PATH" >> "$GITHUB_OUTPUT"
- name: Parse headline metrics
id: parse
run: |
set -euo pipefail
METRICS="$(jq -c '{
success: "\(.succeeded)/\(.num_runs)",
add: {p50: .stats.add_time_s.p50, p90: .stats.add_time_s.p90, p99: .stats.add_time_s.p99},
cognify: {p50: .stats.cognify_time_s.p50, p90: .stats.cognify_time_s.p90, p99: .stats.cognify_time_s.p99},
search: {p50: .stats.search_time.p50, p90: .stats.search_time.p90, p99: .stats.search_time.p99},
total: {p50: .stats.total_ingest_time_s.p50, p90: .stats.total_ingest_time_s.p90, p99: .stats.total_ingest_time_s.p99}
}' "$JSON_PATH")"
echo "metrics=$METRICS" >> "$GITHUB_OUTPUT"
+44
View File
@@ -0,0 +1,44 @@
## Reference: https://github.com/amannn/action-semantic-pull-request
---
name: lint | PR
on:
pull_request:
types:
- opened
- reopened
- edited
- synchronize
permissions:
contents: read
jobs:
pr_title:
permissions:
pull-requests: write
statuses: write
name: Validate & Label PR
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
# Configure which types are allowed (newline-delimited).
# From: https://github.com/commitizen/conventional-commit-types/blob/master/index.json
# listing all below
types: |
chore
ci
docs
feat
fix
perf
refactor
revert
test
break
- uses: release-drafter/release-drafter@v6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+29
View File
@@ -0,0 +1,29 @@
on:
workflow_call:
permissions:
contents: read
env:
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
check-uv-lock:
name: Lockfile and Pre-commit Hooks
runs-on: ubuntu-22.04
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Validate uv lockfile and project metadata
run: uv lock --check || { echo "'uv lock --check' failed."; echo "Run 'uv lock' and push your changes."; exit 1; }
- name: Run pre-commit hooks
uses: pre-commit/action@v3.0.1
@@ -0,0 +1,248 @@
name: Relational DB Migration Tests
on:
workflow_call:
inputs:
python-version:
required: false
type: string
default: '3.11.x'
ci-image:
required: false
type: string
default: ''
secrets:
LLM_PROVIDER:
required: true
LLM_MODEL:
required: true
LLM_ENDPOINT:
required: true
LLM_API_KEY:
required: true
LLM_ARGS:
required: false
LLM_API_VERSION:
required: true
EMBEDDING_PROVIDER:
required: true
EMBEDDING_MODEL:
required: true
EMBEDDING_API_KEY:
required: true
env:
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
run-relational-db-migration-test-networkx:
name: NetworkX Relational DB Migration Test
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
defaults:
run:
shell: bash
services:
postgres:
image: ghcr.io/topoteretes/pgvector:pg17
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
POSTGRES_USER: cognee
POSTGRES_PASSWORD: cognee
POSTGRES_DB: test_migration_db
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
extra-dependencies: "postgres"
- name: Install specific db dependency
run: echo "Dependencies already installed in setup"
- name: Run PostgreSQL Script to create test data (Chinook_PostgreSql.sql)
env:
PGPASSWORD: cognee
PG_HOST: ${{ inputs.ci-image != '' && 'postgres' || 'localhost' }}
run: |
# Wait until the PostgreSQL service is available
until pg_isready -h $PG_HOST -p 5432; do
echo "Waiting for postgres..."
sleep 2
done
# Execute the SQL script against the test_migration_db database
psql -h $PG_HOST -U cognee -d test_migration_db -f ./cognee/tests/test_data/Chinook_PostgreSql.sql
- name: Run relational db test
env:
ENV: 'dev'
LLM_PROVIDER: openai
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_PROVIDER: openai
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
DB_HOST: ${{ inputs.ci-image != '' && 'postgres' || '127.0.0.1' }}
run: uv run python ./cognee/tests/test_relational_db_migration.py
run-relational-db-migration-test-kuzu:
name: Kuzu Relational DB Migration Test
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
defaults:
run:
shell: bash
services:
postgres:
image: ghcr.io/topoteretes/pgvector:pg17
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
POSTGRES_USER: cognee
POSTGRES_PASSWORD: cognee
POSTGRES_DB: test_migration_db
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
extra-dependencies: "postgres"
- name: Install specific db dependency
run: echo "Dependencies already installed in setup"
- name: Run PostgreSQL Script to create test data (Chinook_PostgreSql.sql)
env:
PGPASSWORD: cognee
PG_HOST: ${{ inputs.ci-image != '' && 'postgres' || 'localhost' }}
run: |
# Wait until the PostgreSQL service is available
until pg_isready -h $PG_HOST -p 5432; do
echo "Waiting for postgres..."
sleep 2
done
# Execute the SQL script against the test_migration_db database
psql -h $PG_HOST -U cognee -d test_migration_db -f ./cognee/tests/test_data/Chinook_PostgreSql.sql
- name: Run relational db test
env:
ENV: 'dev'
GRAPH_DATABASE_PROVIDER: 'kuzu'
LLM_PROVIDER: openai
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_PROVIDER: openai
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
DB_HOST: ${{ inputs.ci-image != '' && 'postgres' || '127.0.0.1' }}
run: uv run python ./cognee/tests/test_relational_db_migration.py
run-relational-db-migration-test-neo4j:
name: Neo4j Relational DB Migration Test
runs-on: ubuntu-22.04
defaults:
run:
shell: bash
services:
postgres:
image: ghcr.io/topoteretes/pgvector:pg17
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
POSTGRES_USER: cognee
POSTGRES_PASSWORD: cognee
POSTGRES_DB: test_migration_db
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
extra-dependencies: "postgres"
- name: Setup Neo4j with GDS
uses: ./.github/actions/setup_neo4j
id: neo4j
- name: Install specific db dependency
run: echo "Dependencies already installed in setup"
- name: Run PostgreSQL Script to create test data (Chinook_PostgreSql.sql)
env:
PGPASSWORD: cognee
run: |
# Wait until the PostgreSQL service is available
until pg_isready -h localhost -p 5432; do
echo "Waiting for postgres..."
sleep 2
done
# Execute the SQL script against the test_migration_db database
psql -h localhost -U cognee -d test_migration_db -f ./cognee/tests/test_data/Chinook_PostgreSql.sql
- name: Run relational db test
env:
ENV: 'dev'
GRAPH_DATABASE_PROVIDER: "neo4j"
GRAPH_DATABASE_URL: ${{ steps.neo4j.outputs.neo4j-url }}
GRAPH_DATABASE_USERNAME: ${{ steps.neo4j.outputs.neo4j-username }}
GRAPH_DATABASE_PASSWORD: ${{ steps.neo4j.outputs.neo4j-password }}
LLM_PROVIDER: openai
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_PROVIDER: openai
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./cognee/tests/test_relational_db_migration.py
+254
View File
@@ -0,0 +1,254 @@
name: release.yml
on:
workflow_dispatch:
jobs:
release-github:
name: Create GitHub Release from ${{ github.ref_name }}
outputs:
tag: ${{ steps.create_tag.outputs.tag }}
version: ${{ steps.create_tag.outputs.version }}
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- name: Check out ${{ github.ref_name }}
uses: actions/checkout@v6
with:
ref: ${{ github.ref_name }}
fetch-depth: 0 # Fetch all history for comparison
- name: Fetch main branch for comparison
if: ${{ github.ref_name == 'dev' }}
run: git fetch origin main:main
- name: Fetch dev branch for comparison
if: ${{ github.ref_name == 'main' }}
run: git fetch origin dev:dev
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install Python
run: uv python install
- name: Install dependencies
run: uv sync --locked
- name: Create and push git tag
id: create_tag
run: |
VERSION="$(uv version --short)"
TAG="v${VERSION}"
echo "Tag to create: ${TAG}"
git config user.name "Cognee Team"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
git tag "${TAG}"
git push origin "${TAG}"
- name: Generate AI-powered release notes
id: generate_notes
env:
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_MODEL: ${{ secrets.LLM_MODEL != '' && secrets.LLM_MODEL || 'openai/gpt-4o-mini' }}
run: |
# Set PYTHONPATH to include project root
export PYTHONPATH="${GITHUB_WORKSPACE}:${PYTHONPATH}"
# Generate release notes
# Compares current branch against the latest release tag automatically
uv run python tools/generate_release_notes.py \
--version "${{ steps.create_tag.outputs.version }}" \
--github-output
- name: Create GitHub Release with AI-generated notes
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.create_tag.outputs.tag }}
name: ${{ steps.generate_notes.outputs.RELEASE_TITLE }}
body: ${{ steps.generate_notes.outputs.RELEASE_NOTES }}
prerelease: ${{ github.ref_name == 'dev' }}
env:
GITHUB_TOKEN: ${{ secrets.GH_RELEASE_TOKEN }}
release-pypi-package:
needs: release-github
name: Release PyPI Package from ${{ github.ref_name }}
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- name: Check out ${{ github.ref_name }}
uses: actions/checkout@v6
with:
ref: ${{ github.ref_name }}
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install Python
run: uv python install
- name: Install dependencies
run: uv sync --locked --all-extras
- name: Build distributions
run: uv build
- name: Publish ${{ github.ref_name }} release to PyPI
env:
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }}
run: uv publish
release-docker-image:
needs: release-github
name: Release Docker Image from ${{ github.ref_name }}
permissions:
contents: read
runs-on: ubuntu-latest
steps:
- name: Check out ${{ github.ref_name }}
uses: actions/checkout@v6
with:
ref: ${{ github.ref_name }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push Dev Docker Image
if: ${{ github.ref_name == 'dev' }}
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: cognee/cognee:${{ needs.release-github.outputs.version }}
labels: |
version=${{ needs.release-github.outputs.version }}
flavour=${{ github.ref_name }}
cache-from: type=registry,ref=cognee/cognee:buildcache
cache-to: type=registry,ref=cognee/cognee:buildcache,mode=max
- name: Build and push Main Docker Image
if: ${{ github.ref_name == 'main' }}
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
cognee/cognee:${{ needs.release-github.outputs.version }}
cognee/cognee:latest
labels: |
version=${{ needs.release-github.outputs.version }}
flavour=${{ github.ref_name }}
cache-from: type=registry,ref=cognee/cognee:buildcache
cache-to: type=registry,ref=cognee/cognee:buildcache,mode=max
- name: Build and push Dev MCP Docker Image
if: ${{ github.ref_name == 'dev' }}
uses: docker/build-push-action@v6
with:
context: .
file: cognee-mcp/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: cognee/cognee-mcp:${{ needs.release-github.outputs.version }}
labels: |
version=${{ needs.release-github.outputs.version }}
flavour=${{ github.ref_name }}
cache-from: type=registry,ref=cognee/cognee-mcp:buildcache
cache-to: type=registry,ref=cognee/cognee-mcp:buildcache,mode=max
- name: Build and push Main MCP Docker Image
if: ${{ github.ref_name == 'main' }}
uses: docker/build-push-action@v6
with:
context: .
file: cognee-mcp/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: |
cognee/cognee-mcp:${{ needs.release-github.outputs.version }}
cognee/cognee-mcp:latest
labels: |
version=${{ needs.release-github.outputs.version }}
flavour=${{ github.ref_name }}
cache-from: type=registry,ref=cognee/cognee-mcp:buildcache
cache-to: type=registry,ref=cognee/cognee-mcp:buildcache,mode=max
trigger-docs-test-suite:
needs: release-pypi-package
if: ${{ github.ref_name == 'main' }}
runs-on: ubuntu-22.04
steps:
- name: Trigger docs tests
run: |
curl -L -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.REPO_DISPATCH_PAT_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/topoteretes/cognee-docs/dispatches \
-d '{"event_type":"new-main-release","client_payload":{"caller_repo":"'"${GITHUB_REPOSITORY}"'"}}'
trigger-community-test-suite:
needs: release-pypi-package
if: ${{ github.ref_name == 'main' }}
runs-on: ubuntu-22.04
steps:
- name: Trigger community tests
run: |
curl -L -X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ secrets.REPO_DISPATCH_PAT_TOKEN }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://api.github.com/repos/topoteretes/cognee-community/dispatches \
-d '{"event_type":"new-main-release","client_payload":{"caller_repo":"'"${GITHUB_REPOSITORY}"'"}}'
notify-discord:
needs: release-github
name: Send Release to Discord
if: ${{ github.ref_name == 'main' }}
runs-on: ubuntu-22.04
steps:
- name: Send Discord notification
env:
WEBHOOK_URL: ${{ secrets.WEBHOOK_URL }}
TAG: ${{ needs.release-github.outputs.tag }}
VERSION: ${{ needs.release-github.outputs.version }}
run: |
RELEASE_URL="https://github.com/${{ github.repository }}/releases/tag/${TAG}"
PAYLOAD=$(jq -n \
--arg content "||@everyone|| **${TAG}** has been released!" \
--arg title "Release ${TAG}" \
--arg url "$RELEASE_URL" \
--arg description "Version ${VERSION} released from \`${{ github.ref_name }}\`. [View release notes](${RELEASE_URL})" \
--argjson color 2105893 \
'{
content: $content,
embeds: [{
title: $title,
url: $url,
description: $description,
color: $color,
footer: { text: "Changelog" },
timestamp: (now | todate)
}]
}')
curl -s -H "Content-Type: application/json" -d "$PAYLOAD" "$WEBHOOK_URL"
@@ -0,0 +1,23 @@
name: automation | Send Release to Discord
on:
release:
types: [published]
jobs:
github-releases-to-discord:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Github Releases To Discord
uses: SethCohen/github-releases-to-discord@v1.19.0
with:
webhook_url: ${{ secrets.WEBHOOK_URL }}
color: "2105893"
username: "Release Changelog"
avatar_url: "https://cdn.discordapp.com/avatars/487431320314576937/bd64361e4ba6313d561d54e78c9e7171.png"
content: "||@everyone||"
footer_title: "Changelog"
footer_icon_url: "https://cdn.discordapp.com/avatars/487431320314576937/bd64361e4ba6313d561d54e78c9e7171.png"
footer_timestamp: true
+201
View File
@@ -0,0 +1,201 @@
# Long-running, heavy and resource-consuming tests for release validation.
# Runs automatically on PRs targeting main (the dev -> main promotion) and manually
# via workflow_dispatch. Fork PRs are skipped (no access to secrets).
name: Release Test Workflow
permissions:
contents: read
packages: write
on:
workflow_dispatch:
inputs:
cognee_version:
required: false
default: local
type: string
description: "Pypi-compatible version of cognee to use. For example, 0.5.2.dev0. `local` (default) - Installing Cognee from local source"
pull_request:
branches:
- main
concurrency:
group: release-tests-${{ github.head_ref || github.run_id }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
mcp-test:
name: MCP Tests
if: ${{ github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == github.repository }}
uses: ./.github/workflows/test_mcp.yml
secrets: inherit
with:
cognee_version: ${{ inputs.cognee_version || 'local' }}
cli-test:
name: CLI Tests
if: ${{ github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == github.repository }}
uses: ./.github/workflows/cli_tests.yml
secrets: inherit
with:
cognee_version: ${{ inputs.cognee_version || 'local' }}
cot-retriever-test:
name: COT Retriever Test
if: ${{ github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == github.repository }}
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install Python
run: uv python install
- name: Install dependencies
run: |
if [ "${{ inputs.cognee_version }}" = "local" ] || [ -z "${{ inputs.cognee_version }}" ]; then
uv sync --locked --all-extras
else
uv sync --locked --all-extras
uv pip install cognee==${{ inputs.cognee_version }}
fi
- name: Run COT retriever integration test
env:
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
run: |
uv run pytest cognee/tests/integration/retrieval/test_graph_completion_retriever_cot.py -v --timeout=300
# 10 parallel users against a live HTTP server with access control enabled:
# per-user dataset isolation, add/cognify/search verification via sentinel chunks
# (LLM-free CHUNKS search), delete + recreate, forget + recreate-same-name.
multi-user-e2e-default:
name: Multi-User Release E2E (default file-based DBs)
if: ${{ github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == github.repository }}
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Check out code
uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install Python
run: uv python install
- name: Install dependencies
run: |
if [ "${{ inputs.cognee_version }}" = "local" ] || [ -z "${{ inputs.cognee_version }}" ]; then
uv sync --locked --all-extras
else
uv sync --locked --all-extras
uv pip install cognee==${{ inputs.cognee_version }}
fi
- name: Run multi-user release E2E test
env:
ENV: 'dev'
COGNEE_SKIP_CONNECTION_TEST: 'true'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./cognee/tests/test_release_multi_user_e2e.py
multi-user-e2e-postgres:
name: Multi-User Release E2E (Postgres graph + PGVector + Postgres)
if: ${{ github.event_name == 'workflow_dispatch' || github.event.pull_request.head.repo.full_name == github.repository }}
runs-on: ubuntu-latest
timeout-minutes: 60
services:
postgres:
image: ghcr.io/topoteretes/pgvector:pg17
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
POSTGRES_USER: cognee
POSTGRES_PASSWORD: cognee
POSTGRES_DB: cognee_db
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Check out code
uses: actions/checkout@v6
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install Python
run: uv python install
- name: Install dependencies
run: |
if [ "${{ inputs.cognee_version }}" = "local" ] || [ -z "${{ inputs.cognee_version }}" ]; then
uv sync --locked --all-extras
else
uv sync --locked --all-extras
uv pip install cognee==${{ inputs.cognee_version }}
fi
- name: Run multi-user release E2E test
env:
ENV: 'dev'
COGNEE_SKIP_CONNECTION_TEST: 'true'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
DB_PROVIDER: 'postgres'
DB_NAME: 'cognee_db'
DB_HOST: '127.0.0.1'
DB_PORT: 5432
DB_USERNAME: cognee
DB_PASSWORD: cognee
VECTOR_DB_PROVIDER: 'pgvector'
VECTOR_DB_NAME: 'cognee_db'
VECTOR_DB_HOST: '127.0.0.1'
VECTOR_DB_PORT: 5432
VECTOR_DB_USERNAME: cognee
VECTOR_DB_PASSWORD: cognee
VECTOR_DATASET_DATABASE_HANDLER: 'pgvector'
GRAPH_DATABASE_PROVIDER: 'postgres'
GRAPH_DATABASE_NAME: 'cognee_db'
GRAPH_DATABASE_HOST: '127.0.0.1'
GRAPH_DATABASE_PORT: 5432
GRAPH_DATABASE_USERNAME: cognee
GRAPH_DATABASE_PASSWORD: cognee
GRAPH_DATASET_DATABASE_HANDLER: 'postgres_graph'
run: uv run python ./cognee/tests/test_release_multi_user_e2e.py
load-tests:
if: false
name: Load Tests
uses: ./.github/workflows/load_tests.yml
secrets: inherit
dev-canary-release:
name: Dev Canary Release
if: ${{ github.event_name == 'workflow_dispatch' }}
needs: load-tests
uses: ./.github/workflows/dev_canary_release.yml
secrets: inherit
@@ -0,0 +1,40 @@
name: Require Linear issue
# Every INTERNAL PR must reference a Linear issue (e.g. COG-123) in its title or
# branch name — that is how Linear links a PR to a ticket. Since Linear does not
# gate merges, enforcement is a required GitHub status check: this job fails when a
# PR has no Linear key, and branch protection blocks the merge until it passes.
#
# Fork / external-contributor PRs are intentionally SKIPPED: they have no Linear
# access, and a skipped required check counts as passing, so this never blocks the
# community. Mark the `linear-issue-check` job as a required status check on
# `main` and `dev` in branch protection.
on:
pull_request:
# `synchronize` matters: a required check must re-run on the latest commit.
types: [opened, edited, reopened, synchronize]
permissions:
contents: read
jobs:
linear-issue-check: # this job name is what you mark "required" in branch protection
# Enforce for internal PRs only. Fork PRs (head repo != base repo) skip this job;
# a skipped required check is treated as passing, so external PRs are not blocked.
if: github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
steps:
- name: PR title or branch must reference a Linear issue
env:
PR_TITLE: ${{ github.event.pull_request.title }}
HEAD_REF: ${{ github.head_ref }}
run: |
# List ALL your Linear team prefixes — verify against Linear ▸ Settings ▸ Teams.
KEYS='COG|SDK|CLO|COM|ENG'
if echo "$PR_TITLE $HEAD_REF" | grep -Eiq "\b(${KEYS})-[0-9]+\b"; then
echo "Linear issue reference found."
else
echo "::error::PR title or branch must reference a Linear issue, e.g. COG-123."
exit 1
fi
+71
View File
@@ -0,0 +1,71 @@
name: test-notebook
on:
workflow_call:
inputs:
notebook-location:
description: "Location of Jupyter notebook to run"
required: true
type: string
ci-image:
required: false
type: string
default: ''
secrets:
#LLM_MODEL:
# required: true
#LLM_ENDPOINT:
# required: true
LLM_API_KEY:
required: true
LLM_ARGS:
required: false
OPENAI_API_KEY:
required: true
#LLM_API_VERSION:
# required: true
EMBEDDING_MODEL:
required: true
EMBEDDING_API_KEY:
required: true
env:
RUNTIME__LOG_LEVEL: ERROR
jobs:
run_notebook_test:
name: test
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
defaults:
run:
shell: bash
steps:
- name: Check out
uses: actions/checkout@master
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
extra-dependencies: "notebook"
- name: Execute Jupyter Notebook
env:
ENV: 'dev'
#LLM_MODEL: ${{ secrets.LLM_MODEL }}
#LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} # Use OpenAI Until a multimedia model is deployed and DeepEval support for other models is added
#LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: |
uv run jupyter nbconvert \
--to notebook \
--execute ${{ inputs.notebook-location }} \
--output executed_notebook.ipynb \
--ExecutePreprocessor.timeout=1200
+78
View File
@@ -0,0 +1,78 @@
# This workflow uses actions that are not certified by GitHub. They are provided
# by a third-party and are governed by separate terms of service, privacy
# policy, and support documentation.
name: Scorecard supply-chain security
on:
# For Branch-Protection check. Only the default branch is supported. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
branch_protection_rule:
# To guarantee Maintained check is occasionally updated. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
schedule:
- cron: '35 8 * * 2'
push:
branches: [ "main" ]
# Declare default permissions as read only.
permissions: read-all
jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-latest
# `publish_results: true` only works when run from the default branch. conditional can be removed if disabled.
if: github.event.repository.default_branch == github.ref_name || github.event_name == 'pull_request'
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
# Needed to publish results and get a badge (see publish_results below).
id-token: write
# Uncomment the permissions below if installing in a private repository.
# contents: read
# actions: read
steps:
- name: "Checkout code"
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1
with:
results_file: results.sarif
results_format: sarif
# (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
# - you want to enable the Branch-Protection check on a *public* repository, or
# - you are installing Scorecard on a *private* repository
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action?tab=readme-ov-file#authentication-with-fine-grained-pat-optional.
# repo_token: ${{ secrets.SCORECARD_TOKEN }}
# Public repositories:
# - Publish results to OpenSSF REST API for easy access by consumers
# - Allows the repository to include the Scorecard badge.
# - See https://github.com/ossf/scorecard-action#publishing-results.
# For private repositories:
# - `publish_results` will always be set to `false`, regardless
# of the value entered here.
publish_results: true
# (Optional) Uncomment file_mode if you have a .gitattributes with files marked export-ignore
# file_mode: git
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
with:
name: SARIF file
path: results.sarif
retention-days: 5
# Upload the results to GitHub's code scanning dashboard (optional).
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: results.sarif
+244
View File
@@ -0,0 +1,244 @@
name: Reusable Search DB Tests
permissions:
contents: read
packages: read
on:
workflow_call:
inputs:
databases:
required: false
type: string
default: "all"
description: "Which vector databases to test (comma-separated list or 'all')"
python-versions:
required: false
type: string
default: '["3.10", "3.11", "3.12", "3.13"]'
description: "Python versions to test (JSON array)"
ci-image:
required: false
type: string
default: ''
description: "Container image for CI (empty string means no container)"
env:
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
run-kuzu-lance-sqlite-search-tests:
name: Search test for Kuzu/LanceDB/Sqlite (Python ${{ matrix.python-version }})
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'kuzu/lance/sqlite') }}
strategy:
matrix:
python-version: ${{ fromJSON(inputs.python-versions) }}
fail-fast: false
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ matrix.python-version }}
- name: Dependencies already installed
run: echo "Dependencies already installed in setup"
- name: Run Kuzu search Tests
env:
ENV: 'dev'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
GRAPH_DATABASE_PROVIDER: 'kuzu'
VECTOR_DB_PROVIDER: 'lancedb'
DB_PROVIDER: 'sqlite'
run: uv run pytest cognee/tests/test_search_db.py -v --log-level=INFO
run-neo4j-lance-sqlite-search-tests:
name: Search test for Neo4j/LanceDB/Sqlite (Python ${{ matrix.python-version }})
runs-on: ubuntu-22.04
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'neo4j/lance/sqlite') }}
strategy:
matrix:
python-version: ${{ fromJSON(inputs.python-versions) }}
fail-fast: false
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ matrix.python-version }}
- name: Setup Neo4j with GDS
uses: ./.github/actions/setup_neo4j
id: neo4j
- name: Dependencies already installed
run: echo "Dependencies already installed in setup"
- name: Run Neo4j search Tests
env:
ENV: 'dev'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
GRAPH_DATABASE_PROVIDER: 'neo4j'
VECTOR_DB_PROVIDER: 'lancedb'
DB_PROVIDER: 'sqlite'
ENABLE_BACKEND_ACCESS_CONTROL: 'false'
GRAPH_DATABASE_URL: ${{ steps.neo4j.outputs.neo4j-url }}
GRAPH_DATABASE_USERNAME: ${{ steps.neo4j.outputs.neo4j-username }}
GRAPH_DATABASE_PASSWORD: ${{ steps.neo4j.outputs.neo4j-password }}
run: uv run pytest cognee/tests/test_search_db.py -v --log-level=INFO
run-kuzu-pgvector-postgres-search-tests:
name: Search test for Kuzu/PGVector/Postgres (Python ${{ matrix.python-version }})
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'kuzu/pgvector/postgres') }}
strategy:
matrix:
python-version: ${{ fromJSON(inputs.python-versions) }}
fail-fast: false
services:
postgres:
image: ghcr.io/topoteretes/pgvector:pg17
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
POSTGRES_USER: cognee
POSTGRES_PASSWORD: cognee
POSTGRES_DB: cognee_db
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ matrix.python-version }}
extra-dependencies: "postgres"
- name: Dependencies already installed
run: echo "Dependencies already installed in setup"
- name: Run Kuzu/PGVector/Postgres Tests
env:
ENV: dev
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
GRAPH_DATABASE_PROVIDER: 'kuzu'
VECTOR_DB_PROVIDER: 'pgvector'
ENABLE_BACKEND_ACCESS_CONTROL: 'false'
DB_PROVIDER: 'postgres'
DB_NAME: 'cognee_db'
DB_HOST: ${{ inputs.ci-image != '' && 'postgres' || '127.0.0.1' }}
DB_PORT: 5432
DB_USERNAME: cognee
DB_PASSWORD: cognee
run: uv run pytest cognee/tests/test_search_db.py -v --log-level=INFO
run-neo4j-pgvector-postgres-search-tests:
name: Search test for Neo4j/PGVector/Postgres (Python ${{ matrix.python-version }})
runs-on: ubuntu-22.04
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'neo4j/pgvector/postgres') }}
strategy:
matrix:
python-version: ${{ fromJSON(inputs.python-versions) }}
fail-fast: false
services:
postgres:
image: ghcr.io/topoteretes/pgvector:pg17
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
POSTGRES_USER: cognee
POSTGRES_PASSWORD: cognee
POSTGRES_DB: cognee_db
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries=5
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ matrix.python-version }}
extra-dependencies: "postgres"
- name: Setup Neo4j with GDS
uses: ./.github/actions/setup_neo4j
id: neo4j
- name: Dependencies already installed
run: echo "Dependencies already installed in setup"
- name: Run Neo4j + PGVector + Postgres search Tests
env:
ENV: dev
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
GRAPH_DATABASE_PROVIDER: 'neo4j'
VECTOR_DB_PROVIDER: 'pgvector'
DB_PROVIDER: 'postgres'
GRAPH_DATABASE_URL: ${{ steps.neo4j.outputs.neo4j-url }}
GRAPH_DATABASE_USERNAME: ${{ steps.neo4j.outputs.neo4j-username }}
GRAPH_DATABASE_PASSWORD: ${{ steps.neo4j.outputs.neo4j-password }}
ENABLE_BACKEND_ACCESS_CONTROL: 'false'
DB_NAME: cognee_db
DB_HOST: 127.0.0.1
DB_PORT: 5432
DB_USERNAME: cognee
DB_PASSWORD: cognee
run: uv run pytest cognee/tests/test_search_db.py -v --log-level=INFO
+93
View File
@@ -0,0 +1,93 @@
name: Slow End-to-End Tests
permissions:
contents: read
packages: read
on:
workflow_call:
inputs:
python-version:
required: false
type: string
default: '3.11.x'
ci-image:
required: false
type: string
default: ''
secrets:
LLM_MODEL:
required: true
LLM_ENDPOINT:
required: true
LLM_API_KEY:
required: true
LLM_ARGS:
required: false
LLM_API_VERSION:
required: true
EMBEDDING_MODEL:
required: true
EMBEDDING_API_KEY:
required: true
env:
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
test-edge-centered-payload:
name: Test Cognify - Edge Centered Payload
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
- name: Dependencies already installed
run: echo "Dependencies already installed in setup"
- name: Run Edge Centered Payload Test
env:
ENV: 'dev'
TRIPLET_EMBEDDING: True
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./cognee/tests/test_edge_centered_payload.py
test-deletion-on-default-graph_with_legacy_data_1_default:
name: Delete default graph with legacy data test 1 in Kuzu case
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
- name: Run deletion on default graph with legacy data (Kuzu)
env:
ENV: 'dev'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
ENABLE_AUTO_MIGRATIONS: 'false'
run: uv run python ./cognee/tests/test_delete_default_graph_with_legacy_data_1.py
+169
View File
@@ -0,0 +1,169 @@
name: automation | Sync Mintlify Docs
on:
release:
types: [published]
workflow_dispatch:
permissions:
contents: read
jobs:
sync-mintlify-docs:
if: ${{ github.event_name != 'release' || github.event.release.prerelease == false }}
runs-on: ubuntu-22.04
timeout-minutes: 20
steps:
- name: Check out core repository
uses: actions/checkout@v6
with:
fetch-depth: 0
# Normalize release metadata so the sync script can run unchanged for
# published releases, manual dispatches, and branch-push preview runs.
# This step always produces a body file plus synthetic tag/url/date
# values when the event is not an actual GitHub release.
- name: Prepare release body file
id: release_meta
env:
EVENT_NAME: ${{ github.event_name }}
REF_NAME: ${{ github.ref_name }}
COMMIT_SHA: ${{ github.sha }}
RELEASE_BODY: ${{ github.event.release.body }}
RELEASE_TAG: ${{ github.event.release.tag_name }}
RELEASE_URL: ${{ github.event.release.html_url }}
RELEASE_PUBLISHED_AT: ${{ github.event.release.published_at }}
REPOSITORY: ${{ github.repository }}
SERVER_URL: ${{ github.server_url }}
run: |
BODY_FILE="$(mktemp)"
if [ "${EVENT_NAME}" = "release" ]; then
TAG="${RELEASE_TAG}"
RELEASE_LINK="${RELEASE_URL}"
PUBLISHED_AT="${RELEASE_PUBLISHED_AT}"
DOCS_BRANCH_NAME="automation/sync-mintlify-docs-${RELEASE_TAG}"
printf "%s" "${RELEASE_BODY}" > "${BODY_FILE}"
else
TAG="test-sync-${REF_NAME}-${COMMIT_SHA::7}"
RELEASE_LINK="${SERVER_URL}/${REPOSITORY}/commit/${COMMIT_SHA}"
PUBLISHED_AT="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
DOCS_BRANCH_NAME="${REF_NAME}"
printf "%s\n\n- Source commit: \`%s\`\n- Workflow event: \`%s\`\n- Commit URL: %s\n" \
"Automated docs sync test run from branch \`${REF_NAME}\`." \
"${COMMIT_SHA}" \
"${EVENT_NAME}" \
"${RELEASE_LINK}" > "${BODY_FILE}"
fi
SAFE_DOCS_BRANCH_NAME="${DOCS_BRANCH_NAME// /-}"
echo "body_file=${BODY_FILE}" >> "$GITHUB_OUTPUT"
echo "tag=${TAG}" >> "$GITHUB_OUTPUT"
echo "release_url=${RELEASE_LINK}" >> "$GITHUB_OUTPUT"
echo "published_at=${PUBLISHED_AT}" >> "$GITHUB_OUTPUT"
echo "docs_branch_name=${SAFE_DOCS_BRANCH_NAME}" >> "$GITHUB_OUTPUT"
- name: Install uv
uses: astral-sh/setup-uv@v7
- name: Install Python
run: uv python install
- name: Install dependencies
run: uv sync --locked --all-extras
- name: Check out docs repository
uses: actions/checkout@v6
with:
repository: topoteretes/cognee-docs
token: ${{ secrets.REPO_DISPATCH_PAT_TOKEN }}
ref: main
path: docs-repo
- name: Sync OpenAPI and changelog
run: |
uv run python tools/sync_release_docs.py \
--docs-repo "${GITHUB_WORKSPACE}/docs-repo" \
--tag "${{ steps.release_meta.outputs.tag }}" \
--release-url "${{ steps.release_meta.outputs.release_url }}" \
--published-at "${{ steps.release_meta.outputs.published_at }}" \
--release-body-file "${{ steps.release_meta.outputs.body_file }}"
- name: Commit docs changes
id: commit_docs
working-directory: docs-repo
run: |
BRANCH_NAME="${{ steps.release_meta.outputs.docs_branch_name }}"
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git checkout -B "${BRANCH_NAME}"
git add cognee_openapi_spec.json changelog.mdx
if git diff --cached --quiet; then
echo "changes_made=false" >> "$GITHUB_OUTPUT"
echo "branch_name=${BRANCH_NAME}" >> "$GITHUB_OUTPUT"
exit 0
fi
git commit -m "docs: sync ${{ steps.release_meta.outputs.tag }}"
echo "changes_made=true" >> "$GITHUB_OUTPUT"
echo "branch_name=${BRANCH_NAME}" >> "$GITHUB_OUTPUT"
- name: Push docs branch
if: ${{ steps.commit_docs.outputs.changes_made == 'true' }}
working-directory: docs-repo
env:
GH_TOKEN: ${{ secrets.REPO_DISPATCH_PAT_TOKEN }}
run: |
git push --force-with-lease origin "${{ steps.commit_docs.outputs.branch_name }}"
- name: Create or update docs pull request
if: ${{ steps.commit_docs.outputs.changes_made == 'true' }}
env:
GH_TOKEN: ${{ secrets.REPO_DISPATCH_PAT_TOKEN }}
EVENT_NAME: ${{ github.event_name }}
RELEASE_TAG: ${{ steps.release_meta.outputs.tag }}
RELEASE_URL: ${{ steps.release_meta.outputs.release_url }}
TARGET_REPO: topoteretes/cognee-docs
HEAD_BRANCH: ${{ steps.commit_docs.outputs.branch_name }}
run: |
if [ "${EVENT_NAME}" = "release" ]; then
PR_TITLE="docs: sync release ${RELEASE_TAG}"
PR_BODY=$(cat <<EOF
Automated sync for release \`${RELEASE_TAG}\`.
Source release: ${RELEASE_URL}
EOF
)
else
PR_TITLE="test(docs): preview sync for ${HEAD_BRANCH}"
PR_BODY=$(cat <<EOF
Automated preview sync from branch \`${HEAD_BRANCH}\`.
Source commit/revision: ${RELEASE_URL}
EOF
)
fi
HEAD_REF="topoteretes:${HEAD_BRANCH}"
EXISTING_PR_NUMBER="$(gh pr list \
--repo "${TARGET_REPO}" \
--head "${HEAD_REF}" \
--base main \
--state open \
--json number \
--jq '.[0].number // empty')"
if [ -n "${EXISTING_PR_NUMBER}" ]; then
gh pr edit "${EXISTING_PR_NUMBER}" \
--repo "${TARGET_REPO}" \
--title "${PR_TITLE}" \
--body "${PR_BODY}"
else
gh pr create \
--repo "${TARGET_REPO}" \
--base main \
--head "${HEAD_REF}" \
--title "${PR_TITLE}" \
--body "${PR_BODY}"
fi
+230
View File
@@ -0,0 +1,230 @@
name: Temporal Graph Tests
permissions:
contents: read
packages: read
on:
workflow_call:
inputs:
databases:
required: false
type: string
default: "all"
description: "Which vector databases to test (comma-separated list or 'all')"
ci-image:
required: false
type: string
default: ''
description: "Optional container image for CI"
env:
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
run_temporal_graph_kuzu_lance_sqlite:
name: Temporal Graph test Kuzu (lancedb + sqlite)
runs-on: ubuntu-22.04
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'kuzu/lance/sqlite') }}
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
- name: Dependencies already installed
run: echo "Dependencies already installed in setup"
- name: Run Temporal Graph with Kuzu (lancedb + sqlite)
env:
ENV: 'dev'
LLM_MODEL: ${{ secrets.OPENAI_MODEL }}
LLM_ENDPOINT: ${{ secrets.OPENAI_ENDPOINT }}
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
GRAPH_DATABASE_PROVIDER: 'kuzu'
VECTOR_DB_PROVIDER: 'lancedb'
DB_PROVIDER: 'sqlite'
run: uv run python ./cognee/tests/test_temporal_graph.py
run_temporal_graph_neo4j_lance_sqlite:
name: Temporal Graph test Neo4j (lancedb + sqlite)
runs-on: ubuntu-22.04
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'neo4j/lance/sqlite') }}
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
- name: Setup Neo4j with GDS
uses: ./.github/actions/setup_neo4j
id: neo4j
- name: Dependencies already installed
run: echo "Dependencies already installed in setup"
- name: Run Temporal Graph with Neo4j (lancedb + sqlite)
env:
ENV: 'dev'
ENABLE_BACKEND_ACCESS_CONTROL: 'false'
LLM_MODEL: ${{ secrets.OPENAI_MODEL }}
LLM_ENDPOINT: ${{ secrets.OPENAI_ENDPOINT }}
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
GRAPH_DATABASE_PROVIDER: 'neo4j'
VECTOR_DB_PROVIDER: 'lancedb'
DB_PROVIDER: 'sqlite'
GRAPH_DATABASE_URL: ${{ steps.neo4j.outputs.neo4j-url }}
GRAPH_DATABASE_USERNAME: ${{ steps.neo4j.outputs.neo4j-username }}
GRAPH_DATABASE_PASSWORD: ${{ steps.neo4j.outputs.neo4j-password }}
run: uv run python ./cognee/tests/test_temporal_graph.py
run_temporal_graph_kuzu_postgres_pgvector:
name: Temporal Graph test Kuzu (postgres + pgvector)
runs-on: ubuntu-22.04
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'kuzu/pgvector/postgres') }}
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
services:
postgres:
image: ghcr.io/topoteretes/pgvector:pg17
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
POSTGRES_USER: cognee
POSTGRES_PASSWORD: cognee
POSTGRES_DB: cognee_db
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
extra-dependencies: "postgres"
- name: Dependencies already installed
run: echo "Dependencies already installed in setup"
- name: Run Temporal Graph with Kuzu (postgres + pgvector)
env:
ENV: dev
ENABLE_BACKEND_ACCESS_CONTROL: 'false'
LLM_MODEL: ${{ secrets.OPENAI_MODEL }}
LLM_ENDPOINT: ${{ secrets.OPENAI_ENDPOINT }}
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
GRAPH_DATABASE_PROVIDER: 'kuzu'
VECTOR_DB_PROVIDER: 'pgvector'
DB_PROVIDER: 'postgres'
DB_NAME: 'cognee_db'
DB_HOST: ${{ inputs.ci-image != '' && 'postgres' || '127.0.0.1' }}
DB_PORT: 5432
DB_USERNAME: cognee
DB_PASSWORD: cognee
run: uv run python ./cognee/tests/test_temporal_graph.py
run_temporal_graph_neo4j_postgres_pgvector:
name: Temporal Graph test Neo4j (postgres + pgvector)
runs-on: ubuntu-22.04
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'neo4j/pgvector/postgres') }}
services:
neo4j:
image: neo4j:5.11
env:
NEO4J_AUTH: neo4j/pleaseletmein
NEO4J_PLUGINS: '["apoc","graph-data-science"]'
ports:
- 7474:7474
- 7687:7687
options: >-
--health-cmd="cypher-shell -u neo4j -p pleaseletmein 'RETURN 1'"
--health-interval=10s
--health-timeout=5s
--health-retries=5
postgres:
image: ghcr.io/topoteretes/pgvector:pg17
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
POSTGRES_USER: cognee
POSTGRES_PASSWORD: cognee
POSTGRES_DB: cognee_db
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries=5
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
extra-dependencies: "postgres"
- name: Dependencies already installed
run: echo "Dependencies already installed in setup"
- name: Run Temporal Graph with Neo4j (postgres + pgvector)
env:
ENV: dev
ENABLE_BACKEND_ACCESS_CONTROL: 'false'
LLM_MODEL: ${{ secrets.OPENAI_MODEL }}
LLM_ENDPOINT: ${{ secrets.OPENAI_ENDPOINT }}
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
GRAPH_DATABASE_PROVIDER: 'neo4j'
VECTOR_DB_PROVIDER: 'pgvector'
DB_PROVIDER: 'postgres'
GRAPH_DATABASE_URL: bolt://localhost:7687
GRAPH_DATABASE_USERNAME: neo4j
GRAPH_DATABASE_PASSWORD: pleaseletmein
DB_NAME: cognee_db
DB_HOST: 127.0.0.1
DB_PORT: 5432
DB_USERNAME: cognee
DB_PASSWORD: cognee
run: uv run python ./cognee/tests/test_temporal_graph.py
@@ -0,0 +1,220 @@
name: Tests to run on different Operating Systems
permissions:
contents: read
on:
workflow_call:
inputs:
python-versions:
required: false
type: string
default: '["3.10.x", "3.12.x", "3.13.x"]'
os:
required: false
type: string
default: '["ubuntu-22.04", "macos-15", "windows-latest"]'
extra-dependencies:
# Space-separated package extras for the unit-test job (e.g. "postgres").
# Driver-dependent tests importorskip when their extra is absent.
required: false
type: string
default: ''
secrets:
LLM_PROVIDER:
required: true
LLM_MODEL:
required: true
LLM_ENDPOINT:
required: true
LLM_API_KEY:
required: true
LLM_ARGS:
required: false
LLM_API_VERSION:
required: true
EMBEDDING_PROVIDER:
required: true
EMBEDDING_MODEL:
required: true
EMBEDDING_API_KEY:
required: true
env:
RUNTIME__LOG_LEVEL: ERROR
ENV: 'dev'
jobs:
run-unit-tests:
name: Unit tests ${{ matrix.python-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
matrix:
python-version: ${{ fromJSON(inputs.python-versions) }}
os: ${{ fromJSON(inputs.os) }}
fail-fast: false
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ matrix.python-version }}
extra-dependencies: ${{ inputs.extra-dependencies }}
- name: Run unit tests
shell: bash
run: uv run pytest cognee/tests/unit/ --timeout=300 --timeout-method=thread
env:
PYTHONUTF8: 1
LLM_PROVIDER: openai
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_PROVIDER: openai
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run-library-test:
name: Library test ${{ matrix.python-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
matrix:
python-version: ${{ fromJSON(inputs.python-versions) }}
os: ${{ fromJSON(inputs.os) }}
fail-fast: false
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ matrix.python-version }}
- name: Run default basic pipeline
shell: bash
env:
PYTHONUTF8: 1
LLM_PROVIDER: openai
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_PROVIDER: openai
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./cognee/tests/test_library.py
run-build-test:
name: Build test ${{ matrix.python-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
matrix:
python-version: ${{ fromJSON(inputs.python-versions) }}
os: ${{ fromJSON(inputs.os) }}
fail-fast: false
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ matrix.python-version }}
- name: Build with uv
shell: bash
run: uv build
- name: Install Package
if: ${{ !contains(matrix.os, 'windows-latest') }}
run: |
cd dist
pip install *.whl
run-soft-deletion-test:
name: Soft Delete test ${{ matrix.python-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
matrix:
python-version: ${{ fromJSON(inputs.python-versions) }}
os: ${{ fromJSON(inputs.os) }}
fail-fast: false
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ matrix.python-version }}
- name: Path setup
if: ${{ matrix.os == 'windows-latest' }}
shell: bash
run: |
PATH=$(printf '%s' "$PATH" | tr ':' $'\n' | grep -vi '/git/usr/bin' | paste -sd: -)
export PATH
- name: Run Soft Deletion Tests
env:
ENV: 'dev'
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }} # Test needs OpenAI endpoint to handle multimedia
LLM_ARGS: ${{ secrets.LLM_ARGS }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./cognee/tests/test_delete_default_graph.py
run-hard-deletion-test:
name: Custom Graph Delete test ${{ matrix.python-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
matrix:
python-version: ${{ fromJSON(inputs.python-versions) }}
os: ${{ fromJSON(inputs.os) }}
fail-fast: false
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ matrix.python-version }}
- name: Run Custom Graph Deletion Test
env:
ENV: 'dev'
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }} # Test needs OpenAI endpoint to handle multimedia
LLM_ARGS: ${{ secrets.LLM_ARGS }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./cognee/tests/test_delete_custom_graph.py
+61
View File
@@ -0,0 +1,61 @@
name: test | ollama
on:
workflow_call:
env:
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
run_llama-cpp_test:
# needs ~4 Gb RAM for the GGUF model in a container which the smallest runner has
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.13.x'
extra-dependencies: postgres llama-cpp
- name: Install torch dependency
run: |
uv add torch
- name: Download Phi-3.5 GGUF model from S3
# Mirrored from huggingface.co/bartowski/Phi-3.5-mini-instruct-GGUF (MIT)
# into our bucket to avoid HuggingFace 429 rate limits in CI.
# Phi-3.5-mini reliably emits the required per-node `description`;
# the previous Phi-3-mini-q4 dropped it, failing extraction.
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_S3_DEV_USER_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_S3_DEV_USER_SECRET_KEY }}
AWS_DEFAULT_REGION: eu-west-1
BUCKET: github-runner-cognee-tests
MODEL_KEY: nightly_ci_artifacts/huggingface_models/Phi-3.5-mini-instruct-Q4_K_M.gguf
MODEL_SHA256: e4165e3a71af97f1b4820da61079826d8752a2088e313af0c7d346796c38eff5
run: |
set -euo pipefail
aws s3 cp "s3://$BUCKET/$MODEL_KEY" ./Phi-3.5-mini-instruct-Q4_K_M.gguf
echo "$MODEL_SHA256 ./Phi-3.5-mini-instruct-Q4_K_M.gguf" | sha256sum -c -
- name: Run example test
env:
PYTHONFAULTHANDLER: 1
LLM_PROVIDER: "llama_cpp"
LLAMA_CPP_MODEL_PATH: "./Phi-3.5-mini-instruct-Q4_K_M.gguf"
LLM_ENDPOINT: ""
LLAMA_CPP_N_CTX: 4096
EMBEDDING_PROVIDER: "openai"
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
EMBEDDING_MODEL: "openai/text-embedding-3-large"
EMBEDDING_DIMENSIONS: "3072"
EMBEDDING_MAX_TOKENS: "8191"
STRUCTURED_OUTPUT_FRAMEWORK: "instructor"
LLM_INSTRUCTOR_MODE: ""
run: uv run python ./examples/demos/simple_cognee_example.py
+220
View File
@@ -0,0 +1,220 @@
name: LLM Test Suites
permissions:
contents: read
packages: read
on:
workflow_call:
inputs:
ci-image:
required: false
type: string
default: ''
env:
RUNTIME__LOG_LEVEL: ERROR
ENV: 'dev'
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
test-gemini:
name: Run Gemini Test
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
- name: Run Gemini Simple Example
env:
LLM_PROVIDER: "gemini"
LLM_API_KEY: ${{ secrets.GEMINI_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_MODEL: "gemini/gemini-3-flash-preview"
EMBEDDING_PROVIDER: "gemini"
EMBEDDING_API_KEY: ${{ secrets.GEMINI_API_KEY }}
EMBEDDING_MODEL: "gemini/gemini-embedding-001"
EMBEDDING_DIMENSIONS: "768"
EMBEDDING_MAX_TOKENS: "8076"
run: uv run python ./examples/demos/simple_cognee_example.py
test-fastembed:
name: Run Fastembed Test
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
- name: Run Fastembed Simple Example
env:
LLM_PROVIDER: "openai"
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_PROVIDER: "fastembed"
EMBEDDING_MODEL: "sentence-transformers/all-MiniLM-L6-v2"
EMBEDDING_DIMENSIONS: "384"
EMBEDDING_MAX_TOKENS: "256"
run: uv run python ./examples/demos/simple_cognee_example.py
test-openrouter:
name: Run OpenRouter Test
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
- name: Run OpenRouter Simple Example
env:
LLM_PROVIDER: "custom"
LLM_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_MODEL: "openrouter/x-ai/grok-4.3"
LLM_ENDPOINT: "https://openrouter.ai/api/v1"
EMBEDDING_PROVIDER: "openai"
EMBEDDING_API_KEY: ${{ secrets.OPENAI_API_KEY }}
EMBEDDING_MODEL: "openai/text-embedding-3-large"
EMBEDDING_DIMENSIONS: "3072"
EMBEDDING_MAX_TOKENS: "8191"
run: uv run python ./examples/demos/simple_cognee_example.py
test-bedrock-api-key:
name: Run Bedrock API Key Test
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
extra-dependencies: "aws"
- name: Run Bedrock API Key Simple Example
env:
LLM_PROVIDER: "bedrock"
LLM_API_KEY: ${{ secrets.BEDROCK_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_MODEL: "eu.anthropic.claude-sonnet-4-5-20250929-v1:0"
LLM_MAX_TOKENS: "16384"
AWS_REGION_NAME: "eu-west-1"
EMBEDDING_PROVIDER: "bedrock"
EMBEDDING_API_KEY: ${{ secrets.BEDROCK_API_KEY }}
EMBEDDING_MODEL: "amazon.titan-embed-text-v2:0"
EMBEDDING_DIMENSIONS: "1024"
EMBEDDING_MAX_TOKENS: "8191"
run: uv run python ./examples/demos/simple_cognee_example.py
test-bedrock-aws-credentials:
name: Run Bedrock AWS Credentials Test
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
extra-dependencies: "aws"
- name: Run Bedrock AWS Credentials Simple Example
env:
LLM_PROVIDER: "bedrock"
LLM_MODEL: "eu.anthropic.claude-sonnet-4-5-20250929-v1:0"
LLM_MAX_TOKENS: "16384"
AWS_REGION_NAME: "eu-west-1"
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
EMBEDDING_PROVIDER: "bedrock"
EMBEDDING_API_KEY: ${{ secrets.BEDROCK_API_KEY }}
EMBEDDING_MODEL: "amazon.titan-embed-text-v2:0"
EMBEDDING_DIMENSIONS: "1024"
EMBEDDING_MAX_TOKENS: "8191"
run: uv run python ./examples/demos/simple_cognee_example.py
test-bedrock-aws-profile:
name: Run Bedrock AWS Profile Test
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
extra-dependencies: "aws"
- name: Configure AWS Profile
run: |
mkdir -p ~/.aws
cat > ~/.aws/credentials << EOF
[bedrock-test]
aws_access_key_id = ${{ secrets.AWS_ACCESS_KEY_ID }}
aws_secret_access_key = ${{ secrets.AWS_SECRET_ACCESS_KEY }}
EOF
- name: Run Bedrock AWS Profile Simple Example
env:
LLM_PROVIDER: "bedrock"
LLM_MODEL: "eu.anthropic.claude-sonnet-4-5-20250929-v1:0"
LLM_MAX_TOKENS: "16384"
AWS_PROFILE_NAME: "bedrock-test"
AWS_REGION_NAME: "eu-west-1"
EMBEDDING_PROVIDER: "bedrock"
EMBEDDING_MODEL: "amazon.titan-embed-text-v2:0"
EMBEDDING_DIMENSIONS: "1024"
EMBEDDING_MAX_TOKENS: "8191"
run: uv run python ./examples/demos/simple_cognee_example.py
test-claude-anthropic:
name: Run Anthropic Claude LLM Test
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
- name: Run Claude Anthropic LLM Simple Example
env:
LLM_PROVIDER: "anthropic"
# Note: If model becomes outdated update docs with new model as well
LLM_MODEL: "anthropic/claude-sonnet-4-5-20250929"
LLM_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_MAX_TOKENS: "16384"
EMBEDDING_API_KEY: ${{ secrets.OPENAI_API_KEY }}
EMBEDDING_MODEL: "openai/text-embedding-3-large"
EMBEDDING_DIMENSIONS: "3072"
EMBEDDING_MAX_TOKENS: "8191"
run: uv run python ./examples/demos/simple_cognee_example.py
+64
View File
@@ -0,0 +1,64 @@
name: test | mcp
on:
workflow_call:
inputs:
cognee_version:
required: false
type: string
default: "local" # local - Installing Cognee from local source
description: "Pypi-compatible version of cognee to use. For example, 0.5.2.dev0. `local` (default) - Installing Cognee from local source"
env:
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
test-mcp:
name: Run MCP Test
runs-on: ubuntu-22.04
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ inputs.python-version }}
- name: Install UV
shell: bash
run: |
python -m pip install --upgrade pip
pip install uv
- name: Install dependencies
shell: bash
working-directory: cognee-mcp
run: uv sync
- name: Install Cognee
uses: ./.github/actions/install_cognee
with:
python-version: ${{ inputs.python-version }}
cognee_version: ${{ inputs.cognee_version }}
- name: Run MCP unit tests
working-directory: cognee-mcp
run: uv run --no-sync pytest tests/
- name: Run MCP test
env:
ENV: 'dev'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
working-directory: cognee-mcp
run: |
echo "Cognee Version:"
uv pip show cognee | grep Version
uv run --no-sync python ./src/test_client.py
+111
View File
@@ -0,0 +1,111 @@
name: test | ollama
on:
workflow_call:
env:
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
run_ollama_test:
# TODO: needs 32 Gb RAM for phi4 in a container — GitHub-hosted larger runner
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
- name: Install torch dependency
run: |
uv add torch
- name: Start Ollama container
run: |
docker run -d --name ollama -p 11434:11434 ollama/ollama
sleep 5
docker exec -d ollama bash -c "ollama serve --openai"
- name: Check Ollama logs
run: docker logs ollama
- name: Wait for Ollama to be ready
run: |
for i in {1..30}; do
if curl -s http://localhost:11434/v1/models > /dev/null; then
echo "Ollama is ready"
exit 0
fi
echo "Waiting for Ollama... attempt $i"
sleep 2
done
echo "Ollama failed to start"
exit 1
- name: Pull required Ollama models
run: |
curl -X POST http://localhost:11434/api/pull -d '{"name": "phi4"}'
curl -X POST http://localhost:11434/api/pull -d '{"name": "qwen3-embedding:latest"}'
- name: Call ollama API
run: |
curl -X POST http://localhost:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "phi4",
"stream": false,
"messages": [
{ "role": "system", "content": "You are a helpful assistant." },
{ "role": "user", "content": "Whatever I say, answer with Yes." }
]
}'
curl -X POST http://127.0.0.1:11434/api/embed \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3-embedding:latest",
"input": "This is a test sentence to generate an embedding."
}'
- name: Dump Docker logs
run: |
docker ps
docker logs $(docker ps --filter "ancestor=ollama/ollama" --format "{{.ID}}")
- name: Download embedding tokenizer from S3
# Mirrored from huggingface.co/Qwen/Qwen3-Embedding-8B (Apache-2.0) so the
# embedding tokenizer loads offline and never hits HuggingFace 429s in CI.
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_S3_DEV_USER_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_S3_DEV_USER_SECRET_KEY }}
AWS_DEFAULT_REGION: eu-west-1
BUCKET: github-runner-cognee-tests
TOKENIZER_KEY: nightly_ci_artifacts/huggingface_models/qwen3-embedding-tokenizer.tar.gz
TOKENIZER_SHA256: 8f5834d8791c8da03220feaccc2fe9c443e23b1092dcd99c576ef613990bbd00
run: |
set -euo pipefail
aws s3 cp "s3://$BUCKET/$TOKENIZER_KEY" tokenizer.tar.gz
echo "$TOKENIZER_SHA256 tokenizer.tar.gz" | sha256sum -c -
tar -xzf tokenizer.tar.gz -C "$GITHUB_WORKSPACE"
- name: Run example test
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
PYTHONFAULTHANDLER: 1
LLM_PROVIDER: "ollama"
LLM_API_KEY: "ollama"
LLM_ENDPOINT: "http://localhost:11434/v1/"
LLM_MODEL: "phi4"
EMBEDDING_PROVIDER: "ollama"
EMBEDDING_MODEL: "qwen3-embedding:latest"
EMBEDDING_ENDPOINT: "http://localhost:11434/api/embed"
EMBEDDING_DIMENSIONS: "4096"
# Load the tokenizer from the S3-mirrored local dir, fully offline.
HUGGINGFACE_TOKENIZER: "${{ github.workspace }}/qwen3-embedding-tokenizer"
HF_HUB_OFFLINE: "1"
TRANSFORMERS_OFFLINE: "1"
run: uv run python ./examples/demos/simple_cognee_example.py
@@ -0,0 +1,52 @@
name: test | s3 file storage
on:
workflow_call:
inputs:
ci-image:
required: false
type: string
default: ''
permissions:
contents: read
packages: read
env:
RUNTIME__LOG_LEVEL: ERROR
ENV: 'dev'
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
test-s3-storage:
name: Run S3 File Storage Test
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11.x'
extra-dependencies: "aws"
- name: Run S3 File Storage Test
env:
STORAGE_BACKEND: s3
ENABLE_BACKEND_ACCESS_CONTROL: True
AWS_REGION: eu-west-1
AWS_ENDPOINT_URL: https://s3-eu-west-1.amazonaws.com
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_S3_DEV_USER_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_S3_DEV_USER_SECRET_KEY }}
STORAGE_BUCKET_NAME: github-runner-cognee-tests
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./cognee/tests/test_s3_file_storage.py
+413
View File
@@ -0,0 +1,413 @@
name: Test Suites
permissions:
contents: read
packages: write
on:
push:
branches: [ main, dev ]
pull_request:
branches: [ main, dev ]
types: [opened, synchronize, reopened, labeled]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
env:
RUNTIME__LOG_LEVEL: ERROR
ENV: 'dev'
jobs:
# ── Build pre-baked CI container ──────────────────────────────────────
build-ci-env:
name: Build CI Environment
runs-on: ubuntu-latest
if: >-
github.event_name == 'push' || github.event_name == 'workflow_dispatch' ||
(github.event_name == 'pull_request' &&
github.event.pull_request.head.repo.full_name == github.repository)
outputs:
ci-image: ${{ steps.set-image.outputs.image }}
steps:
- name: Sparse checkout (deps only)
uses: actions/checkout@v6
with:
sparse-checkout: |
pyproject.toml
uv.lock
README.md
Dockerfile.ci
.dockerignore.ci
sparse-checkout-cone-mode: false
- name: Compute dep hash and image tag
id: set-image
run: |
DEP_HASH=$(sha256sum pyproject.toml uv.lock | sha256sum | head -c 16)
IMAGE="ghcr.io/${{ github.repository }}/ci-env:deps-${DEP_HASH}"
echo "image=${IMAGE}" >> "$GITHUB_OUTPUT"
echo "dep_hash=${DEP_HASH}" >> "$GITHUB_OUTPUT"
echo "Image tag: ${IMAGE}"
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Check if image already exists
id: check
run: |
if docker manifest inspect "${{ steps.set-image.outputs.image }}" > /dev/null 2>&1; then
echo "exists=true" >> "$GITHUB_OUTPUT"
echo "Image already exists, skipping build."
else
echo "exists=false" >> "$GITHUB_OUTPUT"
echo "Image not found, will build."
fi
- name: Set up Docker Buildx
if: steps.check.outputs.exists != 'true'
uses: docker/setup-buildx-action@v3
- name: Build and push CI image
if: steps.check.outputs.exists != 'true'
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile.ci
push: true
tags: ${{ steps.set-image.outputs.image }}
cache-from: type=registry,ref=ghcr.io/${{ github.repository }}/ci-env:buildcache
cache-to: type=registry,ref=ghcr.io/${{ github.repository }}/ci-env:buildcache,mode=max
pre-test:
name: basic checks
uses: ./.github/workflows/pre_test.yml
basic-tests:
name: Basic Tests
uses: ./.github/workflows/basic_tests.yml
needs: [ build-ci-env ]
if: ${{ !cancelled() }}
with:
ci-image: ${{ needs.build-ci-env.outputs.ci-image || '' }}
secrets: inherit
e2e-tests:
name: End-to-End Tests
uses: ./.github/workflows/e2e_tests.yml
needs: [ build-ci-env ]
if: ${{ !cancelled() }}
with:
ci-image: ${{ needs.build-ci-env.outputs.ci-image || '' }}
secrets: inherit
cli-tests:
name: CLI Tests
uses: ./.github/workflows/cli_tests.yml
needs: [ build-ci-env ]
if: ${{ !cancelled() }}
with:
ci-image: ${{ needs.build-ci-env.outputs.ci-image || '' }}
secrets: inherit
slow-e2e-tests:
name: Slow End-to-End Tests
uses: ./.github/workflows/slow_e2e_tests.yml
needs: [ build-ci-env ]
if: ${{ !cancelled() }}
with:
ci-image: ${{ needs.build-ci-env.outputs.ci-image || '' }}
secrets: inherit
graph-db-tests:
name: Graph Database Tests
needs: [ build-ci-env ]
if: ${{ !cancelled() }}
uses: ./.github/workflows/graph_db_tests.yml
with:
ci-image: ${{ needs.build-ci-env.outputs.ci-image || '' }}
secrets: inherit
vector-db-tests:
name: Vector DB Tests
needs: [ build-ci-env ]
if: ${{ !cancelled() }}
uses: ./.github/workflows/vector_db_tests.yml
with:
ci-image: ${{ needs.build-ci-env.outputs.ci-image || '' }}
secrets: inherit
example-tests:
name: Example Tests
needs: [ build-ci-env ]
if: ${{ !cancelled() }}
uses: ./.github/workflows/examples_tests.yml
with:
ci-image: ${{ needs.build-ci-env.outputs.ci-image || '' }}
secrets: inherit
notebook-tests:
name: Notebook Tests
needs: [ build-ci-env ]
if: ${{ !cancelled() }}
uses: ./.github/workflows/notebooks_tests.yml
with:
ci-image: ${{ needs.build-ci-env.outputs.ci-image || '' }}
secrets: inherit
different-os-tests-basic:
name: OS and Python Tests Ubuntu
uses: ./.github/workflows/test_different_operating_systems.yml
with:
python-versions: '["3.10.x", "3.11.x", "3.12.x", "3.13.x", "3.14.x"]'
os: '["ubuntu-22.04"]'
# postgres so the SQL cache adapter tests run instead of skipping; omitted
# on macos/windows (extended) where psycopg2 has no prebuilt wheels.
extra-dependencies: 'postgres'
secrets: inherit
different-os-tests-extended:
name: OS and Python Tests Extended
uses: ./.github/workflows/test_different_operating_systems.yml
with:
python-versions: '["3.13.x"]'
os: '["macos-15", "windows-latest"]'
secrets: inherit
llm-tests:
name: LLM Test Suite
needs: [ build-ci-env ]
if: ${{ !cancelled() }}
uses: ./.github/workflows/test_llms.yml
with:
ci-image: ${{ needs.build-ci-env.outputs.ci-image || '' }}
secrets: inherit
s3-file-storage-test:
name: S3 File Storage Test
needs: [ build-ci-env ]
if: ${{ !cancelled() }}
uses: ./.github/workflows/test_s3_file_storage.yml
with:
ci-image: ${{ needs.build-ci-env.outputs.ci-image || '' }}
secrets: inherit
integration-tests:
name: Run Integration Tests
needs: [ build-ci-env ]
if: ${{ !cancelled() }}
uses: ./.github/workflows/integration_tests.yml
with:
ci-image: ${{ needs.build-ci-env.outputs.ci-image || '' }}
secrets: inherit
mcp-test:
name: MCP Tests
uses: ./.github/workflows/test_mcp.yml
secrets: inherit
docker-compose-test:
name: Docker Compose Test
uses: ./.github/workflows/docker_compose.yml
secrets: inherit
docker-ci-test:
name: Docker CI test
uses: ./.github/workflows/backend_docker_build_test.yml
secrets: inherit
temporal-graph-tests:
name: Temporal Graph Test
needs: [ build-ci-env ]
if: ${{ !cancelled() }}
uses: ./.github/workflows/temporal_graph_tests.yml
with:
ci-image: ${{ needs.build-ci-env.outputs.ci-image || '' }}
secrets: inherit
search-db-tests:
name: Search Test on Different DBs
needs: [ build-ci-env ]
if: ${{ !cancelled() }}
uses: ./.github/workflows/search_db_tests.yml
with:
ci-image: ${{ needs.build-ci-env.outputs.ci-image || '' }}
secrets: inherit
relational-db-migration-tests:
name: Relational DB Migration Tests
needs: [ build-ci-env ]
if: ${{ !cancelled() }}
uses: ./.github/workflows/relational_db_migration_tests.yml
with:
ci-image: ${{ needs.build-ci-env.outputs.ci-image || '' }}
secrets: inherit
# NOTE: intentionally excluded from the `notify` aggregator below — this is
# external infra (Modal + Azure secrets), informational only; it must not gate
# merges. (`continue-on-error` is not allowed on a reusable-workflow job.)
distributed-tests:
name: Distributed Cognee Test
needs: [ build-ci-env ]
if: ${{ !cancelled() }}
uses: ./.github/workflows/distributed_test.yml
with:
ci-image: ${{ needs.build-ci-env.outputs.ci-image || '' }}
secrets: inherit
db-examples-tests:
name: DB Examples Tests
needs: [ build-ci-env ]
if: ${{ !cancelled() }}
uses: ./.github/workflows/db_examples_tests.yml
with:
ci-image: ${{ needs.build-ci-env.outputs.ci-image || '' }}
secrets: inherit
notify:
name: Test Completion Status
needs: [
pre-test,
basic-tests,
e2e-tests,
cli-tests,
slow-e2e-tests,
graph-db-tests,
vector-db-tests,
example-tests,
notebook-tests,
different-os-tests-basic,
different-os-tests-extended,
llm-tests,
s3-file-storage-test,
integration-tests,
mcp-test,
docker-compose-test,
docker-ci-test,
temporal-graph-tests,
search-db-tests,
relational-db-migration-tests,
db-examples-tests,
]
runs-on: ubuntu-latest
if: ${{ !cancelled() }}
steps:
- name: Check Status
run: |
if [[ "${{ needs.pre-test.result }}" == "success" &&
"${{ needs.basic-tests.result }}" == "success" &&
"${{ needs.e2e-tests.result }}" == "success" &&
"${{ needs.cli-tests.result }}" == "success" &&
"${{ needs.slow-e2e-tests.result }}" == "success" &&
"${{ needs.graph-db-tests.result }}" == "success" &&
"${{ needs.vector-db-tests.result }}" == "success" &&
"${{ needs.example-tests.result }}" == "success" &&
"${{ needs.notebook-tests.result }}" == "success" &&
"${{ needs.different-os-tests-basic.result }}" == "success" &&
"${{ needs.different-os-tests-extended.result }}" == "success" &&
"${{ needs.llm-tests.result }}" == "success" &&
"${{ needs.s3-file-storage-test.result }}" == "success" &&
"${{ needs.integration-tests.result }}" == "success" &&
"${{ needs.mcp-test.result }}" == "success" &&
"${{ needs.docker-compose-test.result }}" == "success" &&
"${{ needs.docker-ci-test.result }}" == "success" &&
"${{ needs.temporal-graph-tests.result }}" == "success" &&
"${{ needs.search-db-tests.result }}" == "success" &&
"${{ needs.relational-db-migration-tests.result }}" == "success" &&
"${{ needs.db-examples-tests.result }}" == "success" ]]; then
echo "All test suites completed successfully!"
else
echo "One or more test suites failed."
exit 1
fi
# ── Advisory Claude Code review — pulls the private skill from cognee-ci at runtime ──
# The rubric + Slack map live in the private cognee-ci repo; this job carries no review
# logic. Runs only after the suite is green (needs: notify), core-team PRs only, advisory.
claude-review:
name: Claude Code Review
needs: [ notify ]
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository }}
runs-on: ubuntu-latest
continue-on-error: true
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout PR
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Core-team gate
id: gate
env:
AUTHOR: ${{ github.event.pull_request.user.login }}
run: |
author_lc="$(printf '%s' "$AUTHOR" | tr '[:upper:]' '[:lower:]')"
if grep -vE '^[[:space:]]*#' .github/core-team.txt \
| sed 's/^@//' | tr '[:upper:]' '[:lower:]' | grep -qxF "$author_lc"; then
echo "run=true" >> "$GITHUB_OUTPUT"
else
echo "run=false" >> "$GITHUB_OUTPUT"
echo "PR author '$AUTHOR' not in core-team.txt — skipping."
fi
- name: Mint private-repo token
if: ${{ steps.gate.outputs.run == 'true' }}
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.CI_APP_ID }}
private-key: ${{ secrets.CI_APP_PRIVATE_KEY }}
owner: ${{ github.repository_owner }}
repositories: cognee-ci
- name: Fetch private review skill + slack map
if: ${{ steps.gate.outputs.run == 'true' }}
uses: actions/checkout@v6
with:
repository: ${{ github.repository_owner }}/cognee-ci
token: ${{ steps.app-token.outputs.token }}
path: .ci-private
- name: Stage skill into the user skills dir
if: ${{ steps.gate.outputs.run == 'true' }}
run: |
# Stage into the USER skills dir ($HOME/.claude), NOT the repo's .claude/.
# claude-code-action sanitizes the repo .claude for untrusted PR heads
# (it moves the working-tree .claude to .claude-pr/ and restores a clean
# .claude from the base branch), which wipes the staged private skill and
# leaves /pr-review unresolved -> 0 turns, nothing posted. $HOME/.claude is
# untouched by that sanitization and is loaded via settingSources: [user,...].
mkdir -p "$HOME/.claude/skills"
cp -r .ci-private/.claude/skills/pr-review "$HOME/.claude/skills/"
- name: Claude Code review
if: ${{ steps.gate.outputs.run == 'true' }}
uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
prompt: "/pr-review"
claude_args: >-
--allowed-tools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Read,Glob,Grep"
--max-turns 20
--model claude-sonnet-4-5-20250929
- name: DM review summary to PR author on Slack
if: ${{ steps.gate.outputs.run == 'true' }}
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
AUTHOR: ${{ github.event.pull_request.user.login }}
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_URL: ${{ github.event.pull_request.html_url }}
PR_TITLE: ${{ github.event.pull_request.title }}
REPO: ${{ github.repository }}
run: python3 .ci-private/scripts/pr_review_slack_notify.py
+37
View File
@@ -0,0 +1,37 @@
name: community | contributors leaderboard
on:
schedule:
- cron: "0 0 * * 1" # Runs every Monday
workflow_dispatch: # Allows manual trigger
jobs:
update-contributors:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v6
- name: Generate Contributor List
run: |
echo "## 💫 Contributors" > CONTRIBUTORS.md
echo "" >> CONTRIBUTORS.md
echo "Thanks to our amazing contributors! 💖" >> CONTRIBUTORS.md
echo "" >> CONTRIBUTORS.md
echo '<a href="https://github.com/topoteretes/cognee/graphs/contributors">' >> CONTRIBUTORS.md
echo ' <img src="https://contrib.rocks/image?repo=topoteretes/cognee" />' >> CONTRIBUTORS.md
echo '</a>' >> CONTRIBUTORS.md
echo "" >> CONTRIBUTORS.md
echo "## 🏆 Top Contributors" >> CONTRIBUTORS.md
echo "" >> CONTRIBUTORS.md
echo "| Rank | Contributor | Contributions |" >> CONTRIBUTORS.md
echo "|------|------------|---------------|" >> CONTRIBUTORS.md
git shortlog -sne | sort -rn | head -10 | awk '{print "| "NR" | ["$2"](https://github.com/"$2") | "$1" Commits |"}' >> CONTRIBUTORS.md
- name: Commit and Push Changes
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions@users.noreply.github.com"
git add CONTRIBUTORS.md
git commit -m "Update contributors list"
git push
+153
View File
@@ -0,0 +1,153 @@
name: Reusable Vector DB Tests
on:
workflow_call:
inputs:
databases:
required: false
type: string
default: "all"
description: "Which vector databases to test (comma-separated list or 'all')"
ci-image:
required: false
type: string
default: ''
secrets:
POSTGRES_PASSWORD:
required: false
env:
COGNEE_SKIP_CONNECTION_TEST: 'true'
jobs:
run-postgres-tests:
name: PostgreSQL Tests
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'postgres') }}
services:
postgres:
image: ghcr.io/topoteretes/pgvector:pg17
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
POSTGRES_USER: cognee
POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
POSTGRES_DB: cognee_db
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
extra-dependencies: "postgres"
- name: Run PGVector Tests
env:
ENV: 'dev'
ENABLE_BACKEND_ACCESS_CONTROL: 'false'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
DB_HOST: ${{ inputs.ci-image != '' && 'postgres' || '127.0.0.1' }}
run: uv run python ./cognee/tests/test_pgvector.py
run-pgvector-multi-user-tests:
name: PGVector Multi-User Tests
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
if: ${{ inputs.databases == 'all' || contains(inputs.databases, 'postgres') }}
services:
postgres:
image: ghcr.io/topoteretes/pgvector:pg17
credentials:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
env:
POSTGRES_USER: cognee
POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
POSTGRES_DB: cognee_db
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
extra-dependencies: "postgres"
- name: Run PGVector Permissions Tests
env:
ENV: 'dev'
ENABLE_BACKEND_ACCESS_CONTROL: 'true'
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
VECTOR_DB_HOST: ${{ inputs.ci-image != '' && 'postgres' || '127.0.0.1' }}
VECTOR_DB_PORT: 5432
VECTOR_DB_USERNAME: cognee
VECTOR_DB_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
VECTOR_DATASET_DATABASE_HANDLER: pgvector
run: uv run python ./cognee/tests/test_permissions.py
run-lancedb-tests:
name: LanceDB Tests
runs-on: ubuntu-22.04
container: ${{ inputs.ci-image != '' && fromJSON(format('{{"image":"{0}","credentials":{{"username":"{1}","password":"{2}"}}}}', inputs.ci-image, github.actor, github.token)) || null }}
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ inputs.python-version }}
- name: Run LanceDB Tests
env:
ENV: 'dev'
# Cap cached DB adapters
DATABASE_MAX_LRU_CACHE_SIZE: 1
LLM_MODEL: ${{ secrets.LLM_MODEL }}
LLM_ENDPOINT: ${{ secrets.LLM_ENDPOINT }}
LLM_API_KEY: ${{ secrets.LLM_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: ${{ secrets.LLM_API_VERSION }}
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
run: uv run python ./cognee/tests/test_lancedb.py
+169
View File
@@ -0,0 +1,169 @@
name: Weighted Edges Tests
on:
push:
branches: [ main, dev, weighted_edges]
paths:
- 'cognee/modules/graph/utils/get_graph_from_model.py'
- 'cognee/infrastructure/engine/models/Edge.py'
- 'cognee/tests/unit/interfaces/graph/test_weighted_edges.py'
- 'examples/demos/dynamic_multiple_weighted_edges_example.py'
- '.github/workflows/weighted_edges_tests.yml'
pull_request:
branches: [ main, dev ]
paths:
- 'cognee/modules/graph/utils/get_graph_from_model.py'
- 'cognee/infrastructure/engine/models/Edge.py'
- 'cognee/tests/unit/interfaces/graph/test_weighted_edges.py'
- 'examples/demos/dynamic_multiple_weighted_edges_example.py'
- '.github/workflows/weighted_edges_tests.yml'
env:
RUNTIME__LOG_LEVEL: ERROR
ENV: 'dev'
jobs:
test-weighted-edges-functionality:
name: Test Weighted Edges Core Functionality
runs-on: ubuntu-22.04
strategy:
matrix:
python-version: ['3.11', '3.12']
env:
LLM_PROVIDER: openai
LLM_MODEL: gpt-5-mini
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: ${{ matrix.python-version }}
- name: Run Weighted Edges Unit Tests
run: |
uv run pytest cognee/tests/unit/interfaces/graph/test_weighted_edges.py -v --tb=short
- name: Run Standard Graph Tests (Regression)
run: |
uv run pytest cognee/tests/unit/interfaces/graph/get_graph_from_model_unit_test.py -v --tb=short
test-with-different-databases:
name: Test Weighted Edges with Different Graph Databases
runs-on: ubuntu-22.04
strategy:
matrix:
database: ['kuzu', 'neo4j']
include:
- database: kuzu
graph_db_provider: "kuzu"
- database: neo4j
graph_db_provider: "neo4j"
env:
LLM_PROVIDER: openai
LLM_MODEL: gpt-5-mini
LLM_ENDPOINT: https://api.openai.com/v1
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: "2024-02-01"
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11'
- name: Setup Neo4j with GDS
uses: ./.github/actions/setup_neo4j
id: neo4j
- name: Dependencies already installed
run: echo "Dependencies already installed in setup"
- name: Run Weighted Edges Tests
env:
ENABLE_BACKEND_ACCESS_CONTROL: 'false'
GRAPH_DATABASE_PROVIDER: ${{ matrix.graph_db_provider }}
GRAPH_DATABASE_URL: ${{ matrix.graph_db_provider == 'neo4j' && steps.neo4j.outputs.neo4j-url || '' }}
GRAPH_DATABASE_USERNAME: ${{ matrix.graph_db_provider == 'neo4j' && steps.neo4j.outputs.neo4j-username || '' }}
GRAPH_DATABASE_PASSWORD: ${{ matrix.graph_db_provider == 'neo4j' && steps.neo4j.outputs.neo4j-password || '' }}
run: |
uv run pytest cognee/tests/unit/interfaces/graph/test_weighted_edges.py -v --tb=short
test-examples:
name: Test Weighted Edges Examples
runs-on: ubuntu-22.04
env:
LLM_PROVIDER: openai
LLM_MODEL: gpt-5-mini
LLM_ENDPOINT: https://api.openai.com/v1
LLM_API_KEY: ${{ secrets.OPENAI_API_KEY }}
LLM_ARGS: ${{ secrets.LLM_ARGS }}
LLM_API_VERSION: "2024-02-01"
EMBEDDING_DIMENSIONS: 300
EMBEDDING_MODEL: ${{ secrets.EMBEDDING_MODEL }}
EMBEDDING_API_KEY: ${{ secrets.EMBEDDING_API_KEY }}
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11'
- name: Test Weighted Edges Example
run: |
uv run python examples/demos/dynamic_multiple_weighted_edges_example.py
- name: Verify Visualization File Created
run: |
if [ -f "examples/demos/.artifacts/dunder_mifflin_company_graph.html" ]; then
echo "✅ Visualization file created successfully"
ls -la examples/demos/.artifacts/dunder_mifflin_company_graph.html
else
echo "❌ Visualization file not found"
exit 1
fi
code-quality:
name: Code Quality for Weighted Edges
runs-on: ubuntu-22.04
steps:
- name: Check out repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Cognee Setup
uses: ./.github/actions/cognee_setup
with:
python-version: '3.11'
- name: Run Linting on Weighted Edges Files
uses: astral-sh/ruff-action@v3
with:
args: "check cognee/modules/graph/utils/get_graph_from_model.py cognee/tests/unit/interfaces/graph/test_weighted_edges.py examples/demos/dynamic_multiple_weighted_edges_example.py"
- name: Run Formatting Check on Weighted Edges Files
uses: astral-sh/ruff-action@v3
with:
args: "format --check cognee/modules/graph/utils/get_graph_from_model.py cognee/tests/unit/interfaces/graph/test_weighted_edges.py examples/demos/dynamic_multiple_weighted_edges_example.py"