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
235 changes: 69 additions & 166 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,192 +1,95 @@
# This file is autogenerated by maturin v1.13.3
# To update, run
#
# maturin generate-ci github
#
name: Publish
name: Build & Release

on:
push:
tags:
- '*'
- 'v*'
workflow_dispatch:

permissions:
contents: read
contents: write

jobs:
linux:
runs-on: ${{ matrix.platform.runner }}
build:
strategy:
matrix:
platform:
- runner: ubuntu-22.04
target: x86_64
- runner: ubuntu-22.04
target: x86
- runner: ubuntu-22.04
target: aarch64
- runner: ubuntu-22.04
target: armv7
- runner: ubuntu-22.04
target: s390x
- runner: ubuntu-22.04
target: ppc64le
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.9"
- name: Build dashboard
run: cd dashboard && npm ci && npm run build
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist --find-interpreter
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
manylinux: auto
working-directory: crates/perspective-python
before-script-linux: "yum install -y pkg-config openssl-devel || true"
- name: Upload wheels
uses: actions/upload-artifact@v6
with:
name: wheels-linux-${{ matrix.platform.target }}
path: dist
include:
- os: ubuntu-22.04
target: x86_64-unknown-linux-gnu
artifact: perspective-linux-amd64
- os: ubuntu-22.04
target: aarch64-unknown-linux-gnu
artifact: perspective-linux-arm64
- os: macos-latest
target: aarch64-apple-darwin
artifact: perspective-macos-arm64
- os: macos-13
target: x86_64-apple-darwin
artifact: perspective-macos-amd64
- os: windows-latest
target: x86_64-pc-windows-msvc
artifact: perspective-windows-amd64.exe

musllinux:
runs-on: ${{ matrix.platform.runner }}
strategy:
matrix:
platform:
- runner: ubuntu-22.04
target: x86_64
- runner: ubuntu-22.04
target: x86
- runner: ubuntu-22.04
target: aarch64
- runner: ubuntu-22.04
target: armv7
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.9"
- name: Build dashboard
run: cd dashboard && npm ci && npm run build
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist --find-interpreter
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
manylinux: musllinux_1_2
working-directory: crates/perspective-python
before-script-linux: "apk add --no-cache pkgconfig openssl-dev || true"
- name: Upload wheels
uses: actions/upload-artifact@v6
with:
name: wheels-musllinux-${{ matrix.platform.target }}
path: dist

windows:
runs-on: ${{ matrix.platform.runner }}
strategy:
matrix:
platform:
- runner: windows-latest
target: x64
python_arch: x64
- runner: windows-latest
target: x86
python_arch: x86
- runner: windows-11-arm
target: aarch64
python_arch: arm64
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.13"
architecture: ${{ matrix.platform.python_arch }}
- name: Build dashboard
run: cd dashboard && npm ci && npm run build
- name: Build wheels
uses: PyO3/maturin-action@v1
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
target: ${{ matrix.platform.target }}
args: --release --out dist --find-interpreter
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
working-directory: crates/perspective-python
- name: Upload wheels
uses: actions/upload-artifact@v6
with:
name: wheels-windows-${{ matrix.platform.target }}
path: dist
targets: ${{ matrix.target }}

- name: Install cross-compilation tools (Linux ARM64)
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV

- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y libclang-dev cmake pkg-config

macos:
runs-on: ${{ matrix.platform.runner }}
strategy:
matrix:
platform:
- runner: macos-15-intel
target: x86_64
- runner: macos-latest
target: aarch64
steps:
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: "3.9"
- name: Build dashboard
run: cd dashboard && npm ci && npm run build
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.platform.target }}
args: --release --out dist --find-interpreter
sccache: ${{ !startsWith(github.ref, 'refs/tags/') }}
working-directory: crates/perspective-python
- name: Upload wheels
uses: actions/upload-artifact@v6
with:
name: wheels-macos-${{ matrix.platform.target }}
path: dist

sdist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Build sdist
uses: PyO3/maturin-action@v1
with:
command: sdist
args: --out dist
working-directory: crates/perspective-python
- name: Upload sdist
- name: Build release binary
run: cargo build --release --target ${{ matrix.target }} -p perspective-cli

- name: Rename binary (Linux/macOS)
if: runner.os != 'Windows'
run: |
cp target/${{ matrix.target }}/release/perspective ${{ matrix.artifact }}
chmod +x ${{ matrix.artifact }}

- name: Rename binary (Windows)
if: runner.os == 'Windows'
run: cp target/${{ matrix.target }}/release/perspective.exe ${{ matrix.artifact }}

- name: Upload artifact
uses: actions/upload-artifact@v6
with:
name: wheels-sdist
path: dist
name: ${{ matrix.artifact }}
path: ${{ matrix.artifact }}

