v1.1.0 Release Notes (#110)
* fix (docs): Update Changelog, versions, and mintlify * chore: linter errors * chore: Add uv.lock updates * fix (util): Fix save summary metamessages * chore (docs): Fix spelling mistake * fix (db): Fix Query Tagging
This commit is contained in:
parent
5a2fcfed7d
commit
a6d52ab8c9
20
CHANGELOG.md
20
CHANGELOG.md
|
|
@ -5,6 +5,26 @@ 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]
|
||||
|
||||
### Added
|
||||
|
||||
- Normalize resources to remove joins and increase query performance
|
||||
- Query tracing for debugging
|
||||
|
||||
### Changed
|
||||
|
||||
- `/list` endpoints to not require a request body
|
||||
- `metamessage_type` to `label` with backwards compatability
|
||||
- Database Provisioning to rely on alembic
|
||||
- Database Session Manager to explicitly rollback transactions before closing
|
||||
the connection
|
||||
|
||||
### Fixed
|
||||
|
||||
- Alembic Migrations to include initial database migrations
|
||||
- Sentry Middleware to not report Honcho Exceptions
|
||||
|
||||
## [1.0.0]
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# 🫡 Honcho
|
||||
|
||||

|
||||

|
||||
[](https://discord.gg/plasticlabs)
|
||||
[](https://arxiv.org/abs/2310.06983)
|
||||

|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
"url": "https://honcho.dev/",
|
||||
"email": "hello@plasticlabs.ai"
|
||||
},
|
||||
"version": "1.0.0"
|
||||
"version": "1.1.0"
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
|
|
@ -168,12 +168,15 @@
|
|||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/AppGet",
|
||||
"description": "Filtering and pagination options for the apps list"
|
||||
"anyOf": [
|
||||
{ "$ref": "#/components/schemas/AppGet" },
|
||||
{ "type": "null" }
|
||||
],
|
||||
"description": "Filtering and pagination options for the apps list",
|
||||
"title": "Options"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -549,12 +552,15 @@
|
|||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/UserGet",
|
||||
"description": "Filtering options for the users list"
|
||||
"anyOf": [
|
||||
{ "$ref": "#/components/schemas/UserGet" },
|
||||
{ "type": "null" }
|
||||
],
|
||||
"description": "Filtering options for the users list",
|
||||
"title": "Options"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -996,12 +1002,15 @@
|
|||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/SessionGet",
|
||||
"description": "Filtering and pagination options for the sessions list"
|
||||
"anyOf": [
|
||||
{ "$ref": "#/components/schemas/SessionGet" },
|
||||
{ "type": "null" }
|
||||
],
|
||||
"description": "Filtering and pagination options for the sessions list",
|
||||
"title": "Options"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1616,12 +1625,15 @@
|
|||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/MessageGet",
|
||||
"description": "Filtering options for the messages list"
|
||||
"anyOf": [
|
||||
{ "$ref": "#/components/schemas/MessageGet" },
|
||||
{ "type": "null" }
|
||||
],
|
||||
"description": "Filtering options for the messages list",
|
||||
"title": "Options"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1894,11 +1906,11 @@
|
|||
"x-codeSamples": [
|
||||
{
|
||||
"lang": "JavaScript",
|
||||
"source": "import Honcho from 'honcho-ai';\n\nconst client = new Honcho({\n apiKey: process.env['HONCHO_API_KEY'], // This is the default and can be omitted\n});\n\nasync function main() {\n const metamessage = await client.apps.users.metamessages.create('app_id', 'user_id', {\n content: 'content',\n label: 'x',\n });\n\n console.log(metamessage.id);\n}\n\nmain();"
|
||||
"source": "import Honcho from 'honcho-ai';\n\nconst client = new Honcho({\n apiKey: process.env['HONCHO_API_KEY'], // This is the default and can be omitted\n});\n\nasync function main() {\n const metamessage = await client.apps.users.metamessages.create('app_id', 'user_id', {\n content: 'content',\n metamessage_type: 'x',\n });\n\n console.log(metamessage.id);\n}\n\nmain();"
|
||||
},
|
||||
{
|
||||
"lang": "Python",
|
||||
"source": "import os\nfrom honcho import Honcho\n\nclient = Honcho(\n api_key=os.environ.get(\"HONCHO_API_KEY\"), # This is the default and can be omitted\n)\nmetamessage = client.apps.users.metamessages.create(\n user_id=\"user_id\",\n app_id=\"app_id\",\n content=\"content\",\n label=\"x\",\n)\nprint(metamessage.id)"
|
||||
"source": "import os\nfrom honcho import Honcho\n\nclient = Honcho(\n api_key=os.environ.get(\"HONCHO_API_KEY\"), # This is the default and can be omitted\n)\nmetamessage = client.apps.users.metamessages.create(\n user_id=\"user_id\",\n app_id=\"app_id\",\n content=\"content\",\n metamessage_type=\"x\",\n)\nprint(metamessage.id)"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1974,12 +1986,15 @@
|
|||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/MetamessageGet",
|
||||
"description": "Filtering options for the metamessages list"
|
||||
"anyOf": [
|
||||
{ "$ref": "#/components/schemas/MetamessageGet" },
|
||||
{ "type": "null" }
|
||||
],
|
||||
"description": "Filtering options for the metamessages list",
|
||||
"title": "Options"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2380,12 +2395,15 @@
|
|||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/CollectionGet",
|
||||
"description": "Filtering options for the collections list"
|
||||
"anyOf": [
|
||||
{ "$ref": "#/components/schemas/CollectionGet" },
|
||||
{ "type": "null" }
|
||||
],
|
||||
"description": "Filtering options for the collections list",
|
||||
"title": "Options"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2723,12 +2741,15 @@
|
|||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/DocumentGet",
|
||||
"description": "Filtering options for the documents list"
|
||||
"anyOf": [
|
||||
{ "$ref": "#/components/schemas/DocumentGet" },
|
||||
{ "type": "null" }
|
||||
],
|
||||
"description": "Filtering options for the documents list",
|
||||
"title": "Options"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3286,7 +3307,8 @@
|
|||
"metadata": {
|
||||
"additionalProperties": true,
|
||||
"type": "object",
|
||||
"title": "Metadata"
|
||||
"title": "Metadata",
|
||||
"default": {}
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
|
|
@ -3295,9 +3317,8 @@
|
|||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": ["id", "name", "metadata", "created_at"],
|
||||
"title": "App",
|
||||
"exclude": ["h_metadata", "public_id"]
|
||||
"required": ["id", "name", "created_at"],
|
||||
"title": "App"
|
||||
},
|
||||
"AppCreate": {
|
||||
"properties": {
|
||||
|
|
@ -3353,10 +3374,12 @@
|
|||
"id": { "type": "string", "title": "Id" },
|
||||
"name": { "type": "string", "title": "Name" },
|
||||
"user_id": { "type": "string", "title": "User Id" },
|
||||
"app_id": { "type": "string", "title": "App Id" },
|
||||
"metadata": {
|
||||
"additionalProperties": true,
|
||||
"type": "object",
|
||||
"title": "Metadata"
|
||||
"title": "Metadata",
|
||||
"default": {}
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
|
|
@ -3365,9 +3388,8 @@
|
|||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": ["id", "name", "user_id", "metadata", "created_at"],
|
||||
"title": "Collection",
|
||||
"exclude": ["h_metadata", "public_id"]
|
||||
"required": ["id", "name", "user_id", "app_id", "created_at"],
|
||||
"title": "Collection"
|
||||
},
|
||||
"CollectionCreate": {
|
||||
"properties": {
|
||||
|
|
@ -3446,25 +3468,28 @@
|
|||
"metadata": {
|
||||
"additionalProperties": true,
|
||||
"type": "object",
|
||||
"title": "Metadata"
|
||||
"title": "Metadata",
|
||||
"default": {}
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"title": "Created At"
|
||||
},
|
||||
"collection_id": { "type": "string", "title": "Collection Id" }
|
||||
"collection_id": { "type": "string", "title": "Collection Id" },
|
||||
"app_id": { "type": "string", "title": "App Id" },
|
||||
"user_id": { "type": "string", "title": "User Id" }
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
"id",
|
||||
"content",
|
||||
"metadata",
|
||||
"created_at",
|
||||
"collection_id"
|
||||
"collection_id",
|
||||
"app_id",
|
||||
"user_id"
|
||||
],
|
||||
"title": "Document",
|
||||
"exclude": ["h_metadata", "public_id"]
|
||||
"title": "Document"
|
||||
},
|
||||
"DocumentCreate": {
|
||||
"properties": {
|
||||
|
|
@ -3569,13 +3594,16 @@
|
|||
"metadata": {
|
||||
"additionalProperties": true,
|
||||
"type": "object",
|
||||
"title": "Metadata"
|
||||
"title": "Metadata",
|
||||
"default": {}
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"title": "Created At"
|
||||
}
|
||||
},
|
||||
"app_id": { "type": "string", "title": "App Id" },
|
||||
"user_id": { "type": "string", "title": "User Id" }
|
||||
},
|
||||
"type": "object",
|
||||
"required": [
|
||||
|
|
@ -3583,11 +3611,11 @@
|
|||
"content",
|
||||
"is_user",
|
||||
"session_id",
|
||||
"metadata",
|
||||
"created_at"
|
||||
"created_at",
|
||||
"app_id",
|
||||
"user_id"
|
||||
],
|
||||
"title": "Message",
|
||||
"exclude": ["h_metadata", "public_id"]
|
||||
"title": "Message"
|
||||
},
|
||||
"MessageBatchCreate": {
|
||||
"properties": {
|
||||
|
|
@ -3654,6 +3682,7 @@
|
|||
"label": { "type": "string", "title": "Label" },
|
||||
"content": { "type": "string", "title": "Content" },
|
||||
"user_id": { "type": "string", "title": "User Id" },
|
||||
"app_id": { "type": "string", "title": "App Id" },
|
||||
"session_id": {
|
||||
"anyOf": [{ "type": "string" }, { "type": "null" }],
|
||||
"title": "Session Id"
|
||||
|
|
@ -3665,12 +3694,18 @@
|
|||
"metadata": {
|
||||
"additionalProperties": true,
|
||||
"type": "object",
|
||||
"title": "Metadata"
|
||||
"title": "Metadata",
|
||||
"default": {}
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"title": "Created At"
|
||||
},
|
||||
"metamessage_type": {
|
||||
"type": "string",
|
||||
"title": "Metamessage Type",
|
||||
"readOnly": true
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
|
|
@ -3679,17 +3714,17 @@
|
|||
"label",
|
||||
"content",
|
||||
"user_id",
|
||||
"app_id",
|
||||
"session_id",
|
||||
"message_id",
|
||||
"metadata",
|
||||
"created_at"
|
||||
"created_at",
|
||||
"metamessage_type"
|
||||
],
|
||||
"title": "Metamessage",
|
||||
"exclude": ["h_metadata", "public_id"]
|
||||
"title": "Metamessage"
|
||||
},
|
||||
"MetamessageCreate": {
|
||||
"properties": {
|
||||
"label": {
|
||||
"metamessage_type": {
|
||||
"type": "string",
|
||||
"maxLength": 50,
|
||||
"minLength": 1,
|
||||
|
|
@ -3717,12 +3752,12 @@
|
|||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": ["label", "content"],
|
||||
"required": ["metamessage_type", "content"],
|
||||
"title": "MetamessageCreate"
|
||||
},
|
||||
"MetamessageGet": {
|
||||
"properties": {
|
||||
"label": {
|
||||
"metamessage_type": {
|
||||
"anyOf": [{ "type": "string" }, { "type": "null" }],
|
||||
"title": "Metamessage Type"
|
||||
},
|
||||
|
|
@ -3755,7 +3790,7 @@
|
|||
"anyOf": [{ "type": "string" }, { "type": "null" }],
|
||||
"title": "Message Id"
|
||||
},
|
||||
"label": {
|
||||
"metamessage_type": {
|
||||
"anyOf": [{ "type": "string" }, { "type": "null" }],
|
||||
"title": "Metamessage Type"
|
||||
},
|
||||
|
|
@ -3887,10 +3922,12 @@
|
|||
"id": { "type": "string", "title": "Id" },
|
||||
"is_active": { "type": "boolean", "title": "Is Active" },
|
||||
"user_id": { "type": "string", "title": "User Id" },
|
||||
"app_id": { "type": "string", "title": "App Id" },
|
||||
"metadata": {
|
||||
"additionalProperties": true,
|
||||
"type": "object",
|
||||
"title": "Metadata"
|
||||
"title": "Metadata",
|
||||
"default": {}
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
|
|
@ -3899,9 +3936,8 @@
|
|||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": ["id", "is_active", "user_id", "metadata", "created_at"],
|
||||
"title": "Session",
|
||||
"exclude": ["h_metadata", "public_id"]
|
||||
"required": ["id", "is_active", "user_id", "app_id", "created_at"],
|
||||
"title": "Session"
|
||||
},
|
||||
"SessionCreate": {
|
||||
"properties": {
|
||||
|
|
@ -3958,13 +3994,13 @@
|
|||
"metadata": {
|
||||
"additionalProperties": true,
|
||||
"type": "object",
|
||||
"title": "Metadata"
|
||||
"title": "Metadata",
|
||||
"default": {}
|
||||
}
|
||||
},
|
||||
"type": "object",
|
||||
"required": ["id", "name", "app_id", "created_at", "metadata"],
|
||||
"title": "User",
|
||||
"exclude": ["h_metadata", "public_id"]
|
||||
"required": ["id", "name", "app_id", "created_at"],
|
||||
"title": "User"
|
||||
},
|
||||
"UserCreate": {
|
||||
"properties": {
|
||||
|
|
@ -4033,3 +4069,4 @@
|
|||
"securitySchemes": { "HTTPBearer": { "type": "http", "scheme": "bearer" } }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,6 @@
|
|||
"dependencies": {
|
||||
"@mintlify/scraping": "^3.0.92",
|
||||
"honcho-ai": "^0.0.11",
|
||||
"mintlify": "^4.0.245"
|
||||
"mintlify": "^4.0.531"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
4106
docs/pnpm-lock.yaml
4106
docs/pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -1,21 +1,30 @@
|
|||
from os import getenv
|
||||
from typing import Optional
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
|
||||
def get_schema() -> str:
|
||||
return getenv("DATABASE_SCHEMA", "public")
|
||||
|
||||
def column_exists(table_name: str, column_name: str, inspector: Optional[sa.Inspector] = None) -> bool:
|
||||
|
||||
def column_exists(
|
||||
table_name: str, column_name: str, inspector: Optional[sa.Inspector] = None
|
||||
) -> bool:
|
||||
"""Check if a column exists in a table."""
|
||||
if inspector is None:
|
||||
inspector = sa.inspect(op.get_bind())
|
||||
schema = get_schema()
|
||||
existing_columns = [col["name"] for col in inspector.get_columns(table_name, schema=schema)]
|
||||
existing_columns = [
|
||||
col["name"] for col in inspector.get_columns(table_name, schema=schema)
|
||||
]
|
||||
return column_name in existing_columns
|
||||
|
||||
def fk_exists(table_name: str, fk_name: str, inspector: Optional[sa.Inspector] = None) -> bool:
|
||||
|
||||
def fk_exists(
|
||||
table_name: str, fk_name: str, inspector: Optional[sa.Inspector] = None
|
||||
) -> bool:
|
||||
"""Check if a foreign key exists in a table."""
|
||||
if inspector is None:
|
||||
inspector = sa.inspect(op.get_bind())
|
||||
|
|
@ -23,10 +32,14 @@ def fk_exists(table_name: str, fk_name: str, inspector: Optional[sa.Inspector] =
|
|||
foreign_keys = inspector.get_foreign_keys(table_name, schema=schema)
|
||||
return any(fk.get("name") == fk_name for fk in foreign_keys)
|
||||
|
||||
def index_exists(table_name: str, index_name: str, inspector: Optional[sa.Inspector] = None) -> bool:
|
||||
|
||||
def index_exists(
|
||||
table_name: str, index_name: str, inspector: Optional[sa.Inspector] = None
|
||||
) -> bool:
|
||||
"""Check if an index exists in a table."""
|
||||
if inspector is None:
|
||||
inspector = sa.inspect(op.get_bind())
|
||||
schema = get_schema()
|
||||
indexes = inspector.get_indexes(table_name, schema=schema)
|
||||
return any(idx["name"] == index_name for idx in indexes)
|
||||
return any(idx["name"] == index_name for idx in indexes)
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ Create Date: 2025-05-13 16:11:54.859842
|
|||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
from collections.abc import Sequence
|
||||
from typing import Union
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
|
|
|||
|
|
@ -5,22 +5,24 @@ Revises: b765d82110bd
|
|||
Create Date: 2025-05-13 17:10:33.805495
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
from collections.abc import Sequence
|
||||
from typing import Union
|
||||
|
||||
import sqlalchemy as sa
|
||||
from alembic import op
|
||||
from sqlalchemy.exc import IntegrityError, ProgrammingError
|
||||
|
||||
from migrations.utils import (
|
||||
get_schema,
|
||||
column_exists,
|
||||
fk_exists,
|
||||
get_schema,
|
||||
index_exists,
|
||||
)
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '556a16564f50'
|
||||
down_revision: Union[str, None] = 'b765d82110bd'
|
||||
revision: str = "556a16564f50"
|
||||
down_revision: Union[str, None] = "b765d82110bd"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
|
@ -32,7 +34,9 @@ def upgrade() -> None:
|
|||
|
||||
# 1. SESSIONS TABLE
|
||||
if not column_exists("sessions", "app_id", inspector):
|
||||
op.add_column("sessions", sa.Column("app_id", sa.Text(), nullable=True), schema=schema)
|
||||
op.add_column(
|
||||
"sessions", sa.Column("app_id", sa.Text(), nullable=True), schema=schema
|
||||
)
|
||||
print("Added app_id column to sessions table")
|
||||
else:
|
||||
print("app_id column already exists in sessions table")
|
||||
|
|
@ -47,11 +51,13 @@ def upgrade() -> None:
|
|||
["app_id"],
|
||||
["public_id"],
|
||||
source_schema=schema,
|
||||
referent_schema=schema
|
||||
referent_schema=schema,
|
||||
)
|
||||
print("Created app_id foreign key for sessions table")
|
||||
except IntegrityError:
|
||||
print("Cannot create app_id foreign key for sessions table - integrity error")
|
||||
print(
|
||||
"Cannot create app_id foreign key for sessions table - integrity error"
|
||||
)
|
||||
else:
|
||||
print("app_id foreign key already exists for sessions table")
|
||||
|
||||
|
|
@ -77,11 +83,17 @@ def upgrade() -> None:
|
|||
|
||||
# Create index for sessions.app_id
|
||||
if not index_exists("sessions", "ix_sessions_app_id"):
|
||||
op.create_index(op.f("ix_sessions_app_id"), "sessions", ["app_id"], unique=False, schema=schema)
|
||||
op.create_index(
|
||||
op.f("ix_sessions_app_id"),
|
||||
"sessions",
|
||||
["app_id"],
|
||||
unique=False,
|
||||
schema=schema,
|
||||
)
|
||||
print("Created index ix_sessions_app_id")
|
||||
else:
|
||||
print("Index ix_sessions_app_id already exists")
|
||||
|
||||
|
||||
# 2. MESSAGES TABLE
|
||||
if not column_exists("messages", "app_id", inspector):
|
||||
op.add_column("messages", sa.Column("app_id", sa.Text()), schema=schema)
|
||||
|
|
@ -105,14 +117,16 @@ def upgrade() -> None:
|
|||
["app_id"],
|
||||
["public_id"],
|
||||
source_schema=schema,
|
||||
referent_schema=schema
|
||||
referent_schema=schema,
|
||||
)
|
||||
print("Created app_id foreign key for messages table")
|
||||
except IntegrityError:
|
||||
print("Cannot create app_id foreign key for messages table - integrity error")
|
||||
print(
|
||||
"Cannot create app_id foreign key for messages table - integrity error"
|
||||
)
|
||||
else:
|
||||
print("app_id foreign key already exists for messages table")
|
||||
|
||||
|
||||
if not fk_exists("messages", "messages_user_id_fkey", inspector):
|
||||
try:
|
||||
op.create_foreign_key(
|
||||
|
|
@ -122,11 +136,13 @@ def upgrade() -> None:
|
|||
["user_id"],
|
||||
["public_id"],
|
||||
source_schema=schema,
|
||||
referent_schema=schema
|
||||
referent_schema=schema,
|
||||
)
|
||||
print("Created user_id foreign key for messages table")
|
||||
except IntegrityError:
|
||||
print("Cannot create user_id foreign key for messages table - integrity error")
|
||||
print(
|
||||
"Cannot create user_id foreign key for messages table - integrity error"
|
||||
)
|
||||
else:
|
||||
print("user_id foreign key already exists for messages table")
|
||||
|
||||
|
|
@ -145,7 +161,7 @@ def upgrade() -> None:
|
|||
print("Updated app_id and user_id values from sessions for messages table")
|
||||
except Exception as e:
|
||||
print(f"Error updating app_id and user_id values for messages table: {e}")
|
||||
|
||||
|
||||
# Make app_id and user_id non-nullable
|
||||
try:
|
||||
op.alter_column("messages", "app_id", nullable=False, schema=schema)
|
||||
|
|
@ -156,17 +172,29 @@ def upgrade() -> None:
|
|||
|
||||
# Create indices for messages foreign keys
|
||||
if not index_exists("messages", "ix_messages_app_id"):
|
||||
op.create_index(op.f("ix_messages_app_id"), "messages", ["app_id"], unique=False, schema=schema)
|
||||
op.create_index(
|
||||
op.f("ix_messages_app_id"),
|
||||
"messages",
|
||||
["app_id"],
|
||||
unique=False,
|
||||
schema=schema,
|
||||
)
|
||||
print("Created index ix_messages_app_id")
|
||||
else:
|
||||
print("Index ix_messages_app_id already exists")
|
||||
|
||||
if not index_exists("messages", "ix_messages_user_id"):
|
||||
op.create_index(op.f("ix_messages_user_id"), "messages", ["user_id"], unique=False, schema=schema)
|
||||
op.create_index(
|
||||
op.f("ix_messages_user_id"),
|
||||
"messages",
|
||||
["user_id"],
|
||||
unique=False,
|
||||
schema=schema,
|
||||
)
|
||||
print("Created index ix_messages_user_id")
|
||||
else:
|
||||
print("Index ix_messages_user_id already exists")
|
||||
|
||||
print("Index ix_messages_user_id already exists")
|
||||
|
||||
# 3. METAMESSAGES TABLE
|
||||
if not column_exists("metamessages", "app_id", inspector):
|
||||
op.add_column("metamessages", sa.Column("app_id", sa.Text()), schema=schema)
|
||||
|
|
@ -184,14 +212,16 @@ def upgrade() -> None:
|
|||
["app_id"],
|
||||
["public_id"],
|
||||
source_schema=schema,
|
||||
referent_schema=schema
|
||||
referent_schema=schema,
|
||||
)
|
||||
print("Created app_id foreign key for metamessages table")
|
||||
except IntegrityError:
|
||||
print("Cannot create app_id foreign key for metamessages table - integrity error")
|
||||
print(
|
||||
"Cannot create app_id foreign key for metamessages table - integrity error"
|
||||
)
|
||||
else:
|
||||
print("app_id foreign key already exists for metamessages table")
|
||||
|
||||
|
||||
# Data migration: Fill app_id from users table
|
||||
try:
|
||||
op.execute("""
|
||||
|
|
@ -214,7 +244,13 @@ def upgrade() -> None:
|
|||
|
||||
# Create index for metamessages.app_id
|
||||
if not index_exists("metamessages", "ix_metamessages_app_id"):
|
||||
op.create_index(op.f("ix_metamessages_app_id"), "metamessages", ["app_id"], unique=False, schema=schema)
|
||||
op.create_index(
|
||||
op.f("ix_metamessages_app_id"),
|
||||
"metamessages",
|
||||
["app_id"],
|
||||
unique=False,
|
||||
schema=schema,
|
||||
)
|
||||
print("Created index ix_metamessages_app_id")
|
||||
else:
|
||||
print("Index ix_metamessages_app_id already exists")
|
||||
|
|
@ -236,14 +272,16 @@ def upgrade() -> None:
|
|||
["app_id"],
|
||||
["public_id"],
|
||||
source_schema=schema,
|
||||
referent_schema=schema
|
||||
referent_schema=schema,
|
||||
)
|
||||
print("Created app_id foreign key for collections table")
|
||||
except IntegrityError:
|
||||
print("Cannot create app_id foreign key for collections table - integrity error")
|
||||
print(
|
||||
"Cannot create app_id foreign key for collections table - integrity error"
|
||||
)
|
||||
else:
|
||||
print("app_id foreign key already exists for collections table")
|
||||
|
||||
|
||||
# Data migration: Fill app_id from users table
|
||||
try:
|
||||
op.execute("""
|
||||
|
|
@ -266,11 +304,17 @@ def upgrade() -> None:
|
|||
|
||||
# Create index for collections.app_id
|
||||
if not index_exists("collections", "ix_collections_app_id"):
|
||||
op.create_index(op.f("ix_collections_app_id"), "collections", ["app_id"], unique=False, schema=schema)
|
||||
op.create_index(
|
||||
op.f("ix_collections_app_id"),
|
||||
"collections",
|
||||
["app_id"],
|
||||
unique=False,
|
||||
schema=schema,
|
||||
)
|
||||
print("Created index ix_collections_app_id")
|
||||
else:
|
||||
print("Index ix_collections_app_id already exists")
|
||||
|
||||
|
||||
# 5. DOCUMENTS TABLE
|
||||
if not column_exists("documents", "app_id", inspector):
|
||||
op.add_column("documents", sa.Column("app_id", sa.Text()), schema=schema)
|
||||
|
|
@ -294,14 +338,16 @@ def upgrade() -> None:
|
|||
["app_id"],
|
||||
["public_id"],
|
||||
source_schema=schema,
|
||||
referent_schema=schema
|
||||
referent_schema=schema,
|
||||
)
|
||||
print("Created app_id foreign key for documents table")
|
||||
except IntegrityError:
|
||||
print("Cannot create app_id foreign key for documents table - integrity error")
|
||||
print(
|
||||
"Cannot create app_id foreign key for documents table - integrity error"
|
||||
)
|
||||
else:
|
||||
print("app_id foreign key already exists for documents table")
|
||||
|
||||
|
||||
if not fk_exists("documents", "documents_user_id_fkey", inspector):
|
||||
try:
|
||||
op.create_foreign_key(
|
||||
|
|
@ -311,14 +357,16 @@ def upgrade() -> None:
|
|||
["user_id"],
|
||||
["public_id"],
|
||||
source_schema=schema,
|
||||
referent_schema=schema
|
||||
referent_schema=schema,
|
||||
)
|
||||
print("Created user_id foreign key for documents table")
|
||||
except IntegrityError:
|
||||
print("Cannot create user_id foreign key for documents table - integrity error")
|
||||
print(
|
||||
"Cannot create user_id foreign key for documents table - integrity error"
|
||||
)
|
||||
else:
|
||||
print("user_id foreign key already exists for documents table")
|
||||
|
||||
|
||||
# Data migration: Fill app_id and user_id from collections table
|
||||
try:
|
||||
op.execute("""
|
||||
|
|
@ -345,23 +393,36 @@ def upgrade() -> None:
|
|||
|
||||
# Create indices for documents foreign keys
|
||||
if not index_exists("documents", "ix_documents_app_id"):
|
||||
op.create_index(op.f("ix_documents_app_id"), "documents", ["app_id"], unique=False, schema=schema)
|
||||
op.create_index(
|
||||
op.f("ix_documents_app_id"),
|
||||
"documents",
|
||||
["app_id"],
|
||||
unique=False,
|
||||
schema=schema,
|
||||
)
|
||||
print("Created index ix_documents_app_id")
|
||||
else:
|
||||
print("Index ix_documents_app_id already exists")
|
||||
|
||||
if not index_exists("documents", "ix_documents_user_id"):
|
||||
op.create_index(op.f("ix_documents_user_id"), "documents", ["user_id"], unique=False, schema=schema)
|
||||
op.create_index(
|
||||
op.f("ix_documents_user_id"),
|
||||
"documents",
|
||||
["user_id"],
|
||||
unique=False,
|
||||
schema=schema,
|
||||
)
|
||||
print("Created index ix_documents_user_id")
|
||||
else:
|
||||
print("Index ix_documents_user_id already exists")
|
||||
|
||||
|
||||
|
||||
def downgrade():
|
||||
schema = get_schema()
|
||||
inspector = sa.inspect(op.get_bind())
|
||||
|
||||
|
||||
# 5. Documents table
|
||||
|
||||
|
||||
# Drop indices
|
||||
if index_exists("documents", "ix_documents_app_id", inspector):
|
||||
op.drop_index("ix_documents_app_id", table_name="documents", schema=schema)
|
||||
|
|
@ -374,27 +435,27 @@ def downgrade():
|
|||
op.alter_column("documents", "app_id", nullable=True, schema=schema)
|
||||
op.alter_column("documents", "user_id", nullable=True, schema=schema)
|
||||
print("Made app_id and user_id nullable again for documents table")
|
||||
|
||||
|
||||
# Drop foreign key constraints
|
||||
try:
|
||||
op.drop_constraint("documents_user_id_fkey", "documents", schema=schema)
|
||||
print("Dropped user_id foreign key for documents table")
|
||||
except Exception as e:
|
||||
print(f"Error dropping user_id foreign key for documents table: {e}")
|
||||
|
||||
|
||||
try:
|
||||
op.drop_constraint("documents_app_id_fkey", "documents", schema=schema)
|
||||
print("Dropped app_id foreign key for documents table")
|
||||
except Exception as e:
|
||||
print(f"Error dropping app_id foreign key for documents table: {e}")
|
||||
|
||||
|
||||
# Drop the columns
|
||||
op.drop_column("documents", "user_id", schema=schema)
|
||||
op.drop_column("documents", "app_id", schema=schema)
|
||||
print("Dropped app_id and user_id columns from documents table")
|
||||
|
||||
|
||||
# 4. Collections table
|
||||
|
||||
|
||||
# Drop indices
|
||||
if index_exists("collections", "ix_collections_app_id", inspector):
|
||||
op.drop_index("ix_collections_app_id", table_name="collections", schema=schema)
|
||||
|
|
@ -403,42 +464,44 @@ def downgrade():
|
|||
# Make app_id nullable again
|
||||
op.alter_column("collections", "app_id", nullable=True, schema=schema)
|
||||
print("Made app_id nullable again for collections table")
|
||||
|
||||
|
||||
# Drop foreign key constraint
|
||||
try:
|
||||
op.drop_constraint("collections_app_id_fkey", "collections", schema=schema)
|
||||
print("Dropped app_id foreign key for collections table")
|
||||
except Exception as e:
|
||||
print(f"Error dropping app_id foreign key for collections table: {e}")
|
||||
|
||||
|
||||
# Drop the column
|
||||
op.drop_column("collections", "app_id", schema=schema)
|
||||
print("Dropped app_id column from collections table")
|
||||
|
||||
|
||||
# 3. Metamessages table
|
||||
|
||||
|
||||
# Drop indices
|
||||
if index_exists("metamessages", "ix_metamessages_app_id", inspector):
|
||||
op.drop_index("ix_metamessages_app_id", table_name="metamessages", schema=schema)
|
||||
op.drop_index(
|
||||
"ix_metamessages_app_id", table_name="metamessages", schema=schema
|
||||
)
|
||||
print("Dropped index ix_metamessages_app_id")
|
||||
|
||||
# Make app_id nullable again
|
||||
op.alter_column("metamessages", "app_id", nullable=True, schema=schema)
|
||||
print("Made app_id nullable again for metamessages table")
|
||||
|
||||
|
||||
# Drop foreign key constraint
|
||||
try:
|
||||
op.drop_constraint("metamessages_app_id_fkey", "metamessages", schema=schema)
|
||||
print("Dropped app_id foreign key for metamessages table")
|
||||
except Exception as e:
|
||||
print(f"Error dropping app_id foreign key for metamessages table: {e}")
|
||||
|
||||
|
||||
# Drop the column
|
||||
op.drop_column("metamessages", "app_id", schema=schema)
|
||||
print("Dropped app_id column from metamessages table")
|
||||
|
||||
|
||||
# 2. Messages table
|
||||
|
||||
|
||||
# Drop indices
|
||||
if index_exists("messages", "ix_messages_app_id", inspector):
|
||||
op.drop_index("ix_messages_app_id", table_name="messages", schema=schema)
|
||||
|
|
@ -451,27 +514,27 @@ def downgrade():
|
|||
op.alter_column("messages", "app_id", nullable=True, schema=schema)
|
||||
op.alter_column("messages", "user_id", nullable=True, schema=schema)
|
||||
print("Made app_id and user_id nullable again for messages table")
|
||||
|
||||
|
||||
# Drop foreign key constraints
|
||||
try:
|
||||
op.drop_constraint("messages_user_id_fkey", "messages", schema=schema)
|
||||
print("Dropped user_id foreign key for messages table")
|
||||
except Exception as e:
|
||||
print(f"Error dropping user_id foreign key for messages table: {e}")
|
||||
|
||||
|
||||
try:
|
||||
op.drop_constraint("messages_app_id_fkey", "messages", schema=schema)
|
||||
print("Dropped app_id foreign key for messages table")
|
||||
except Exception as e:
|
||||
print(f"Error dropping app_id foreign key for messages table: {e}")
|
||||
|
||||
|
||||
# Drop the columns
|
||||
op.drop_column("messages", "user_id", schema=schema)
|
||||
op.drop_column("messages", "app_id", schema=schema)
|
||||
print("Dropped app_id and user_id columns from messages table")
|
||||
|
||||
|
||||
# 1. Sessions table
|
||||
|
||||
|
||||
# Drop indices
|
||||
if index_exists("sessions", "ix_sessions_app_id", inspector):
|
||||
op.drop_index("ix_sessions_app_id", table_name="sessions", schema=schema)
|
||||
|
|
@ -480,14 +543,15 @@ def downgrade():
|
|||
# Make app_id nullable again
|
||||
op.alter_column("sessions", "app_id", nullable=True, schema=schema)
|
||||
print("Made app_id nullable again for sessions table")
|
||||
|
||||
|
||||
# Drop foreign key constraint
|
||||
try:
|
||||
op.drop_constraint("sessions_app_id_fkey", "sessions", schema=schema)
|
||||
print("Dropped app_id foreign key for sessions table")
|
||||
except Exception as e:
|
||||
print(f"Error dropping app_id foreign key for sessions table: {e}")
|
||||
|
||||
|
||||
# Drop the column
|
||||
op.drop_column("sessions", "app_id", schema=schema)
|
||||
print("Dropped app_id column from sessions table")
|
||||
print("Dropped app_id column from sessions table")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[project]
|
||||
name = "honcho"
|
||||
version = "1.0.0"
|
||||
version = "1.1.0"
|
||||
description = "Honcho Server"
|
||||
authors = [
|
||||
{name = "Plastic Labs", email = "hello@plasticlabs.ai"},
|
||||
|
|
|
|||
26
src/agent.py
26
src/agent.py
|
|
@ -192,15 +192,15 @@ async def chat(
|
|||
)
|
||||
|
||||
stmt = (
|
||||
select(models.Message)
|
||||
.where(models.Message.app_id == app_id)
|
||||
.where(models.Message.user_id == user_id)
|
||||
.where(models.Message.session_id == session_id)
|
||||
.where(models.Message.is_user)
|
||||
.order_by(models.Message.id.desc())
|
||||
.limit(1)
|
||||
)
|
||||
|
||||
select(models.Message)
|
||||
.where(models.Message.app_id == app_id)
|
||||
.where(models.Message.user_id == user_id)
|
||||
.where(models.Message.session_id == session_id)
|
||||
.where(models.Message.is_user)
|
||||
.order_by(models.Message.id.desc())
|
||||
.limit(1)
|
||||
)
|
||||
|
||||
latest_messages = await db.execute(stmt)
|
||||
latest_message = latest_messages.scalar_one_or_none()
|
||||
latest_message_id = latest_message.public_id if latest_message else None
|
||||
|
|
@ -451,11 +451,10 @@ async def generate_user_representation(
|
|||
logger.debug(f"Fetching latest representation for session {session_id}")
|
||||
latest_representation_stmt = (
|
||||
select(models.Metamessage)
|
||||
.where(models.Metamessage.session_id == session_id) # only from the same session
|
||||
.where(
|
||||
models.Metamessage.label
|
||||
== USER_REPRESENTATION_METAMESSAGE_TYPE
|
||||
)
|
||||
models.Metamessage.session_id == session_id
|
||||
) # only from the same session
|
||||
.where(models.Metamessage.label == USER_REPRESENTATION_METAMESSAGE_TYPE)
|
||||
.order_by(models.Metamessage.id.desc())
|
||||
.limit(1)
|
||||
)
|
||||
|
|
@ -519,6 +518,7 @@ RELEVANT LONG-TERM FACTS ABOUT THE USER:
|
|||
message_id = None
|
||||
else:
|
||||
metamessage = models.Metamessage(
|
||||
app_id=app_id,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
message_id=message_id if message_id else None,
|
||||
|
|
|
|||
23
src/crud.py
23
src/crud.py
|
|
@ -1,6 +1,6 @@
|
|||
from collections.abc import Sequence
|
||||
from logging import getLogger
|
||||
from typing import List, Optional
|
||||
from typing import Optional
|
||||
|
||||
from dotenv import load_dotenv
|
||||
from openai import AsyncOpenAI
|
||||
|
|
@ -54,7 +54,6 @@ async def get_app(db: AsyncSession, app_id: str) -> models.App:
|
|||
|
||||
|
||||
async def get_all_apps(
|
||||
db: AsyncSession,
|
||||
reverse: Optional[bool] = False,
|
||||
filter: Optional[dict] = None,
|
||||
) -> Select:
|
||||
|
|
@ -260,7 +259,6 @@ async def get_user_by_name(db: AsyncSession, app_id: str, name: str) -> models.U
|
|||
|
||||
|
||||
async def get_users(
|
||||
db: AsyncSession,
|
||||
app_id: str,
|
||||
reverse: bool = False,
|
||||
filter: Optional[dict] = None,
|
||||
|
|
@ -409,7 +407,7 @@ async def create_session(
|
|||
"""
|
||||
try:
|
||||
# This will raise ResourceNotFoundException if user not found
|
||||
_honcho_user = await get_user(db, app_id=app_id, user_id=user_id)
|
||||
await get_user(db, app_id=app_id, user_id=user_id)
|
||||
|
||||
honcho_session = models.Session(
|
||||
user_id=user_id,
|
||||
|
|
@ -715,7 +713,6 @@ async def create_messages(
|
|||
|
||||
|
||||
async def get_messages(
|
||||
db: AsyncSession,
|
||||
app_id: str,
|
||||
user_id: str,
|
||||
session_id: str,
|
||||
|
|
@ -749,7 +746,7 @@ async def get_message(
|
|||
) -> Optional[models.Message]:
|
||||
stmt = (
|
||||
select(models.Message)
|
||||
.where(models.Message.app_id == app_id)
|
||||
.where(models.Message.app_id == app_id)
|
||||
.where(models.Message.user_id == user_id)
|
||||
.where(models.Message.session_id == session_id)
|
||||
.where(models.Message.public_id == message_id)
|
||||
|
|
@ -845,7 +842,6 @@ async def create_metamessage(
|
|||
|
||||
|
||||
async def get_metamessages(
|
||||
db: AsyncSession,
|
||||
app_id: str,
|
||||
user_id: str,
|
||||
session_id: Optional[str] = None,
|
||||
|
|
@ -942,7 +938,7 @@ async def update_metamessage(
|
|||
db,
|
||||
app_id=app_id,
|
||||
session_id=metamessage.session_id,
|
||||
user_id=metamessage.user_id,
|
||||
user_id=user_id,
|
||||
message_id=metamessage.message_id,
|
||||
)
|
||||
if message is None:
|
||||
|
|
@ -975,7 +971,6 @@ async def update_metamessage(
|
|||
|
||||
|
||||
async def get_collections(
|
||||
db: AsyncSession,
|
||||
app_id: str,
|
||||
user_id: str,
|
||||
reverse: Optional[bool] = False,
|
||||
|
|
@ -1134,6 +1129,9 @@ async def create_user_protected_collection(
|
|||
name=DEF_PROTECTED_COLLECTION_NAME,
|
||||
)
|
||||
try:
|
||||
# This will raise ResourceNotFoundException if user not found
|
||||
await get_user(db, app_id=app_id, user_id=user_id)
|
||||
|
||||
db.add(honcho_collection)
|
||||
await db.commit()
|
||||
except IntegrityError:
|
||||
|
|
@ -1272,7 +1270,6 @@ async def delete_collection(
|
|||
|
||||
|
||||
async def get_documents(
|
||||
db: AsyncSession,
|
||||
app_id: str,
|
||||
user_id: str,
|
||||
collection_id: str,
|
||||
|
|
@ -1400,7 +1397,7 @@ async def create_document(
|
|||
"""
|
||||
|
||||
# This will raise ResourceNotFoundException if collection not found
|
||||
collection = await get_collection_by_id(
|
||||
await get_collection_by_id(
|
||||
db, app_id=app_id, collection_id=collection_id, user_id=user_id
|
||||
)
|
||||
|
||||
|
|
@ -1518,7 +1515,7 @@ async def get_duplicate_documents(
|
|||
collection_id: str,
|
||||
content: str,
|
||||
similarity_threshold: float = 0.85,
|
||||
) -> List[models.Document]:
|
||||
) -> list[models.Document]:
|
||||
"""Check if a document with similar content already exists in the collection.
|
||||
|
||||
Args:
|
||||
|
|
@ -1542,6 +1539,8 @@ async def get_duplicate_documents(
|
|||
# Find documents with similar embeddings
|
||||
stmt = (
|
||||
select(models.Document)
|
||||
.where(models.Document.app_id == app_id)
|
||||
.where(models.Document.user_id == user_id)
|
||||
.where(models.Document.collection_id == collection_id)
|
||||
.where(
|
||||
models.Document.embedding.cosine_distance(embedding)
|
||||
|
|
|
|||
|
|
@ -51,7 +51,11 @@ async def process_item(db: AsyncSession, payload: dict):
|
|||
await process_ai_message(*processing_args)
|
||||
logger.debug(f"Finished processing message: {payload['message_id']}")
|
||||
await summarize_if_needed(
|
||||
db, payload["session_id"], payload["user_id"], payload["message_id"]
|
||||
db,
|
||||
payload["app_id"],
|
||||
payload["session_id"],
|
||||
payload["user_id"],
|
||||
payload["message_id"],
|
||||
)
|
||||
return
|
||||
|
||||
|
|
@ -147,7 +151,7 @@ async def process_user_message(
|
|||
|
||||
|
||||
async def summarize_if_needed(
|
||||
db: AsyncSession, session_id: str, user_id: str, message_id: str
|
||||
db: AsyncSession, app_id: str, session_id: str, user_id: str, message_id: str
|
||||
):
|
||||
summary_start = os.times()[4]
|
||||
logger.debug("Checking if summaries should be created")
|
||||
|
|
@ -193,6 +197,7 @@ async def summarize_if_needed(
|
|||
# Save the long summary as a metamessage and capture the returned object
|
||||
latest_long_summary = await history.save_summary_metamessage(
|
||||
db=db,
|
||||
app_id=app_id,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
message_id=message_id,
|
||||
|
|
@ -225,6 +230,7 @@ async def summarize_if_needed(
|
|||
# Save the short summary as a metamessage
|
||||
await history.save_summary_metamessage(
|
||||
db=db,
|
||||
app_id=app_id,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
message_id=message_id,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import logging
|
||||
import os
|
||||
import re
|
||||
import uuid
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
|
|
@ -110,7 +111,7 @@ app = FastAPI(
|
|||
title="Honcho API",
|
||||
summary="The Identity Layer for the Agentic World",
|
||||
description="""Honcho is a platform for giving agents user-centric memory and social cognition""",
|
||||
version="1.0.0",
|
||||
version="1.1.0",
|
||||
contact={
|
||||
"name": "Plastic Labs",
|
||||
"url": "https://honcho.dev",
|
||||
|
|
@ -173,8 +174,8 @@ async def global_exception_handler(request: Request, exc: Exception):
|
|||
@app.middleware("http")
|
||||
async def track_request(request: Request, call_next):
|
||||
# Create a request ID that includes endpoint information
|
||||
endpoint = request.url.path.replace("/", "_")
|
||||
request_id = f"{endpoint}:{str(uuid.uuid4())[:8]}"
|
||||
endpoint = re.sub(r"/[A-Za-z0-9_-]{21}", "", request.url.path).replace("/", "_")
|
||||
request_id = f"{request.method}:{endpoint}:{str(uuid.uuid4())[:8]}"
|
||||
|
||||
# Store in request state and context var
|
||||
request.state.request_id = request_id
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ async def get_all_apps(
|
|||
):
|
||||
"""Get all Apps"""
|
||||
filter_param = None
|
||||
if options and hasattr(options, 'filter'):
|
||||
if options and hasattr(options, "filter"):
|
||||
filter_param = options.filter
|
||||
if filter_param == {}:
|
||||
filter_param = None
|
||||
|
|
@ -70,7 +70,6 @@ async def get_all_apps(
|
|||
return await paginate(
|
||||
db,
|
||||
await crud.get_all_apps(
|
||||
db,
|
||||
reverse=reverse,
|
||||
filter=filter_param,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -81,15 +81,15 @@ async def get_collections(
|
|||
):
|
||||
"""Get All Collections for a User"""
|
||||
filter_param = None
|
||||
if options and hasattr(options, 'filter'):
|
||||
if options and hasattr(options, "filter"):
|
||||
filter_param = options.filter
|
||||
if filter_param == {}: # Explicitly check for empty dict
|
||||
if filter_param == {}: # Explicitly check for empty dict
|
||||
filter_param = None
|
||||
|
||||
return await paginate(
|
||||
db,
|
||||
await crud.get_collections(
|
||||
db, app_id=app_id, user_id=user_id, filter=filter_param, reverse=reverse
|
||||
app_id=app_id, user_id=user_id, filter=filter_param, reverse=reverse
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ async def get_documents(
|
|||
|
||||
try:
|
||||
documents_query = await crud.get_documents(
|
||||
db,
|
||||
app_id=app_id,
|
||||
user_id=user_id,
|
||||
collection_id=collection_id,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import logging
|
||||
import os
|
||||
from typing import List, Optional
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, BackgroundTasks, Body, Depends, Path, Query
|
||||
from fastapi_pagination import Page
|
||||
|
|
@ -189,7 +189,7 @@ async def create_message_for_session(
|
|||
raise ResourceNotFoundException("Session not found") from e
|
||||
|
||||
|
||||
@router.post("/batch", response_model=List[schemas.Message])
|
||||
@router.post("/batch", response_model=list[schemas.Message])
|
||||
async def create_batch_messages_for_session(
|
||||
background_tasks: BackgroundTasks,
|
||||
app_id: str = Path(..., description="ID of the app"),
|
||||
|
|
@ -254,13 +254,12 @@ async def get_messages(
|
|||
"""Get all messages for a session"""
|
||||
try:
|
||||
filter = None
|
||||
if options and hasattr(options, 'filter'):
|
||||
if options and hasattr(options, "filter"):
|
||||
filter = options.filter
|
||||
if filter == {}:
|
||||
filter = None
|
||||
|
||||
messages_query = await crud.get_messages(
|
||||
db,
|
||||
app_id=app_id,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
|
|
|
|||
|
|
@ -73,20 +73,19 @@ async def get_metamessages(
|
|||
filter_param = None
|
||||
|
||||
if options:
|
||||
if hasattr(options, 'session_id') and options.session_id:
|
||||
if hasattr(options, "session_id") and options.session_id:
|
||||
session_id_param = options.session_id
|
||||
if hasattr(options, 'message_id') and options.message_id:
|
||||
if hasattr(options, "message_id") and options.message_id:
|
||||
message_id_param = options.message_id
|
||||
if hasattr(options, 'label') and options.label:
|
||||
if hasattr(options, "label") and options.label:
|
||||
label_param = options.label
|
||||
if hasattr(options, 'filter') and options.filter:
|
||||
if hasattr(options, "filter") and options.filter:
|
||||
filter_param = options.filter
|
||||
if filter_param == {}: # Explicitly check for empty dict
|
||||
if filter_param == {}: # Explicitly check for empty dict
|
||||
filter_param = None
|
||||
|
||||
try:
|
||||
metamessages_query = await crud.get_metamessages(
|
||||
db,
|
||||
app_id=app_id,
|
||||
user_id=user_id,
|
||||
session_id=session_id_param,
|
||||
|
|
|
|||
|
|
@ -51,14 +51,14 @@ async def get_users(
|
|||
):
|
||||
"""Get All Users for an App"""
|
||||
filter_param = None
|
||||
if options and hasattr(options, 'filter'):
|
||||
if options and hasattr(options, "filter"):
|
||||
filter_param = options.filter
|
||||
if filter_param == {}:
|
||||
filter_param = None
|
||||
|
||||
return await paginate(
|
||||
db,
|
||||
await crud.get_users(db, app_id=app_id, reverse=reverse, filter=filter_param),
|
||||
await crud.get_users(app_id=app_id, reverse=reverse, filter=filter_param),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import datetime
|
||||
from typing import Annotated
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field, field_validator, computed_field
|
||||
from pydantic import BaseModel, ConfigDict, Field, computed_field, field_validator
|
||||
|
||||
|
||||
class AppBase(BaseModel):
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
from collections import OrderedDict
|
||||
import asyncio
|
||||
from collections import OrderedDict
|
||||
|
||||
|
||||
class LRUCache:
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -220,6 +220,7 @@ Provide a {"comprehensive" if summary_type == SummaryType.LONG else "concise"} s
|
|||
|
||||
async def save_summary_metamessage(
|
||||
db: AsyncSession,
|
||||
app_id: str,
|
||||
user_id: str,
|
||||
session_id: str,
|
||||
message_id: str,
|
||||
|
|
@ -247,6 +248,7 @@ async def save_summary_metamessage(
|
|||
|
||||
# Create and save the metamessage
|
||||
metamessage = models.Metamessage(
|
||||
app_id=app_id,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
message_id=message_id,
|
||||
|
|
@ -389,4 +391,3 @@ def format_messages(messages: list[models.Message]) -> str:
|
|||
return "\n".join(
|
||||
[f"{'user' if msg.is_user else 'assistant'}: {msg.content}" for msg in messages]
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue