fix release script

This commit is contained in:
Nicolò Boschi 2025-12-03 16:04:27 +01:00
parent a8c23b1e1e
commit 902eed711d
5 changed files with 93 additions and 268 deletions

View file

@ -1,4 +1,4 @@
name: Build Release Artifacts
name: Release
on:
push:
@ -6,17 +6,11 @@ on:
- 'v*'
jobs:
build-python-packages:
release-python-packages:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- name: hindsight-all
path: hindsight
- name: hindsight-api
path: hindsight-api
- name: hindsight-client
path: hindsight-clients/python
environment: pypi
permissions:
id-token: write
steps:
- uses: actions/checkout@v4
@ -31,19 +25,52 @@ jobs:
with:
python-version-file: ".python-version"
- name: Build ${{ matrix.name }} package
working-directory: ./${{ matrix.path }}
# Build all packages
- name: Build hindsight-client
working-directory: ./hindsight-clients/python
run: uv build
- name: Build hindsight-api
working-directory: ./hindsight-api
run: uv build
- name: Build hindsight-all
working-directory: ./hindsight
run: uv build
# Publish in order (client and api first, then hindsight-all which depends on them)
- name: Publish hindsight-client to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: ./hindsight-clients/python/dist
skip-existing: true
- name: Publish hindsight-api to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: ./hindsight-api/dist
skip-existing: true
- name: Publish hindsight-all to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: ./hindsight/dist
skip-existing: true
# Upload artifacts for GitHub release
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: python-${{ matrix.name }}-dist
path: ${{ matrix.path }}/dist/*
retention-days: 30
name: python-packages
path: |
hindsight-clients/python/dist/*
hindsight-api/dist/*
hindsight/dist/*
retention-days: 1
build-typescript-client:
release-typescript-client:
runs-on: ubuntu-latest
environment: npm
steps:
- uses: actions/checkout@v4
@ -58,22 +85,28 @@ jobs:
working-directory: ./hindsight-clients/typescript
run: npm ci
- name: Build TypeScript client
- name: Build
working-directory: ./hindsight-clients/typescript
run: npm run build
- name: Pack npm package
- name: Publish to npm
working-directory: ./hindsight-clients/typescript
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Pack for GitHub release
working-directory: ./hindsight-clients/typescript
run: npm pack
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: typescript-client-dist
name: typescript-client
path: hindsight-clients/typescript/*.tgz
retention-days: 30
retention-days: 1
build-rust-cli:
release-rust-cli:
runs-on: ${{ matrix.os }}
strategy:
matrix:
@ -99,24 +132,6 @@ jobs:
with:
targets: ${{ matrix.target }}
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo index
uses: actions/cache@v4
with:
path: ~/.cargo/git
key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
- name: Cache cargo build
uses: actions/cache@v4
with:
path: hindsight-cli/target
key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }}
- name: Build
working-directory: hindsight-cli
run: cargo build --release --target ${{ matrix.target }}
@ -132,9 +147,9 @@ jobs:
with:
name: rust-cli-${{ matrix.asset_name }}
path: artifacts/${{ matrix.asset_name }}
retention-days: 30
retention-days: 1
build-docker-images:
release-docker-images:
runs-on: ubuntu-latest
permissions:
contents: read
@ -142,7 +157,6 @@ jobs:
strategy:
matrix:
include:
# All images use the same Dockerfile with different --target
- target: api-only
image_name: hindsight-api
- target: cp-only
@ -192,7 +206,7 @@ jobs:
type=semver,pattern={{major}},value=${{ steps.get_version.outputs.VERSION }}
type=raw,value=latest
- name: Build and push Docker image
- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
@ -203,7 +217,7 @@ jobs:
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
package-helm-chart:
release-helm-chart:
runs-on: ubuntu-latest
steps:
@ -215,77 +229,21 @@ jobs:
version: 'latest'
- name: Lint Helm chart
run: |
helm lint helm/hindsight
run: helm lint helm/hindsight
- name: Package Helm chart
run: |
helm package helm/hindsight --destination ./helm-packages
run: helm package helm/hindsight --destination ./helm-packages
- name: Upload Helm chart artifact
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: helm-chart
path: helm-packages/*.tgz
retention-days: 30
publish-python-packages:
runs-on: ubuntu-latest
needs: [build-python-packages]
environment: pypi
strategy:
max-parallel: 1
matrix:
include:
# Order matters: client and api first, then hindsight-all (which depends on them)
- name: hindsight-client
- name: hindsight-api
- name: hindsight-all
steps:
- name: Download ${{ matrix.name }}
uses: actions/download-artifact@v4
with:
name: python-${{ matrix.name }}-dist
path: ./dist
- name: Publish ${{ matrix.name }} to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: ./dist
skip-existing: true
publish-npm-package:
runs-on: ubuntu-latest
needs: [build-typescript-client]
environment: npm
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'
- name: Install dependencies
working-directory: ./hindsight-clients/typescript
run: npm ci
- name: Build TypeScript client
working-directory: ./hindsight-clients/typescript
run: npm run build
- name: Publish to npm
working-directory: ./hindsight-clients/typescript
run: npm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
retention-days: 1
create-github-release:
runs-on: ubuntu-latest
needs: [build-python-packages, build-typescript-client, build-rust-cli, build-docker-images, package-helm-chart]
needs: [release-python-packages, release-typescript-client, release-rust-cli, release-docker-images, release-helm-chart]
permissions:
contents: write
@ -296,76 +254,31 @@ jobs:
id: get_version
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: Download hindsight-all
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
name: python-hindsight-all-dist
path: ./artifacts/python-hindsight-all
- name: Download hindsight-api
uses: actions/download-artifact@v4
with:
name: python-hindsight-api-dist
path: ./artifacts/python-hindsight-api
- name: Download hindsight-client
uses: actions/download-artifact@v4
with:
name: python-hindsight-client-dist
path: ./artifacts/python-hindsight-client
- name: Download TypeScript Client
uses: actions/download-artifact@v4
with:
name: typescript-client-dist
path: ./artifacts/typescript-client
- name: Download Rust CLI (Linux)
uses: actions/download-artifact@v4
with:
name: rust-cli-hindsight-linux-amd64
path: ./artifacts/rust-cli-hindsight-linux-amd64
- name: Download Rust CLI (macOS Intel)
uses: actions/download-artifact@v4
with:
name: rust-cli-hindsight-darwin-amd64
path: ./artifacts/rust-cli-hindsight-darwin-amd64
- name: Download Rust CLI (macOS ARM)
uses: actions/download-artifact@v4
with:
name: rust-cli-hindsight-darwin-arm64
path: ./artifacts/rust-cli-hindsight-darwin-arm64
- name: Download Helm chart
uses: actions/download-artifact@v4
with:
name: helm-chart
path: ./artifacts/helm-chart
path: ./artifacts
- name: Prepare release assets
run: |
mkdir -p release-assets
# Python packages
cp artifacts/python-hindsight-all/* release-assets/
cp artifacts/python-hindsight-api/* release-assets/
cp artifacts/python-hindsight-client/* release-assets/
# TypeScript Client
cp artifacts/typescript-client/*.tgz release-assets/
cp artifacts/python-packages/hindsight-clients/python/dist/* release-assets/ || true
cp artifacts/python-packages/hindsight-api/dist/* release-assets/ || true
cp artifacts/python-packages/hindsight/dist/* release-assets/ || true
# TypeScript client
cp artifacts/typescript-client/*.tgz release-assets/ || true
# Rust CLI binaries
cp artifacts/rust-cli-hindsight-linux-amd64/hindsight-linux-amd64 release-assets/
cp artifacts/rust-cli-hindsight-darwin-amd64/hindsight-darwin-amd64 release-assets/
cp artifacts/rust-cli-hindsight-darwin-arm64/hindsight-darwin-arm64 release-assets/
cp artifacts/rust-cli-hindsight-linux-amd64/hindsight-linux-amd64 release-assets/ || true
cp artifacts/rust-cli-hindsight-darwin-amd64/hindsight-darwin-amd64 release-assets/ || true
cp artifacts/rust-cli-hindsight-darwin-arm64/hindsight-darwin-arm64 release-assets/ || true
# Helm chart
cp artifacts/helm-chart/*.tgz release-assets/
cp artifacts/helm-chart/*.tgz release-assets/ || true
ls -la release-assets/
- name: Generate release notes
id: release_notes
run: |
cat << 'EOF' > release-notes.md
# Hindsight v${{ steps.get_version.outputs.VERSION }}
## Quick Start
```bash
@ -376,70 +289,29 @@ jobs:
ghcr.io/${{ github.repository_owner }}/hindsight:${{ steps.get_version.outputs.VERSION }}
```
## 📦 Release Artifacts
### Docker Images
- `ghcr.io/${{ github.repository_owner }}/hindsight:${{ steps.get_version.outputs.VERSION }}` - **Standalone all-in-one** (recommended)
- `ghcr.io/${{ github.repository_owner }}/hindsight-api:${{ steps.get_version.outputs.VERSION }}` - API server only
## Docker Images
- `ghcr.io/${{ github.repository_owner }}/hindsight:${{ steps.get_version.outputs.VERSION }}` - Standalone (recommended)
- `ghcr.io/${{ github.repository_owner }}/hindsight-api:${{ steps.get_version.outputs.VERSION }}` - API only
- `ghcr.io/${{ github.repository_owner }}/hindsight-control-plane:${{ steps.get_version.outputs.VERSION }}` - Web UI only
### Python Packages
- `hindsight-all` - All-in-one package (includes API + client)
- `hindsight-api` - API server
- `hindsight-client` - Client library
### TypeScript/JavaScript
- `@vectorize-io/hindsight-client` - TypeScript SDK
### CLI Binaries
- `hindsight-linux-amd64` - Linux x86_64
- `hindsight-darwin-amd64` - macOS Intel
- `hindsight-darwin-arm64` - macOS Apple Silicon
### Helm Chart
- `hindsight-${{ steps.get_version.outputs.VERSION }}.tgz`
## 🚀 Installation
### Python
## Python
```bash
# All-in-one (recommended)
pip install hindsight-all==${{ steps.get_version.outputs.VERSION }}
# Or install components separately
pip install hindsight-api==${{ steps.get_version.outputs.VERSION }}
pip install hindsight-client==${{ steps.get_version.outputs.VERSION }}
pip install hindsight-all # or hindsight-api, hindsight-client
```
### TypeScript/JavaScript
## TypeScript/JavaScript
```bash
npm install @vectorize-io/hindsight-client@${{ steps.get_version.outputs.VERSION }}
npm install @vectorize-io/hindsight-client
```
### CLI
```bash
# macOS (Apple Silicon)
curl -L https://github.com/${{ github.repository }}/releases/download/v${{ steps.get_version.outputs.VERSION }}/hindsight-darwin-arm64 -o hindsight
chmod +x hindsight
sudo mv hindsight /usr/local/bin/
## CLI
Download the appropriate binary from the release assets below.
# macOS (Intel)
curl -L https://github.com/${{ github.repository }}/releases/download/v${{ steps.get_version.outputs.VERSION }}/hindsight-darwin-amd64 -o hindsight
chmod +x hindsight
sudo mv hindsight /usr/local/bin/
# Linux
curl -L https://github.com/${{ github.repository }}/releases/download/v${{ steps.get_version.outputs.VERSION }}/hindsight-linux-amd64 -o hindsight
chmod +x hindsight
sudo mv hindsight /usr/local/bin/
```
### Helm (Kubernetes)
## Helm
```bash
helm install hindsight oci://ghcr.io/${{ github.repository_owner }}/charts/hindsight --version ${{ steps.get_version.outputs.VERSION }}
```
EOF
cat release-notes.md
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
@ -448,19 +320,5 @@ jobs:
body_path: release-notes.md
draft: false
prerelease: false
generate_release_notes: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create release summary
run: |
echo "# Release v${{ steps.get_version.outputs.VERSION }} Published Successfully" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "## 📦 Components" >> $GITHUB_STEP_SUMMARY
echo "- ✅ Python packages (hindsight-all, hindsight-api, hindsight-client)" >> $GITHUB_STEP_SUMMARY
echo "- ✅ TypeScript Client (@vectorize-io/hindsight-client)" >> $GITHUB_STEP_SUMMARY
echo "- ✅ Rust CLI (Linux amd64, macOS amd64, macOS arm64)" >> $GITHUB_STEP_SUMMARY
echo "- ✅ Docker images (standalone, API, Control Plane)" >> $GITHUB_STEP_SUMMARY
echo "- ✅ Helm chart" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "🎉 Release is now available at: https://github.com/${{ github.repository }}/releases/tag/v${{ steps.get_version.outputs.VERSION }}" >> $GITHUB_STEP_SUMMARY

View file

@ -287,39 +287,7 @@ async def retrieve_temporal(
query_emb_str, bank_id, fact_type, start_date, end_date, semantic_threshold
)
import logging
logger = logging.getLogger(__name__)
if not entry_points:
# Check if there are ANY memories with temporal metadata for this bank
total_with_dates = await conn.fetchval(
"""SELECT COUNT(*) FROM memory_units
WHERE bank_id = $1 AND fact_type = $2
AND (occurred_start IS NOT NULL OR occurred_end IS NOT NULL OR mentioned_at IS NOT NULL)""",
bank_id, fact_type
)
# Check how many have mentioned_at in the range
in_range = await conn.fetchval(
"""SELECT COUNT(*) FROM memory_units
WHERE bank_id = $1 AND fact_type = $2
AND mentioned_at IS NOT NULL AND mentioned_at BETWEEN $3 AND $4""",
bank_id, fact_type, start_date, end_date
)
# Check semantic similarity of those in range
sample = await conn.fetch(
"""SELECT id, text, mentioned_at, 1 - (embedding <=> $1::vector) AS similarity
FROM memory_units
WHERE bank_id = $2 AND fact_type = $3
AND mentioned_at IS NOT NULL AND mentioned_at BETWEEN $4 AND $5
AND embedding IS NOT NULL
ORDER BY mentioned_at DESC
LIMIT 5""",
query_emb_str, bank_id, fact_type, start_date, end_date
)
logger.info(f"[TEMPORAL] No entry points for {bank_id}/{fact_type} in {start_date} to {end_date}.")
logger.info(f"[TEMPORAL] Total with dates: {total_with_dates}, In date range: {in_range}")
for row in sample:
logger.info(f"[TEMPORAL] Sample: {row['text'][:60]}... mentioned_at={row['mentioned_at']} sim={row['similarity']:.3f}")
return []
# Calculate temporal scores for entry points
@ -475,9 +443,7 @@ async def retrieve_parallel(
"""
# Detect temporal constraint
from .temporal_extraction import extract_temporal_constraint
import logging
import time
logger = logging.getLogger(__name__)
temporal_constraint = extract_temporal_constraint(
query_text, reference_date=question_date, analyzer=query_analyzer

View file

@ -506,10 +506,11 @@ export function DataView({ factType }: DataViewProps) {
{/* Memory Detail Panel for Table View - Fixed on Right */}
{selectedTableMemory && (
<div className="fixed right-0 top-0 h-screen w-96 bg-background border-l border-border shadow-lg z-50 overflow-y-auto p-4">
<div className="fixed right-0 top-0 h-screen w-[420px] bg-card border-l-2 border-primary shadow-2xl z-50 overflow-y-auto animate-in slide-in-from-right duration-300 ease-out">
<MemoryDetailPanel
memory={selectedTableMemory}
onClose={() => setSelectedTableMemory(null)}
inPanel
/>
</div>
)}

View file

@ -174,7 +174,7 @@ class LongMemEvalAnswerGenerator(LLMAnswerGenerator):
**How to Answer:**
1. Start by scanning retrieved context to understand the facts and events that happened and the timeline.
2. Reason about all the memories and find the right answer, considering the most recent memory as an update of the current facts
2. Reason about all the memories and find the right answer, considering the most recent memory as an update of the current facts.
In general the answer must be comprehensive and plenty of details from the retrieved context.
@ -184,7 +184,7 @@ For recommendations/suggestions, use the retrieved context to understand the use
For questions asking for help or instructions, consider the users' latest purchases and previous interactions with the assistant to understand which details to focus your answer on (include these references in your answer).
For specific number/value questions, use the context to understand what is the most up-to-date number based on recency, but also include the reasoning (in the answer) on previous possible values and why you think are less relevant.
For open questions, include as much details as possible from different sources that are relevant.
For questions where a specific entity is mentioned and it's different from your memory, just say the truth, don't make up anything just to fulfill the question. For example, if the question is about a specific sport, you should consider if the memories and the question are about the same sport.
For questions where a specific entity/role is mentioned and it's different from your memory, just say the truth, don't make up anything just to fulfill the question. For example, if the question is about a specific sport, you should consider if the memories and the question are about the same sport.
For comparative questions , say you don't know the answer if you don't have information about both sides. (or more sides)
For questions related to time/date, carefully review the question date and the memories date to correctly answer the question.
For questions related to time/date calculation (e.g. How many days passed between X and Y?), carefully review the memories date to correctly answer the question and only provide an answer if you have information about both X and Y, otherwise say it's not possible to calculate and why.

View file

@ -1141,7 +1141,7 @@ provides-extras = ["test"]
[[package]]
name = "hindsight-api"
version = "0.0.10"
version = "0.0.11"
source = { editable = "hindsight-api" }
dependencies = [
{ name = "alembic" },
@ -1243,7 +1243,7 @@ dev = [
[[package]]
name = "hindsight-client"
version = "0.0.10"
version = "0.0.11"
source = { editable = "hindsight-clients/python" }
dependencies = [
{ name = "aiohttp" },
@ -1275,7 +1275,7 @@ provides-extras = ["test"]
[[package]]
name = "hindsight-dev"
version = "0.0.10"
version = "0.0.11"
source = { editable = "hindsight-dev" }
dependencies = [
{ name = "hindsight-api" },