release:
name: Release
needs: build
runs-on: ubuntu-latest
if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
needs: [linux, musllinux, windows, macos, sdist]
environment: release
permissions:
id-token: write
contents: write
attestations: write
if: startsWith(github.ref, 'refs/tags/')
steps:
- uses: actions/download-artifact@v7
- name: Generate artifact attestation
uses: actions/attest@v4
- uses: actions/checkout@v6

- name: Download all artifacts
uses: actions/download-artifact@v7

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
subject-path: 'wheels-*/*'
- name: Install uv
if: ${{ startsWith(github.ref, 'refs/tags/') }}
uses: astral-sh/setup-uv@v7
- name: Publish to PyPI
if: ${{ startsWith(github.ref, 'refs/tags/') }}
run: uv publish --trusted-publishing always 'wheels-*/*'
generate_release_notes: true
files: |
perspective-linux-amd64
perspective-linux-arm64
perspective-macos-arm64
perspective-macos-amd64
perspective-windows-amd64.exe
12 changes: 6 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ Perspective is a graph+vector memory engine for AI agents, written in Rust.
MIT license. Standalone engine with first-class Hermes integration.

## Architecture
- - Workspace with 4 crates: perspective-core, perspective-cli (CLI), perspective-plugin, perspective-python
- HTTP server lives in perspective-core, auto-starts on port 2085
- Workspace with 3 crates: perspective-core, perspective-cli, perspective-plugin
- CLI binary manages server lifecycle: `perspective start` / `perspective stop`
- HTTP server on port 2085 (started by CLI or in-process by plugin)
- Storage: Qdrant-edge (embedded vectors) + redb (graph) + Tantivy (BM25)
- Memory types: episodic, semantic, procedural
- LLM extraction: bundled model (NuExtract via llama-cpp-2) or external OpenAI-compatible API
Expand All @@ -15,7 +16,7 @@ MIT license. Standalone engine with first-class Hermes integration.
## Build Commands
- `cargo check` — verify compilation (first run takes ~4 min, compiles llama.cpp)
- `cargo test` — run tests
- `cargo build` — full build
- `cargo build --release -p perspective-cli` — build release binary
- `cargo clippy` — lint

### Build Dependencies
Expand All @@ -37,13 +38,12 @@ MIT license. Standalone engine with first-class Hermes integration.
## Key Files
- `crates/perspective-core/src/server.rs` — HTTP server (auto-starts on :2085)
- `crates/perspective-core/src/static_files.rs` — Dashboard static file serving
- `crates/perspective-cli/src/main.rs` — CLI only (init, status, config)
- `crates/perspective-cli/src/main.rs` — CLI commands (init, status, config, start, stop)
- `crates/perspective-core/src/types/` — Memory type definitions (memory.rs, graph.rs)
- `crates/perspective-core/src/engine.rs` — Main engine struct
- `crates/perspective-core/src/store/` — Storage layer (vector.rs, graph.rs, text.rs)
- `crates/perspective-core/src/retrieval/` — Retrieval pipeline (vector, graph, text, entity search + fusion)
- `crates/perspective-core/src/llm.rs` — Bundled LLM (llama-cpp-2) wrapper
- `crates/perspective-core/src/extraction/pipeline.rs` — Extraction routing (bundled vs HTTP)
- `crates/perspective-plugin/` — Hermes integration
- `crates/perspective-python/` — Python bindings (PyO3)
- `crates/perspective-plugin/` — Hermes integration (Rust plugin)
- `ARCHITECTURE.md` — Full architecture document
15 changes: 5 additions & 10 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,20 +110,15 @@ perspective/
│ │
│ ├── perspective-cli/ # CLI tool (init, status, config)
│ │ ├── src/
│ │ │ └── main.rs # CLI commands only (init, status, config)
│ │ │ └── main.rs # CLI commands (init, status, config, start, stop)
│ │ └── Cargo.toml
│ │
│ └── perspective-plugin/ # Hermes MemoryProvider plugin
│
│ └── perspective-plugin/ # Hermes MemoryProvider plugin (Rust)
│ ├── src/
│ │ ├── lib.rs
│ │ └── provider.rs # MemoryProvider trait impl
│ │ └── provider.rs
│ └── Cargo.toml
│
├── perspective-python/ # Python bindings (PyO3)
│ ├── src/
│ │ └── lib.rs
│ └── Cargo.toml
│
├── tests/
│ ├── integration/
│ └── fixtures/
Expand Down Expand Up @@ -491,7 +486,7 @@ The engine exposes a REST API on port 2085 when running. No separate server proc
| GET | `/*` | Dashboard static files (SPA) |

### Auto-start
The HTTP server starts automatically when `PerspectiveEngine` is created via the Python plugin. No `perspective serve` command needed.
The HTTP server starts when `perspective start` is run, or when the Hermes plugin creates an in-process engine. The CLI binary manages the server lifecycle.

---

Expand Down
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading