fleet-memory/hindsight-api/hindsight_api/extensions/__init__.py
Chris Bartholomew 1d17dea2f1
Add on_file_convert_complete extension hook after file-to-markdown conversion (#507)
* Add file upload API with parser selection and conversion hooks

- Add FileRetainRequest.parser field for per-request parser selection
- Add FileConvertResult dataclass and on_file_convert_complete extension hook
- Fire hook after file-to-markdown conversion with output text for metering
- Fix obstore.Bytes incompatibility with httpx in Iris parser (GCS returns
  obstore.Bytes instead of plain bytes)
- Export new types from extensions __init__

* remove parser field from FileRetainRequest API

Parser selection remains server-side only via HINDSIGHT_API_FILE_PARSER config.

* test: add tests for on_file_convert_complete extension hook

Verifies that the hook is called with correct parameters on success,
called once per file for multi-file uploads, and not called when
file conversion fails.

* test: verify tenant_id propagation to on_file_convert_complete hook

---------

Co-authored-by: Nicolò Boschi <boschi1997@gmail.com>
2026-03-06 09:56:53 +01:00

103 lines
2.9 KiB
Python

"""
Hindsight Extensions System.
Extensions allow customizing and extending Hindsight behavior without modifying core code.
Extensions are loaded via environment variables pointing to implementation classes.
Example:
HINDSIGHT_API_OPERATION_VALIDATOR_EXTENSION=mypackage.validators:MyValidator
HINDSIGHT_API_OPERATION_VALIDATOR_MAX_RETRIES=3
HINDSIGHT_API_HTTP_EXTENSION=mypackage.http:MyHttpExtension
HINDSIGHT_API_HTTP_SOME_CONFIG=value
Extensions receive an ExtensionContext that provides a controlled API for interacting
with the system (e.g., running migrations for tenant schemas).
"""
from hindsight_api.extensions.base import Extension
from hindsight_api.extensions.builtin import ApiKeyTenantExtension, SupabaseTenantExtension
from hindsight_api.extensions.context import DefaultExtensionContext, ExtensionContext
from hindsight_api.extensions.http import HttpExtension
from hindsight_api.extensions.loader import load_extension
from hindsight_api.extensions.mcp import MCPExtension
from hindsight_api.extensions.operation_validator import (
# Bank Management operations
BankListContext,
BankListResult,
BankReadContext,
BankWriteContext,
# Consolidation operation
ConsolidateContext,
ConsolidateResult,
# File Conversion
FileConvertResult,
# Mental Model operations
MentalModelGetContext,
MentalModelGetResult,
MentalModelRefreshContext,
MentalModelRefreshResult,
# Core operations
OperationValidationError,
OperationValidatorExtension,
RecallContext,
RecallResult,
ReflectContext,
ReflectResultContext,
RetainContext,
RetainResult,
ValidationResult,
)
from hindsight_api.extensions.tenant import (
AuthenticationError,
Tenant,
TenantContext,
TenantExtension,
)
from hindsight_api.models import RequestContext
__all__ = [
# Base
"Extension",
"load_extension",
# Context
"ExtensionContext",
"DefaultExtensionContext",
# HTTP Extension
"HttpExtension",
# MCP Extension
"MCPExtension",
# Operation Validator - Core
"OperationValidationError",
"OperationValidatorExtension",
"RecallContext",
"RecallResult",
"ReflectContext",
"ReflectResultContext",
"RetainContext",
"RetainResult",
"ValidationResult",
# Operation Validator - Bank Management
"BankListContext",
"BankListResult",
"BankReadContext",
"BankWriteContext",
# Operation Validator - Consolidation
"ConsolidateContext",
"ConsolidateResult",
# Operation Validator - File Conversion
"FileConvertResult",
# Operation Validator - Mental Model
"MentalModelGetContext",
"MentalModelGetResult",
"MentalModelRefreshContext",
"MentalModelRefreshResult",
# Tenant/Auth
"ApiKeyTenantExtension",
"SupabaseTenantExtension",
"AuthenticationError",
"RequestContext",
"Tenant",
"TenantContext",
"TenantExtension",
]