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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .env.TEMPLATE
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ USE_GEMINI_EMBEDDINGS=1
GEMINI_EMBEDDING_MODEL_NAME="text-embedding-004"

# should be filled with the URL to the text embedding model
# (you'll need to contact a manugen-ai admin for this URL;
# (you'll need to contact a manufold admin for this URL;
# we can't make it publicly available)
WITHDRARXIV_EMBEDDINGS_URL__TEXT_EMBEDDING_004=""

Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@ jobs:
- name: Run ollama
run: |
ollama serve &

until curl -s http://localhost:11434/api/tags > /dev/null; do
sleep 1
done

ollama pull llama3.2:3b

- name: Python setup
uses: actions/setup-python@v5
with:
Expand All @@ -39,7 +45,7 @@ jobs:
- name: Run pytest
# cd into the packages dir and run pytest
# note: we skip notebooks as these are for reporting only.
run: cd packages/manugen-ai && uv run --frozen pytest -m "not notebooks"
run: cd packages/manufold && uv run --frozen pytest -m "not notebooks"
env:
# use the same models here to keep ci run duration low
# by avoiding extra downloads
Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,10 @@ cython_debug/

withdrarxiv.parquet
retraction_watch.csv
withdrarxiv_embeddings.duckdb
withdrarxiv_embeddings*.duckdb

# ignore session db, wherever it ends up being created
session.db

# gitignore the model cache directory
model_cache/
Expand Down
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ repos:
- id: check-yaml
- id: detect-private-key
- repo: https://github.com/tox-dev/pyproject-fmt
rev: "v2.11.1"
rev: "v2.16.2"
hooks:
- id: pyproject-fmt
- repo: https://github.com/citation-file-format/cffconvert
rev: 5295f87c0e261da61a7b919fc754e3a77edd98a7
hooks:
- id: validate-cff
- repo: https://github.com/codespell-project/codespell
rev: v2.4.1
rev: v2.4.2
hooks:
- id: codespell
exclude: |
Expand All @@ -34,17 +34,17 @@ repos:
additional_dependencies:
- mdformat-gfm
- repo: https://github.com/adrienverge/yamllint
rev: v1.37.1
rev: v1.38.0
hooks:
- id: yamllint
exclude: pre-commit-config.yaml
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.14.7"
rev: "v0.15.5"
hooks:
- id: ruff-format
- id: ruff-check
- repo: https://github.com/rhysd/actionlint
rev: v1.7.9
rev: v1.7.11
hooks:
- id: actionlint
- repo: https://gitlab.com/vojko.pribudic.foss/pre-commit-update
Expand Down
2 changes: 1 addition & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cff-version: 1.2.0
title: Manugen-AI
title: Manufold
message: >-
If you use this work in some way, please use the
information found within the CITATION.cff file.
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Contributing

Thank you for your interest in contributing to the Manugen AI project!
Thank you for your interest in contributing to the Manufold project!
We welcome contributions from the community to help improve and expand the functionality of this multi-agent tool for creating academic manuscripts.

### How to Contribute
Expand Down
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# Manugen AI
# Manufold (formerly, Manugen AI)

<img align="left" src="packages/manugen-ai/docs/media/manugen-ai-logo.png" alt="Project Logo" width="300px" />
<img align="left" src="packages/manufold/docs/media/manugen-ai-logo.png" alt="Project Logo" width="300px" />

Writing academic manuscripts can be tedious.
Imagine that you could bring together your results, prior research, source code, and some brief bullet points per section to generate a manuscript automatically.
That is **Manugen-AI**.
That is **Manufold** (formerly, Manugen AI).

This repo holds our submission for the 2025 [Agent Development Kit (ADK) Hackathon with Google Cloud](https://googlecloudmultiagents.devpost.com/) - Manugen AI.
**Manugen AI** is a multi-agent tool for drafting academic manuscripts from assets and guidance: a collection of figures, text/instructions, source code, and other content files.
This repo holds our submission for the 2025 [Agent Development Kit (ADK) Hackathon with Google Cloud](https://googlecloudmultiagents.devpost.com/) - Manugen AI (now Manufold).
**Manufold** is a multi-agent tool for drafting academic manuscripts from assets and guidance: a collection of figures, text/instructions, source code, and other content files.
It uses agents based on large language models (LLMs) and the [Google ADK](https://google.github.io/adk-docs/).
See the [Manugen AI package README](packages/manugen-ai/README.md) for more details on the package itself.
See the [Manugen AI package README](packages/manufold/README.md) for more details on the package itself.

The project consists of a web-based frontend, backend, and additional services.
It includes Docker Compose configuration to run the application stack locally.
Expand Down Expand Up @@ -59,7 +59,7 @@ Make sure the model you pick [supports "tools"](https://ollama.com/search?c=tool
ollama pull qwen3:8b
```

If you want to use Manugen-AI to upload figures and interpret them, you'll also need a model that [supports "vision"](https://ollama.com/search?c=vision), such as [Gemma3](https://ollama.com/library/gemma3):
If you want to use Manufold to upload figures and interpret them, you'll also need a model that [supports "vision"](https://ollama.com/search?c=vision), such as [Gemma3](https://ollama.com/library/gemma3):

```bash
# gemma3 supports vision, which can be used to interpret your figures
Expand Down Expand Up @@ -128,7 +128,7 @@ You'll see two text fields: one on the left for entering manuscript content in M

### Draft a manuscript

Manugen-AI allows a human author to quickly draft a scientific manuscript from a minimum set of research assets (such as figures or source code) and human guidance.
Manufold allows a human author to quickly draft a scientific manuscript from a minimum set of research assets (such as figures or source code) and human guidance.
After opening the web interface in your browser, follow these steps to draft a manuscript from scratch:

1. **Load an example of human guidelines.**
Expand Down Expand Up @@ -172,7 +172,7 @@ Does your research involve the use of a version controlled repository (for examp
You can use Manugen AI to create a manuscript by passing the URL for the project with the "Repos" action.

1. Within the frontend, refresh your browser so you start with an empty session.
1. On the left panel, paste in a GitHub URL (e.g. `https://github.com/pivlab/manugen-ai`).
1. On the left panel, paste in a GitHub URL (e.g. `https://github.com/pivlab/manufold`).
1. Highlight the GitHub URL and click the "Repos" action.
1. Manugen AI agents will absorb information about your repository and provide a draft manuscript in return.

Expand Down Expand Up @@ -205,7 +205,7 @@ The project is a standard three-tier web application, with the following compone

- `./frontend/`: A web-based user interface for interacting with the application, built with React.
- `./backend/`: A REST API that serves the frontend and handles requests from the web interface.
- `./packages/manugen-ai/`: The *Manugen AI* package, which is used to generate academic manuscripts from content files.
- `./packages/manufold/`: The *Manufold* package, which is used to generate academic manuscripts from content files.
The backend relies on this package to perform the actual manuscript generation.

The project includes an optional PostgreSQL database that, if available, ADK will use to persist session data between stack runs.
Expand Down
6 changes: 3 additions & 3 deletions backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# copied from https://docs.astral.sh/uv/guides/integration/docker/#intermediate-layers

# note that this Dockerfile's context should be set to the project root, due to
# the fact that it relies on a package under /packages/manugen-ai
# the fact that it relies on a package under /packages/manufold
# all backend-specific path refs should be prefixed with `backend/`

# Install uv
Expand All @@ -18,8 +18,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
# Change the working directory to the `app` directory
WORKDIR /app

# copy packages/manugen-ai into /opt/manugen-ai
COPY --exclude=.venv ./packages/manugen-ai/ /packages/manugen-ai/
# copy packages/manufold into /opt/manufold
COPY --exclude=.venv ./packages/manufold/ /packages/manufold/

# Install dependencies
ENV VIRTUAL_ENV=/app/.venv
Expand Down
6 changes: 3 additions & 3 deletions backend/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Manugen-AI Backend
# Manufold Backend

This folder implements a simple API for the frontend to invoke agents from the `manugen-ai` package, located at [packages/manugen-ai/](../packages/manugen-ai).
This folder implements a simple API for the frontend to invoke agents from the `manufold` package, located at [packages/manufold/](../packages/manufold).

While the API is intended to be run as part of the stack (see the [root README](../README.md) for details), you can run it independently on the host.

Expand All @@ -12,7 +12,7 @@ First, install the dependencies:
uv sync
```

This will install `manugen-ai` as well as other dependencies for running the FastAPI server.
This will install `manufold` as well as other dependencies for running the FastAPI server.

Then, run the API:

Expand Down
17 changes: 10 additions & 7 deletions backend/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
[project]
name = "manugen-ai-backend"
name = "manufold-backend"
version = "0.1.0"
description = "A backend for the Manugen AI project, providing APIs for AI-driven manuscript generation."
description = "A backend for the Manufold project, providing APIs for AI-driven manuscript generation."
readme = "README.md"
requires-python = ">=3.12,<3.13"
classifiers = [ "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.12" ]
classifiers = [
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.12",
]
dependencies = [
"fastapi>=0.104",
"manugen-ai",
"manufold",
"uvicorn[standard]>=0.24",
]

[tool.uv.sources]
# manugen-ai = { path = "/opt/manugen-ai" }
manugen-ai = { path = "../packages/manugen-ai" }
[tool.uv]
# manufold = { path = "/opt/manufold" }
sources.manufold = { path = "../packages/manufold" }
2 changes: 1 addition & 1 deletion backend/src/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
Manugen AI Backend Package
Manufold Backend Package
"""

__version__ = "0.1.0"
4 changes: 2 additions & 2 deletions backend/src/adk_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

- (GET) /adk_api/apps/<app_name>/users/<username>/sessions
query for all sessions for a user under <app_name> (where <app_name> is a
folder under ../packages/manugen-ai/src/manugen_ai/agents/)
folder under ../packages/manufold/src/manufold/agents/)
- (POST) /adk_api/apps/<app_name>/users/<username>/sessions/<session_id>
create a new session for a user under <app_name> with the given session_id
for running agents, these two endpoints are available:
Expand Down Expand Up @@ -44,7 +44,7 @@

adk_app = get_fast_api_app(
agents_dir=os.environ.get(
"MANUGEN_AGENTS_DIR", "/packages/manugen-ai/src/manugen_ai/agents/"
"MANUGEN_AGENTS_DIR", "/packages/manufold/src/manufold/agents/"
),
session_service_uri=os.environ.get("SESSION_DB_CONN_STRING"),
# artifact_service_uri= ,
Expand Down
14 changes: 7 additions & 7 deletions backend/src/main.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
"""
FastAPI backend for Manugen AI project.
FastAPI backend for Manufold project.
"""

import os

# read version number from manugen_ai package
# read version number from manufold package
from importlib.metadata import version

import uvicorn
Expand All @@ -13,12 +13,12 @@

from .adk_api import adk_app # Import the ADK FastAPI app

MANUGEN_VERSION = version("manugen_ai")
MANUGEN_VERSION = version("manufold")

# Create FastAPI app
app = FastAPI(
title="Manugen AI Backend",
description="A backend for the Manugen AI project, providing APIs for AI-driven manuscript generation.",
title="Manufold Backend",
description="A backend for the Manufold project, providing APIs for AI-driven manuscript generation.",
version=MANUGEN_VERSION,
docs_url="/docs",
redoc_url="/redoc",
Expand All @@ -40,7 +40,7 @@ async def root():
"""Root endpoint returning basic API information."""
root_path = os.environ.get("API_ROOT_PREFIX", "")
return {
"message": "Welcome to Manugen AI Backend",
"message": "Welcome to Manufold Backend",
"version": MANUGEN_VERSION,
"docs": f"{root_path}/docs",
"adk_api_docs": f"{root_path}/adk_api/docs",
Expand All @@ -50,7 +50,7 @@ async def root():
@app.get("/health")
async def health_check():
"""Health check endpoint."""
return {"status": "healthy", "service": "manugen-ai-backend"}
return {"status": "healthy", "service": "manufold-backend"}


@app.get("/api/v1/status")
Expand Down
2 changes: 1 addition & 1 deletion backend/start_adk_web.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

cd /packages/manugen-ai/src/manugen_ai/agents/
cd /packages/manufold/src/manufold/agents/

if [ -z "${SESSION_DB_CONN_STRING}" ]; then
SESSION_DB_ARG=""
Expand Down
10 changes: 5 additions & 5 deletions backend/start_api_server.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#!/bin/bash

# Start a FastAPI server implementing the Manugen AI Backend
# Start a FastAPI server implementing the Manufold Backend

MANUGEN_API_PORT=${MANUGEN_API_PORT:-8000}

echo "Starting Manugen AI Backend on http://0.0.0.0:${MANUGEN_API_PORT}"
echo "Starting Manufold Backend on http://0.0.0.0:${MANUGEN_API_PORT}"
echo "- API Documentation will be available at http://localhost:${MANUGEN_API_PORT}/docs"
echo "- Press Ctrl+C to stop the server"
echo ""
Expand All @@ -17,7 +17,7 @@ cd "$(dirname "$0")"
# ensure the text embedding model is downloaded
if [ "${USE_GEMINI_EMBEDDINGS:-0}" != "1" ]; then
echo "* Downloading FlagEmbedding text embedding model (${FLAGEMBEDDING_MODEL_OR_PATH:-BAAI/bge-m3})..."
uv run python -c "from manugen_ai.data import get_flag_embedding_model ; get_flag_embedding_model()"
uv run python -c "from manufold.data import get_flag_embedding_model ; get_flag_embedding_model()"
else
echo "* Using Gemini text embeddings via the Google GenAI API, skipping download."
fi
Expand All @@ -29,12 +29,12 @@ if [ "${HOT_RELOAD_BACKEND}" = "1" ]; then
--host 0.0.0.0 \
--port ${MANUGEN_API_PORT} \
--reload \
--log-level info
--log-level ${LOG_LEVEL:-info}
else
# run in production mode
exec uv run uvicorn src.main:app \
--host 0.0.0.0 \
--port ${MANUGEN_API_PORT} \
--workers ${WEB_CONCURRENCY:-8} \
--log-level warning
--log-level ${LOG_LEVEL:-info}
fi
Loading