platform guide rewrite, workspace dashboard ui (#156)
* workspace dash platform guide * fix (docs): Platform Update Guide * feat (scripts): Add utility script to quickly update Changelogs and versions * chore (sdks): Add Changelog files to SDKs * chore (docs): Fix compatability guide * chore (docs): Code Rabbit and Changelog Dates * chore (docs): Code Rabbit * chore (docs): Code Rabbit * chore (docs): Restructure * chore (docs): Code Rabbit * Code Rabit --------- Co-authored-by: Vineeth Voruganti <13438633+VVoruganti@users.noreply.github.com>
20
CHANGELOG.md
|
|
@ -1,29 +1,29 @@
|
|||
# Change Log
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [2.0.4]
|
||||
## [2.0.4] - 2025-07-02
|
||||
|
||||
### Fixed
|
||||
|
||||
- Migration/provision scripts did not have correct database connection arguments, causing timeouts
|
||||
|
||||
## [2.0.3]
|
||||
## [2.0.3] - 2025-07-01
|
||||
|
||||
### Fixed
|
||||
|
||||
- Bug that causes runtime error when Sentry flags are enabled
|
||||
|
||||
## [2.0.2]
|
||||
## [2.0.2] - 2025-06-27
|
||||
|
||||
### Fixed
|
||||
|
||||
- Database initialization was misconfigured and led to provision_db script failing: switch to consistent working configuration with transaction pooler
|
||||
|
||||
## [2.0.1]
|
||||
## [2.0.1] - 2025-06-26
|
||||
|
||||
### Added
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- Use new config arrangement everywhere
|
||||
- Remove hardcoded responses
|
||||
|
||||
## [2.0.0]
|
||||
## [2.0.0] - 2025-06-24
|
||||
|
||||
### Added
|
||||
|
||||
|
|
@ -87,7 +87,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- Collections and Documents no longer exposed in the API, solely internal
|
||||
- Obsolete tests for apps, users, collections, documents, and metamessages
|
||||
|
||||
## [1.1.0]
|
||||
## [1.1.0] - 2025-05-15
|
||||
|
||||
### Added
|
||||
|
||||
|
|
@ -107,7 +107,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- Alembic Migrations to include initial database migrations
|
||||
- Sentry Middleware to not report Honcho Exceptions
|
||||
|
||||
## [1.0.0]
|
||||
## [1.0.0] - 2025-04-10
|
||||
|
||||
### Added
|
||||
|
||||
|
|
@ -123,7 +123,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||
- Database provisioning is a separate script instead of happening on startup
|
||||
- Consolidated `session/chat` and `session/chat/stream` endpoints
|
||||
|
||||
## [0.0.16]
|
||||
## [0.0.16] - 2025-03-05
|
||||
|
||||
### Added
|
||||
|
||||
|
|
@ -144,7 +144,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||
|
||||
- Self-hosting documentation and README to mention `uv` instead of `poetry`
|
||||
|
||||
## [0.0.15]
|
||||
## [0.0.15] - 2025-01-06
|
||||
|
||||
### Added
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ This guide helps you understand which versions of Honcho's API are compatible wi
|
|||
|
||||
## Version Compatibility
|
||||
|
||||
### Honcho API v2.0.2 (Current)
|
||||
### Honcho API v2.0.4 (Current)
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="TypeScript SDK" icon="js">
|
||||
|
|
@ -32,6 +32,6 @@ This guide helps you understand which versions of Honcho's API are compatible wi
|
|||
|
||||
## Version Compatibility Table
|
||||
|
||||
| Honcho API Version | TypeScript SDK | Python SDK | Notes |
|
||||
|-------------------|---------------|------------|-------|
|
||||
| v2.0.2 (Current) | v1.1.0 | v1.1.0 | Full compatibility with new peer architecture |
|
||||
| Honcho API Version | TypeScript SDK | Python SDK |
|
||||
|-------------------|---------------|------------|
|
||||
| v2.0.4 (Current) | v1.1.0 | v1.1.0 |
|
||||
|
|
|
|||
|
|
@ -26,7 +26,8 @@
|
|||
"group": "Introduction",
|
||||
"pages": [
|
||||
"v2/documentation/introduction/overview",
|
||||
"v2/documentation/introduction/quickstart"
|
||||
"v2/documentation/introduction/quickstart",
|
||||
"v2/documentation/introduction/vibecoding"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -51,11 +52,7 @@
|
|||
"groups": [
|
||||
{
|
||||
"group": "Getting Started",
|
||||
"pages": [
|
||||
"v2/guides/overview",
|
||||
"v2/guides/ai-assisted-setup",
|
||||
"v2/guides/mcp"
|
||||
]
|
||||
"pages": ["v2/guides/overview", "v2/guides/mcp"]
|
||||
},
|
||||
{
|
||||
"group": "Application Interfaces",
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 172 KiB After Width: | Height: | Size: 197 KiB |
|
After Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 127 KiB |
|
After Width: | Height: | Size: 169 KiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 160 KiB |
|
Before Width: | Height: | Size: 107 KiB |
|
After Width: | Height: | Size: 156 KiB |
|
After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 211 KiB After Width: | Height: | Size: 306 KiB |
|
After Width: | Height: | Size: 204 KiB |
|
After Width: | Height: | Size: 268 KiB |
6734
docs/pnpm-lock.yaml
|
|
@ -2,7 +2,7 @@
|
|||
title: "Cursor & Claude: AI-Powered Honcho Setup"
|
||||
icon: "wand-magic-sparkles"
|
||||
description: "Build Honcho-powered AI agents quickly using Cursor or Claude. Zero configuration required."
|
||||
sidebarTitle: 'AI-Assisted Setup'
|
||||
sidebarTitle: 'Vibecoding Setup'
|
||||
---
|
||||
|
||||
Get Honcho up and running in minutes using AI coding assistants. These prompts are specifically optimized for Cursor and Claude to generate production-ready code with minimal effort.
|
||||
|
|
@ -293,4 +293,4 @@ When working with AI assistants, mention these concepts:
|
|||
|
||||
<Note>
|
||||
**Pro Tip**: Be specific about your requirements and constraints when prompting AI. The more context you provide, the better the generated code will match your needs.
|
||||
</Note>
|
||||
</Note>
|
||||
|
|
@ -1,116 +1,117 @@
|
|||
---
|
||||
title: "Platform Overview"
|
||||
title: "Managed Honcho Platform"
|
||||
icon: "rocket"
|
||||
description: "Honcho is the personal identity platform for AI - enabling truly personalized, contextually aware agents and applications."
|
||||
description: "Build socially intelligent agents without worrying about infrastructure"
|
||||
sidebarTitle: "Platform Overview"
|
||||
---
|
||||
|
||||
<Card title="Sign up to start using Honcho!" icon="rocket" href="https://app.honcho.dev">
|
||||
Start using the platform to manage Honcho instances for your workspace or app.
|
||||
</Card>
|
||||
|
||||
## Welcome to Honcho!
|
||||
The quickest way to begin using Honcho in production is with the
|
||||
[Honcho Cloud Platform](https://app.honcho.dev). Sign up, generate an API key,
|
||||
and start building with Honcho.
|
||||
|
||||
The Honcho Platform is a managed service and the easiest way to add personal memory and identity to your AI applications. Built by the team at Plastic Labs, Honcho enables **ambient personalization** - your AI learns about users automatically as they interact, with no surveys or additional user overhead.
|
||||
## 1. Go to [app.honcho.dev](https://app.honcho.dev)
|
||||
|
||||
Create an account to start using Honcho. If a teammate already uses Honcho, ask
|
||||
them to invite you to their organization; otherwise, you’ll see a banner
|
||||
prompting you to create a new one.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/app-screenshots/welcome-to-honcho.png" alt="Honcho Platform Dashboard" width="400" />
|
||||
</Frame>
|
||||
|
||||
## Why Use the Honcho Dashboard?
|
||||
Once you've created an organization, you'll be taken to the dashboard and see
|
||||
the welcome page.
|
||||
|
||||
The Honcho management platform streamlines deployment and monitoring so you can focus on building great AI experiences:
|
||||
<img src="/images/app-screenshots/get-started-copy.png" alt="Honcho Dashboard Getting Started"/>
|
||||
|
||||
**One-Click Deployment**: Launch dedicated Honcho instances in seconds with zero infrastructure setup. We handle provisioning, scaling, and maintenance automatically.
|
||||
Each organization has dedicated infrastructure running to isolate your
|
||||
workloads. Until you activate a subscription under the
|
||||
[Billing](https://app.honcho.dev/billing) page, the infrastructure will be
|
||||
deactivated. You can check the status of your instance by going to the
|
||||
[Status](https://app.honcho.dev/status) page.
|
||||
|
||||
**Developer-First Tools**: Create and manage API keys, utilize an API playground with a Postman-like experience, get machine status and performance analytics of your Honcho instance.
|
||||
<img src="/images/app-screenshots/no-subscription-status.png" alt="Honcho Status Page with No Subscription" />
|
||||
|
||||
**Production Monitoring**: Real-time analytics, usage metrics, and health monitoring. Track performance and user engagement across all your AI applications.
|
||||
## **2. Set up billing to activate your Honcho instance**
|
||||
|
||||
<img src="/images/app-screenshots/get-started copy.png" alt="Honcho Dashboard Getting Started" width="500" />
|
||||
|
||||
## Go to app.honcho.dev
|
||||
|
||||
Get up and running with Honcho in minutes through our managed platform:
|
||||
|
||||
### **1. Sign Up & Create Your Organization**
|
||||
Start by creating your account and setting up your organization. Each organization gets isolated workspaces, team management, and dedicated infrastructure for your Honcho instances.
|
||||
|
||||
### **2. Deploy Your Honcho Instance**
|
||||
One-click deployment creates a dedicated Honcho instance on Fly.io infrastructure. Your instance is automatically provisioned with PostgreSQL + pgvector, background workers, and API endpoints - ready to handle production traffic for your workspace.
|
||||
|
||||
### **3. Generate API Keys**
|
||||
Create and manage API keys for different environments (development, staging, production). Each key provides secure access to your Honcho instance with granular permissions and usage tracking.
|
||||
|
||||
<img src="/images/app-screenshots/api-keys.png" alt="API Key Management Dashboard" />
|
||||
|
||||
### **4. Test with API Playground**
|
||||
Use our Postman-like API playground to test queries, explore endpoints, and validate your integration. Send requests directly to your Honcho instance and see real-time responses with full request/response logging.
|
||||
|
||||
<img src="/images/app-screenshots/api-playground.png" alt="API Playground Interface" />
|
||||
|
||||
### **5. Monitor Performance & Machine Status**
|
||||
Track your Honcho instance health, usage metrics, and performance analytics. Monitor API response times, background processing queues, memory usage, and user engagement across all your AI applications.
|
||||
Once you activate your subscription, your Honcho instance provisions
|
||||
automatically, and you can watch the status page until all systems show a green
|
||||
check mark.
|
||||
|
||||
<img src="/images/app-screenshots/performance-analytics.png" alt="Performance Analytics Dashboard" />
|
||||
|
||||
View the status of your machines running Honcho:
|
||||
<img src="/images/app-screenshots/machine-status.png" alt="Machine Status" />
|
||||
Here you can monitor your Honcho instance health, usage metrics, and
|
||||
performance analytics. See request volume, API response times, and endpoint
|
||||
usage across all your AI applications.
|
||||
|
||||
## What's Happening Under the Hood
|
||||
You can also upgrade Honcho when new versions are made available.
|
||||
|
||||
```mermaid
|
||||
## **3. Manage API Keys**
|
||||
Create and manage API keys for different environments. You can create
|
||||
admin-level keys that have access to the entire Honcho instance or scope keys
|
||||
to restrict access to `Workspaces`, `Peers`, or `Sessions`.
|
||||
|
||||
graph LR
|
||||
User[User Interacts] --> App[Your AI App]
|
||||
App --> Honcho[Honcho API]
|
||||
Honcho --> Theory[Theory of Mind<br/>Processing]
|
||||
Theory --> Profile[Living User<br/>Representation]
|
||||
Profile --> Context[Rich Context<br/>for AI]
|
||||
Context --> App
|
||||
<img src="/images/app-screenshots/api-keys.png" alt="API Key Management Dashboard" />
|
||||
|
||||
## **4. Test with API Playground**
|
||||
Use our Postman-like API playground to test queries, explore endpoints, and
|
||||
validate your integration. Send requests directly to your Honcho instance and
|
||||
see real-time responses with full request/response logging.
|
||||
|
||||
<img src="/images/app-screenshots/api-playground.png" alt="API Playground Interface" />
|
||||
|
||||
## **5. Create a Workspace**
|
||||
On the explore page, you can see and interact with the data stored in your
|
||||
Honcho instance. You can create `Workspaces`, `Peers`, `Sessions`, and `Messages`.
|
||||
|
||||
<img src="/images/app-screenshots/explore-honcho.png" alt="Explore Honcho Page" />
|
||||
|
||||
## **6. Peers & Sessions Management**
|
||||
Click into a `Workspace` to open up the `Workspace` dashboard. Here you can create
|
||||
`Peers` and `Sessions`, use the Dialectic API and add `Messages` to your `Peer`
|
||||
representations. Utilize your ability to search across all `Messages` in a
|
||||
`Workspace`.
|
||||
|
||||
<img src="/images/app-screenshots/workspace-dash.png" alt="Workspace Dashboard Overview" />
|
||||
|
||||
|
||||
```
|
||||
## **7. Peer Utilities & Chat Endpoint**
|
||||
Select a `Peer` to open its utilities. From here you can search that `Peer`'s
|
||||
`Messages`, view participating `Sessions`, or edit its metadata.
|
||||
|
||||
**1. Users interact naturally** with your AI application
|
||||
**2. Honcho processes interactions via** using advanced theory of mind inference
|
||||
**3. Builds living representations** of each user's psychology, preferences, and identity
|
||||
**4. Provides rich context** to your AI when needed, in natural language
|
||||
The Chat Endpoint allows you to send a query through the Honcho API to get
|
||||
information about the `Peer`'s representation. If you include the `Session` ID,
|
||||
the query will be scoped to `Messages` and the representation of a `Peer`
|
||||
within that `Session`.
|
||||
|
||||
<Frame>
|
||||
<img src="/images/app-screenshots/peer-utilities.png" alt="Peer Utilities Dashboard" width="400" />
|
||||
</Frame>
|
||||
|
||||
|
||||
**Memory Engine Architecture**
|
||||
- Hierarchical data storage (Workspaces → Peers / Sessions → Messages)
|
||||
- Vector similarity search for semantic queries
|
||||
- Metadata indexing for fast retrieval
|
||||
- Automatic data organization and cleanup
|
||||
## **8. Session Dashboard & Get Context**
|
||||
From the workspace dashboard, navigate to a `Session` to find options to add `Peers`, view `Messages`, and search across all `Messages` for a particular session.
|
||||
|
||||
Use the **Get Context** feature to quickly generate output that fits into your
|
||||
LLM’s context window. Get a subset of messages with an optional summary
|
||||
based on the token count you input. The [Session Context](../../guides/get-context) guide goes over how to use this in your agents
|
||||
|
||||
<img src="/images/app-screenshots/session-dash.png" alt="Session Dashboard Overview" />
|
||||
|
||||
<Frame>
|
||||
<img src="/images/app-screenshots/create-message.png" alt="Create Message Interface" width="400" />
|
||||
</Frame>
|
||||
|
||||
|
||||
```python
|
||||
import honcho
|
||||
## Go Further
|
||||
|
||||
# Initialize client
|
||||
client = honcho.Client(api_key="your-api-key")
|
||||
View the [Architecture](/v2/documentation/reference/architecture) to see how Honcho works under the hood.
|
||||
|
||||
# Create a workspace for your app
|
||||
workspace = client.workspaces.create(name="My AI App")
|
||||
|
||||
# Create a peer (user)
|
||||
peer = client.peers.create(
|
||||
workspace_id=workspace.id,
|
||||
name="user_123"
|
||||
)
|
||||
|
||||
# Get personalized context for AI response
|
||||
context = client.dialectic.query(
|
||||
workspace_id=workspace.id,
|
||||
peer_id=peer.id,
|
||||
query="What communication style does this user prefer?"
|
||||
)
|
||||
# Returns rich, nuanced context about the user
|
||||
```
|
||||
|
||||
## Getting Started
|
||||
|
||||
Check out our [Platform Guide](/v2/documentation/platform/guided-tutorial) to start using Honcho platform quickly.
|
||||
|
||||
Or dive into our [API Reference](/v2/api-reference) to explore all available endpoints.
|
||||
Dive into our [API Reference](/v2/api-reference) to explore all available endpoints.
|
||||
|
||||
## Next Steps
|
||||
|
||||
|
|
@ -121,10 +122,10 @@ Or dive into our [API Reference](/v2/api-reference) to explore all available end
|
|||
<Card title="Join our Discord" icon="discord" href="http://discord.gg/plasticlabs">
|
||||
Connect with 1000+ developers building with Honcho
|
||||
</Card>
|
||||
<Card title="Read the Docs" icon="book" href="/v2/documentation/introduction/quickstart">
|
||||
Follow our comprehensive guides
|
||||
<Card title="Contribute to Honcho" icon="code" href="/v2/contributing/guidelines">
|
||||
View our guidelines and explore the codebase
|
||||
</Card>
|
||||
<Card title="Explore Examples" icon="code" href="/v2/guides">
|
||||
<Card title="Explore Examples" icon="book" href="/v2/guides">
|
||||
See Honcho in action with real examples
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,623 @@
|
|||
#!/usr/bin/env uv run python
|
||||
"""
|
||||
Honcho Version Update Script
|
||||
|
||||
This script helps update version numbers across the Honcho repository.
|
||||
It handles the main API, Python SDK, and TypeScript SDK in a single operation.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import tempfile
|
||||
import re
|
||||
from datetime import datetime
|
||||
from typing import Optional, Dict, List, Tuple
|
||||
import json
|
||||
|
||||
|
||||
class VersionUpdater:
|
||||
def __init__(self, base_path: str):
|
||||
self.base_path = base_path
|
||||
|
||||
def get_current_versions(self) -> Dict[str, str]:
|
||||
"""Get current version numbers from the repository."""
|
||||
versions = {}
|
||||
|
||||
# Main API version
|
||||
with open(os.path.join(self.base_path, "pyproject.toml"), "r") as f:
|
||||
for line in f:
|
||||
if line.startswith("version = "):
|
||||
versions["api"] = line.split('"')[1]
|
||||
break
|
||||
|
||||
# Python SDK version
|
||||
with open(os.path.join(self.base_path, "sdks/python/pyproject.toml"), "r") as f:
|
||||
for line in f:
|
||||
if line.startswith("version = "):
|
||||
versions["python_sdk"] = line.split('"')[1]
|
||||
break
|
||||
|
||||
# TypeScript SDK version
|
||||
with open(os.path.join(self.base_path, "sdks/typescript/package.json"), "r") as f:
|
||||
data = json.load(f)
|
||||
versions["typescript_sdk"] = data["version"]
|
||||
|
||||
return versions
|
||||
|
||||
def get_all_versions_from_editor(self, current_versions: Dict[str, str]) -> Dict[str, Dict[str, str]]:
|
||||
"""Open editor to get all version updates at once."""
|
||||
template = f"""# Honcho Version Update
|
||||
# Enter new version numbers below. Leave blank to skip updating that component.
|
||||
#
|
||||
# MAIN API
|
||||
# Current version: {current_versions['api']}
|
||||
API_VERSION=
|
||||
|
||||
# API Changelog (use ### for section headers: Added, Changed, Fixed, etc.)
|
||||
|
||||
|
||||
# PYTHON SDK
|
||||
# Current version: {current_versions['python_sdk']}
|
||||
PYTHON_VERSION=
|
||||
|
||||
# Python SDK Changelog
|
||||
|
||||
|
||||
# TYPESCRIPT SDK
|
||||
# Current version: {current_versions['typescript_sdk']}
|
||||
TYPESCRIPT_VERSION=
|
||||
|
||||
# TypeScript SDK Changelog
|
||||
|
||||
|
||||
# Lines starting with # are comments and will be ignored
|
||||
"""
|
||||
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
|
||||
f.write(template)
|
||||
temp_file = f.name
|
||||
|
||||
# Open in vim
|
||||
subprocess.call(['vim', temp_file])
|
||||
|
||||
# Parse the file
|
||||
with open(temp_file, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
os.unlink(temp_file)
|
||||
|
||||
# Extract all versions and changelogs
|
||||
updates = {}
|
||||
|
||||
# Parse API version
|
||||
api_match = re.search(r'^API_VERSION=(.*)$', content, re.MULTILINE)
|
||||
if api_match and api_match.group(1).strip():
|
||||
changelog = self._extract_changelog_between(content, 'API_VERSION=', 'PYTHON_VERSION=')
|
||||
updates['api'] = {
|
||||
'version': api_match.group(1).strip(),
|
||||
'changelog': self._clean_changelog_sections(changelog)
|
||||
}
|
||||
|
||||
# Parse Python SDK version
|
||||
python_match = re.search(r'^PYTHON_VERSION=(.*)$', content, re.MULTILINE)
|
||||
if python_match and python_match.group(1).strip():
|
||||
changelog = self._extract_changelog_between(content, 'PYTHON_VERSION=', 'TYPESCRIPT_VERSION=')
|
||||
updates['python_sdk'] = {
|
||||
'version': python_match.group(1).strip(),
|
||||
'changelog': self._clean_changelog_sections(changelog)
|
||||
}
|
||||
|
||||
# Parse TypeScript SDK version
|
||||
ts_match = re.search(r'^TYPESCRIPT_VERSION=(.*)$', content, re.MULTILINE)
|
||||
if ts_match and ts_match.group(1).strip():
|
||||
changelog = self._extract_changelog_between(content, 'TYPESCRIPT_VERSION=', None)
|
||||
updates['typescript_sdk'] = {
|
||||
'version': ts_match.group(1).strip(),
|
||||
'changelog': self._clean_changelog_sections(changelog)
|
||||
}
|
||||
|
||||
return updates
|
||||
|
||||
def _extract_changelog_between(self, content: str, start_marker: str, end_marker: Optional[str]) -> str:
|
||||
"""Extract changelog content between markers."""
|
||||
lines = content.split('\n')
|
||||
changelog_lines = []
|
||||
in_section = False
|
||||
|
||||
for line in lines:
|
||||
if start_marker in line:
|
||||
in_section = True
|
||||
continue
|
||||
if end_marker and end_marker in line:
|
||||
break
|
||||
if in_section:
|
||||
# Skip comment lines but keep markdown headers
|
||||
if line.strip().startswith('# ') and not line.strip().startswith('###'):
|
||||
continue
|
||||
if line.strip() == '#':
|
||||
continue
|
||||
changelog_lines.append(line)
|
||||
|
||||
# Remove trailing empty lines
|
||||
while changelog_lines and not changelog_lines[-1].strip():
|
||||
changelog_lines.pop()
|
||||
|
||||
return '\n'.join(changelog_lines).strip()
|
||||
|
||||
def _clean_changelog_sections(self, changelog: str) -> str:
|
||||
"""Remove empty changelog sections."""
|
||||
sections = ['Added', 'Changed', 'Fixed', 'Deprecated', 'Removed', 'Security']
|
||||
lines = changelog.split('\n')
|
||||
cleaned_lines = []
|
||||
current_section = None
|
||||
section_has_content = False
|
||||
section_start_idx = -1
|
||||
|
||||
for i, line in enumerate(lines):
|
||||
# Check if this is a section header
|
||||
is_section_header = False
|
||||
for section in sections:
|
||||
if line.strip() == f'### {section}':
|
||||
# If we have a previous section, decide whether to keep it
|
||||
if current_section is not None and section_start_idx != -1:
|
||||
if section_has_content:
|
||||
# Keep the section
|
||||
cleaned_lines.extend(lines[section_start_idx:i])
|
||||
|
||||
# Start tracking new section
|
||||
current_section = section
|
||||
section_start_idx = i
|
||||
section_has_content = False
|
||||
is_section_header = True
|
||||
break
|
||||
|
||||
if not is_section_header and current_section is not None:
|
||||
# Check if this line has content (not empty and not just whitespace)
|
||||
if line.strip() and not line.strip().startswith('#'):
|
||||
section_has_content = True
|
||||
|
||||
# Handle the last section
|
||||
if current_section is not None and section_start_idx != -1:
|
||||
if section_has_content:
|
||||
cleaned_lines.extend(lines[section_start_idx:])
|
||||
|
||||
# If no sections were found, return original
|
||||
if not cleaned_lines and '###' not in changelog:
|
||||
return changelog
|
||||
|
||||
return '\n'.join(cleaned_lines).strip()
|
||||
|
||||
def update_all(self, updates: Dict[str, Dict[str, str]], current_versions: Dict[str, str]):
|
||||
"""Update all components that have new versions."""
|
||||
# Update API if specified
|
||||
if 'api' in updates:
|
||||
print(f"\nUpdating API version to {updates['api']['version']}...")
|
||||
self.update_api_version(updates['api']['version'], updates['api']['changelog'])
|
||||
|
||||
# Update compatibility guide for new API version
|
||||
self._update_compatibility_guide_for_api(
|
||||
updates['api']['version'],
|
||||
updates.get('python_sdk', {}).get('version', current_versions['python_sdk']),
|
||||
updates.get('typescript_sdk', {}).get('version', current_versions['typescript_sdk'])
|
||||
)
|
||||
|
||||
# Update Python SDK if specified
|
||||
if 'python_sdk' in updates:
|
||||
print(f"Updating Python SDK version to {updates['python_sdk']['version']}...")
|
||||
self.update_python_sdk_version(updates['python_sdk']['version'], updates['python_sdk']['changelog'])
|
||||
|
||||
# Update TypeScript SDK if specified
|
||||
if 'typescript_sdk' in updates:
|
||||
print(f"Updating TypeScript SDK version to {updates['typescript_sdk']['version']}...")
|
||||
self.update_typescript_sdk_version(updates['typescript_sdk']['version'], updates['typescript_sdk']['changelog'])
|
||||
|
||||
def update_api_version(self, new_version: str, changelog: str):
|
||||
"""Update main API version across all files."""
|
||||
updates = [
|
||||
# Simple replacements
|
||||
{
|
||||
'file': 'pyproject.toml',
|
||||
'pattern': r'version = "[^"]*"',
|
||||
'replacement': f'version = "{new_version}"'
|
||||
},
|
||||
{
|
||||
'file': 'src/main.py',
|
||||
'pattern': r'version="[^"]*"',
|
||||
'replacement': f'version="{new_version}"'
|
||||
},
|
||||
{
|
||||
'file': 'README.md',
|
||||
'pattern': r'Version-\d+\.\d+\.\d+-blue',
|
||||
'replacement': f'Version-{new_version}-blue'
|
||||
},
|
||||
# docs.json is handled separately to only update same major version
|
||||
]
|
||||
|
||||
# Apply simple updates
|
||||
for update in updates:
|
||||
file_path = os.path.join(self.base_path, update['file'])
|
||||
with open(file_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
content = re.sub(update['pattern'], update['replacement'], content)
|
||||
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(content)
|
||||
|
||||
# Update docs.json - only update same major version
|
||||
self._update_docs_json(new_version)
|
||||
|
||||
# Update CHANGELOG.md (prepend new entry)
|
||||
self._update_changelog_md(new_version, changelog)
|
||||
|
||||
# Update docs changelog (MDX format)
|
||||
self._update_docs_changelog(new_version, changelog, 'api')
|
||||
|
||||
def update_python_sdk_version(self, new_version: str, changelog: str):
|
||||
"""Update Python SDK version."""
|
||||
updates = [
|
||||
{
|
||||
'file': 'sdks/python/pyproject.toml',
|
||||
'pattern': r'version = "[^"]*"',
|
||||
'replacement': f'version = "{new_version}"'
|
||||
},
|
||||
{
|
||||
'file': 'sdks/python/src/honcho/__init__.py',
|
||||
'pattern': r'__version__ = "[^"]*"',
|
||||
'replacement': f'__version__ = "{new_version}"'
|
||||
}
|
||||
]
|
||||
|
||||
for update in updates:
|
||||
file_path = os.path.join(self.base_path, update['file'])
|
||||
with open(file_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
content = re.sub(update['pattern'], update['replacement'], content)
|
||||
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(content)
|
||||
|
||||
# Update SDK's own CHANGELOG.md
|
||||
self._update_sdk_changelog(new_version, changelog, 'sdks/python/CHANGELOG.md')
|
||||
|
||||
# Update docs changelog
|
||||
self._update_docs_changelog(new_version, changelog, 'python_sdk')
|
||||
|
||||
# Update compatibility guide SDK version
|
||||
self._update_compatibility_guide('python', new_version)
|
||||
|
||||
def update_typescript_sdk_version(self, new_version: str, changelog: str):
|
||||
"""Update TypeScript SDK version."""
|
||||
# Update package.json
|
||||
file_path = os.path.join(self.base_path, 'sdks/typescript/package.json')
|
||||
with open(file_path, 'r') as f:
|
||||
data = json.load(f)
|
||||
|
||||
data['version'] = new_version
|
||||
|
||||
with open(file_path, 'w') as f:
|
||||
json.dump(data, f, indent=2)
|
||||
f.write('\n') # Add trailing newline
|
||||
|
||||
# Update SDK's own CHANGELOG.md
|
||||
self._update_sdk_changelog(new_version, changelog, 'sdks/typescript/CHANGELOG.md')
|
||||
|
||||
# Update docs changelog
|
||||
self._update_docs_changelog(new_version, changelog, 'typescript_sdk')
|
||||
|
||||
# Update compatibility guide SDK version
|
||||
self._update_compatibility_guide('typescript', new_version)
|
||||
|
||||
def _update_docs_json(self, new_version: str):
|
||||
"""Update docs.json - only update versions with same major version."""
|
||||
file_path = os.path.join(self.base_path, 'docs/docs.json')
|
||||
|
||||
with open(file_path, 'r') as f:
|
||||
data = json.load(f)
|
||||
|
||||
# Get major version of new version
|
||||
new_major = new_version.split('.')[0]
|
||||
|
||||
# Update only matching major versions
|
||||
if 'navigation' in data and 'versions' in data['navigation']:
|
||||
for version_entry in data['navigation']['versions']:
|
||||
if 'version' in version_entry:
|
||||
current_version = version_entry['version'].lstrip('v')
|
||||
current_major = current_version.split('.')[0]
|
||||
|
||||
if current_major == new_major:
|
||||
version_entry['version'] = f'v{new_version}'
|
||||
|
||||
with open(file_path, 'w') as f:
|
||||
json.dump(data, f, indent=2)
|
||||
f.write('\n')
|
||||
|
||||
def _update_sdk_changelog(self, version: str, changelog: str, relative_path: str):
|
||||
"""Update an SDK's CHANGELOG.md file."""
|
||||
file_path = os.path.join(self.base_path, relative_path)
|
||||
|
||||
with open(file_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Find the position after the header
|
||||
header_end = content.find('\n## [')
|
||||
if header_end == -1:
|
||||
header_end = content.find('\n##')
|
||||
|
||||
if header_end == -1:
|
||||
# No existing entries, add after title section
|
||||
header_end = content.find('and this project adheres to')
|
||||
if header_end != -1:
|
||||
header_end = content.find('\n', header_end)
|
||||
|
||||
# Create new entry with proper formatting
|
||||
date = datetime.now().strftime('%Y-%m-%d')
|
||||
|
||||
# Ensure changelog content is properly formatted
|
||||
if changelog.strip():
|
||||
formatted_changelog = changelog.strip()
|
||||
else:
|
||||
formatted_changelog = "### Changed\n\n- Updated version"
|
||||
|
||||
new_entry = f"\n\n## [{version}] - {date}\n\n{formatted_changelog}\n"
|
||||
|
||||
# Insert the new entry
|
||||
new_content = content[:header_end] + new_entry + content[header_end:]
|
||||
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(new_content)
|
||||
|
||||
def _update_changelog_md(self, version: str, changelog: str):
|
||||
"""Update the main CHANGELOG.md file."""
|
||||
file_path = os.path.join(self.base_path, 'CHANGELOG.md')
|
||||
|
||||
with open(file_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Find the position after the header
|
||||
header_end = content.find('\n## [')
|
||||
if header_end == -1:
|
||||
header_end = content.find('\n##')
|
||||
|
||||
if header_end == -1:
|
||||
# No existing entries, add after title
|
||||
header_end = content.find('\n', content.find('# Changelog'))
|
||||
|
||||
# Create new entry with proper formatting
|
||||
date = datetime.now().strftime('%Y-%m-%d')
|
||||
|
||||
# Ensure changelog content is properly formatted
|
||||
if changelog.strip():
|
||||
formatted_changelog = changelog.strip()
|
||||
else:
|
||||
formatted_changelog = "### Changed\n\n- Updated version"
|
||||
|
||||
new_entry = f"\n\n## [{version}] - {date}\n\n{formatted_changelog}\n"
|
||||
|
||||
# Insert the new entry
|
||||
new_content = content[:header_end] + new_entry + content[header_end:]
|
||||
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(new_content)
|
||||
|
||||
def _update_docs_changelog(self, version: str, changelog: str, component: str):
|
||||
"""Update the docs/changelog/introduction.mdx file."""
|
||||
file_path = os.path.join(self.base_path, 'docs/changelog/introduction.mdx')
|
||||
|
||||
with open(file_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
if component == 'api':
|
||||
# Find the Honcho API tab content
|
||||
tab_start = content.find('<Tab title="Honcho API">')
|
||||
if tab_start == -1:
|
||||
return
|
||||
|
||||
# Find where to insert (after the Tab opening)
|
||||
insert_pos = content.find('\n', tab_start) + 1
|
||||
|
||||
# Format the changelog with proper indentation
|
||||
indented_changelog = '\n'.join(' ' + line if line.strip() else ''
|
||||
for line in changelog.strip().split('\n'))
|
||||
|
||||
# Create the new update entry
|
||||
new_entry = f""" <Update label="v{version} (Current)">
|
||||
{indented_changelog}
|
||||
</Update>
|
||||
|
||||
"""
|
||||
|
||||
# Remove (Current) from previous entries
|
||||
# Use a more specific pattern to avoid replacing in other contexts
|
||||
content = re.sub(
|
||||
r'(<Update label="v[^"]*) \(Current\)(")',
|
||||
r'\1\2',
|
||||
content
|
||||
)
|
||||
|
||||
# Insert the new entry right after the Tab line
|
||||
content = content[:insert_pos] + new_entry + content[insert_pos:]
|
||||
|
||||
elif component == 'python_sdk':
|
||||
# Update Python SDK section
|
||||
content = self._update_sdk_changelog_section(content, 'Python SDK', version, changelog)
|
||||
|
||||
elif component == 'typescript_sdk':
|
||||
# Update TypeScript SDK section
|
||||
content = self._update_sdk_changelog_section(content, 'TypeScript SDK', version, changelog)
|
||||
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(content)
|
||||
|
||||
def _update_sdk_changelog_section(self, content: str, sdk_title: str, version: str, changelog: str):
|
||||
"""Update a specific SDK section in the changelog."""
|
||||
tab_pattern = f'<Tab title="{sdk_title}">'
|
||||
tab_start = content.find(tab_pattern)
|
||||
if tab_start == -1:
|
||||
return content
|
||||
|
||||
# Format the changelog with proper indentation
|
||||
indented_changelog = '\n'.join(' ' + line if line.strip() else ''
|
||||
for line in changelog.strip().split('\n'))
|
||||
|
||||
# Create new update entry
|
||||
new_entry = f""" <Update label="v{version} (Current)">
|
||||
{indented_changelog}
|
||||
</Update>
|
||||
"""
|
||||
|
||||
# Remove (Current) from previous SDK entries
|
||||
# More precise pattern to avoid issues
|
||||
pattern = rf'(<Tab title="{sdk_title}">.*?<Update label="v[^"]*) \(Current\)(".*?</Tab>)'
|
||||
content = re.sub(pattern, r'\1\2', content, flags=re.DOTALL)
|
||||
|
||||
# Find where to insert the new entry
|
||||
# Look for the line after the SDK link (e.g., [Python SDK](...))
|
||||
tab_pos = content.find(tab_pattern)
|
||||
if tab_pos == -1:
|
||||
return content
|
||||
|
||||
# Find the end of the SDK link line
|
||||
link_start = content.find('[', tab_pos)
|
||||
if link_start != -1:
|
||||
link_end = content.find('\n', link_start)
|
||||
if link_end != -1:
|
||||
insert_pos = link_end + 1
|
||||
content = content[:insert_pos] + new_entry + content[insert_pos:]
|
||||
|
||||
return content
|
||||
|
||||
def _update_compatibility_guide(self, sdk_type: str, version: str):
|
||||
"""Update the compatibility guide with new SDK version."""
|
||||
file_path = os.path.join(self.base_path, 'docs/changelog/compatibility-guide.mdx')
|
||||
|
||||
with open(file_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
if sdk_type == 'typescript':
|
||||
# Update in the card
|
||||
content = re.sub(
|
||||
r'(<Card title="TypeScript SDK".*?Compatible Version:\*\*) v[\d.]+',
|
||||
rf'\1 v{version}',
|
||||
content,
|
||||
flags=re.DOTALL
|
||||
)
|
||||
# Update in the install command
|
||||
content = re.sub(
|
||||
r'npm install @honcho-ai/sdk@[\d.]+',
|
||||
f'npm install @honcho-ai/sdk@{version}',
|
||||
content
|
||||
)
|
||||
elif sdk_type == 'python':
|
||||
# Update in the card
|
||||
content = re.sub(
|
||||
r'(<Card title="Python SDK".*?Compatible Version:\*\*) v[\d.]+',
|
||||
rf'\1 v{version}',
|
||||
content,
|
||||
flags=re.DOTALL
|
||||
)
|
||||
# Update in the install command
|
||||
content = re.sub(
|
||||
r'pip install honcho-ai==[\d.]+',
|
||||
f'pip install honcho-ai=={version}',
|
||||
content
|
||||
)
|
||||
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(content)
|
||||
|
||||
def _update_compatibility_guide_for_api(self, api_version: str, python_version: str, typescript_version: str):
|
||||
"""Update compatibility guide when API version changes."""
|
||||
file_path = os.path.join(self.base_path, 'docs/changelog/compatibility-guide.mdx')
|
||||
|
||||
with open(file_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Update the current API version header
|
||||
content = re.sub(
|
||||
r'### Honcho API v[\d.]+ \(Current\)',
|
||||
f'### Honcho API v{api_version} (Current)',
|
||||
content
|
||||
)
|
||||
|
||||
# Find the table and update/add entry
|
||||
table_match = re.search(r'(\| Honcho API Version.*?\n\|[-| ]+\n)(.*?)(\n\n|$)', content, re.DOTALL)
|
||||
if table_match:
|
||||
header = table_match.group(1)
|
||||
rows = table_match.group(2)
|
||||
after_table = table_match.group(3)
|
||||
|
||||
# Update existing current version
|
||||
rows = re.sub(r'v[\d.]+ \(Current\)', lambda m: m.group(0).replace(' (Current)', ''), rows)
|
||||
|
||||
# Add new row at the top
|
||||
new_row = f'| v{api_version} (Current) | v{typescript_version} | v{python_version} | Latest release |'
|
||||
|
||||
# Reconstruct table
|
||||
new_table = header + new_row + '\n' + rows + after_table
|
||||
|
||||
# Replace in content
|
||||
content = content[:table_match.start()] + new_table + content[table_match.end():]
|
||||
|
||||
with open(file_path, 'w') as f:
|
||||
f.write(content)
|
||||
|
||||
|
||||
def main():
|
||||
# Get the parent directory of the scripts folder (the project root)
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
base_path = os.path.dirname(script_dir)
|
||||
updater = VersionUpdater(base_path)
|
||||
|
||||
# Get current versions
|
||||
current_versions = updater.get_current_versions()
|
||||
|
||||
print("Honcho Version Updater")
|
||||
print("=" * 50)
|
||||
print("\nCurrent versions:")
|
||||
print(f" Main API: {current_versions['api']}")
|
||||
print(f" Python SDK: {current_versions['python_sdk']}")
|
||||
print(f" TypeScript SDK: {current_versions['typescript_sdk']}")
|
||||
print()
|
||||
print("Opening editor for version updates...")
|
||||
print("Leave version fields blank to skip updating that component.")
|
||||
print()
|
||||
|
||||
# Get all updates at once
|
||||
updates = updater.get_all_versions_from_editor(current_versions)
|
||||
|
||||
if not updates:
|
||||
print("No versions specified. Exiting...")
|
||||
sys.exit(0)
|
||||
|
||||
# Show what will be updated
|
||||
print("\nThe following components will be updated:")
|
||||
for component, info in updates.items():
|
||||
component_name = {
|
||||
'api': 'Main API',
|
||||
'python_sdk': 'Python SDK',
|
||||
'typescript_sdk': 'TypeScript SDK'
|
||||
}[component]
|
||||
print(f" {component_name}: {current_versions[component]} → {info['version']}")
|
||||
|
||||
# Confirm
|
||||
response = input("\nProceed with updates? (y/n): ").strip().lower()
|
||||
if response != 'y':
|
||||
print("Cancelled.")
|
||||
sys.exit(0)
|
||||
|
||||
# Apply all updates
|
||||
updater.update_all(updates, current_versions)
|
||||
|
||||
print("\nVersion updates complete!")
|
||||
print("\nDon't forget to:")
|
||||
print(" - Review the changes with `git diff`")
|
||||
print(" - Commit the changes")
|
||||
print(" - Create git tags for the new versions")
|
||||
print(" - Push the changes and tags")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [1.1.0] - 2025-07-08
|
||||
|
||||
### Fixed
|
||||
|
||||
- Properly handle AsyncClient
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## [1.1.0] - 2025-07-08
|
||||
|
||||
### Fixed
|
||||
|
||||
- Create default workspace on Honcho client instantiation
|
||||
- Simplified Honcho client import path
|
||||