feat: bank template import/export with Template Hub (#819)
* feat(api): add bank template import/export endpoints
Add POST /banks/{bank_id}/import and GET /banks/{bank_id}/export
endpoints for declarative bank setup via JSON manifests.
A template manifest (version 1) can include bank config overrides
and mental model definitions. Import creates or updates mental
models matched by id, applies config as per-bank overrides, and
returns async operation IDs for content generation.
Export dumps a bank's explicit overrides and mental models as a
manifest that can be re-imported into another bank.
Includes control plane UI: bank creation dialog now accepts an
optional template JSON to pre-configure the bank on creation.
* docs: add Template Gallery page and bank templates reference
- Template Gallery (/templates) with search, category filter, manifest
preview modal with copy-to-clipboard
- 5 starter templates: Customer Support, Research Assistant, Personal
Journal, Code Review Buddy, Meeting Notes
- Bank Templates API reference doc (developer/api/bank-templates)
- Sidebar entry under API section
* docs: add Template Gallery links to navbar and sidebar
- Top navbar: "Templates" link between Integrations and Changelog
- Sidebar: "Template Gallery" in Resources section
* fix(docs): remove emoji icons, autofocus search, fix placeholder in template gallery
* docs: rename to Bank Templates, move to Resources sidebar only
* docs: add Bank Templates to Resources navbar dropdown
* feat(api): add directives to bank template import/export
- Add BankTemplateDirective model with name, content, priority, is_active, tags
- Import creates/updates directives matched by name
- Export includes all directives (active and inactive)
- Validation: duplicate names rejected, empty name/content caught
- Tests: 24 tests covering directives create/update, existing vs new
bank import, validation, export with directives, full round-trip
* docs: add directives to bank templates docs and sample templates
* feat(api): add JSON Schema endpoint for bank template validation
- GET /v1/default/bank-template-schema returns the JSON Schema
auto-generated from the Pydantic BankTemplateManifest model
- Static schema file at docs/static/bank-template-schema.json
- Docs updated with schema endpoint, static file link, and
validation examples (Python jsonschema, Node ajv-cli)
* feat(api): live schema validation on import, fix schema endpoint path
- Move schema endpoint to /v1/bank-template-schema (system-level, not per-bank)
- Import endpoint now accepts raw JSON and validates with Pydantic manually,
returning clean 400 errors instead of raw 422s for all validation failures
- All validation (schema + semantic) returns consistent 400 with detailed messages
* docs: add interactive JSON Schema viewer to Bank Templates page
Renders the Pydantic-generated schema as a collapsible property tree
with types, required badges, defaults, and descriptions. The schema
is imported from the static bank-template-schema.json file.
* ui: add template toggle switch and browse link to bank creation dialog
- Replace always-visible textarea with a switch toggle ("Import from template")
- Textarea only shows when switch is on, keeping the dialog clean by default
- Add "Browse templates" link pointing to hindsight.vectorize.io/templates
- Reset template state when switch is toggled off or dialog is cancelled
* ui: add empty state with Add Document CTA to data view
When a bank has 0 memories, the data view (all tabs: constellation,
graph, table, timeline) shows a centered empty state with a CTA
button that opens the Add Document dialog.
* docs: replace templates with Conversation and Coding Agent
Remove generic placeholder templates. Add two practical templates
based on actual integration patterns:
- Conversation: for chat agents (LiteLLM, LangGraph, Pydantic AI,
Vercel AI SDK). Tracks user preferences, open threads.
- Coding Agent: for Claude Code/Codex. Tracks technical decisions,
project context, developer preferences. High literalism.
* docs: rename gallery to Bank Templates Hub, keep API doc as Bank Templates
* docs: register layout-template and file-json icons in navbar and sidebar
* docs: register layout-template icon in DefaultNavbarItem for dropdown items
* docs: show integration icons on template cards
Templates now have an optional `integrations` field referencing
integration IDs from integrations.json. Icons are resolved at render
time and shown in the card header next to the category badge.
* docs: add Personal Assistant template for OpenClaw, Hermes, NemoClaw
* feat: add Export Template to bank actions + map all integrations to templates
- Add "Export Template" to the bank Actions dropdown — exports config,
mental models, and directives as JSON, copies to clipboard
- Add export API route and client method
- Map remaining integrations to templates: CrewAI, AG2, Agno, Strands,
LlamaIndex, local-mcp, skills → Conversation; hindclaw → Personal Assistant
* feat: add --template flag to LoCoMo benchmark + remove schema from Hub
- LoCoMo benchmark accepts --template <path> to apply a bank template
manifest (config, mental models, directives) before ingestion
- Template is applied per-bank in both single-phase and two-phase modes
- BenchmarkRunner.apply_template() reuses the same engine methods as
the /import API endpoint
- Remove Manifest Schema section from Bank Templates Hub page
(schema stays in the API reference doc)
* refactor: remove description field from bank template manifest
* docs: remove tags, fact_types, and directives from starter templates
* docs: remove reflect_mission and disposition fields from starter templates
* build: validate template manifests against JSON Schema during docs build
* cleanup: remove unused JsonSchemaViewer component
* docs: remove retain_extraction_mode from starter templates
* ui: enable word wrap in template manifest preview
* docs: add link to Bank Templates reference doc from Hub page
* docs: convert bank templates doc to mdx with multi-language code snippets
- Convert bank-templates.md to .mdx with Tabs/CodeSnippet components
- Add example files: bank-templates.py, .mjs, .sh, .go with doc markers
- Examples cover import, dry-run, export, round-trip, and schema
- Regenerate OpenAPI spec and all client SDKs (Python, TS, Rust, Go)
* fix: migration revision collision + use typed models in benchmark template
- Rename merge migration d6e7f8a9b0c1 -> d6e7f8a9b0c2 to resolve
revision ID collision with case_insensitive_entities_trgm_index
- Update a4b5c6d7e8f9 down_revision to point to the renamed migration
- Fix f-string lint in case_insensitive migration
- BenchmarkRunner.apply_template() now validates manifest through
BankTemplateManifest Pydantic model instead of raw dict access
- Remove redundant inline imports (json, Path already at module top)
* fix(docs): add missing Go tab to dry-run code snippet
* ci: retrigger
* fix: sync skills openapi.json + fix bankId null type error in export
- Copy updated openapi.json to skills/hindsight-docs/references/
- Add null guard for bankId in Export Template onClick handler
* fix: sync generated files (memory_engine formatting, docs skill references)
* cleanup: remove obsolete migration collision workaround
This commit is contained in:
parent
9cfdd464a9
commit
30a319a6ab
53 changed files with 9698 additions and 113 deletions
|
|
@ -4,8 +4,8 @@ The previous GIN trigram index on canonical_name was case-sensitive, causing
|
||||||
"Alice" and "alice" to have different trigram sets. This recreates it on
|
"Alice" and "alice" to have different trigram sets. This recreates it on
|
||||||
LOWER(canonical_name) so the % operator matches case-insensitively.
|
LOWER(canonical_name) so the % operator matches case-insensitively.
|
||||||
|
|
||||||
Revision ID: 2eee35aa3cfc
|
Revision ID: d6e7f8a9b0c1
|
||||||
Revises: d6e7f8a9b0c1
|
Revises: c5d6e7f8a9b0
|
||||||
Create Date: 2026-03-31
|
Create Date: 2026-03-31
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -13,8 +13,8 @@ from collections.abc import Sequence
|
||||||
|
|
||||||
from alembic import context, op
|
from alembic import context, op
|
||||||
|
|
||||||
revision: str = "2eee35aa3cfc"
|
revision: str = "d6e7f8a9b0c1"
|
||||||
down_revision: str | Sequence[str] | None = "d6e7f8a9b0c1"
|
down_revision: str | Sequence[str] | None = "c5d6e7f8a9b0"
|
||||||
branch_labels: str | Sequence[str] | None = None
|
branch_labels: str | Sequence[str] | None = None
|
||||||
depends_on: str | Sequence[str] | None = None
|
depends_on: str | Sequence[str] | None = None
|
||||||
|
|
||||||
|
|
@ -27,7 +27,7 @@ def _get_schema_prefix() -> str:
|
||||||
def upgrade() -> None:
|
def upgrade() -> None:
|
||||||
schema = _get_schema_prefix()
|
schema = _get_schema_prefix()
|
||||||
# Drop the old case-sensitive trigram index
|
# Drop the old case-sensitive trigram index
|
||||||
op.execute(f"DROP INDEX IF EXISTS {schema}entities_canonical_name_trgm_idx")
|
op.execute("DROP INDEX IF EXISTS entities_canonical_name_trgm_idx")
|
||||||
# Create case-insensitive trigram index on LOWER(canonical_name)
|
# Create case-insensitive trigram index on LOWER(canonical_name)
|
||||||
op.execute(
|
op.execute(
|
||||||
f"CREATE INDEX IF NOT EXISTS entities_canonical_name_lower_trgm_idx "
|
f"CREATE INDEX IF NOT EXISTS entities_canonical_name_lower_trgm_idx "
|
||||||
|
|
@ -36,8 +36,8 @@ def upgrade() -> None:
|
||||||
|
|
||||||
|
|
||||||
def downgrade() -> None:
|
def downgrade() -> None:
|
||||||
|
op.execute("DROP INDEX IF EXISTS entities_canonical_name_lower_trgm_idx")
|
||||||
schema = _get_schema_prefix()
|
schema = _get_schema_prefix()
|
||||||
op.execute(f"DROP INDEX IF EXISTS {schema}entities_canonical_name_lower_trgm_idx")
|
|
||||||
# Restore original case-sensitive index
|
# Restore original case-sensitive index
|
||||||
op.execute(
|
op.execute(
|
||||||
f"CREATE INDEX IF NOT EXISTS entities_canonical_name_trgm_idx "
|
f"CREATE INDEX IF NOT EXISTS entities_canonical_name_trgm_idx "
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"""Fix per-bank vector indexes to match configured extension
|
"""Fix per-bank vector indexes to match configured extension
|
||||||
|
|
||||||
Revision ID: a4b5c6d7e8f9
|
Revision ID: a4b5c6d7e8f9
|
||||||
Revises: 2eee35aa3cfc
|
Revises: c2d3e4f5g6h7, c5d6e7f8a9b0
|
||||||
Create Date: 2026-04-01
|
Create Date: 2026-04-01
|
||||||
|
|
||||||
Migration d5e6f7a8b9c0 hardcoded HNSW when creating per-bank partial vector
|
Migration d5e6f7a8b9c0 hardcoded HNSW when creating per-bank partial vector
|
||||||
|
|
@ -21,7 +21,10 @@ from alembic import context, op
|
||||||
from sqlalchemy import text
|
from sqlalchemy import text
|
||||||
|
|
||||||
revision: str = "a4b5c6d7e8f9"
|
revision: str = "a4b5c6d7e8f9"
|
||||||
down_revision: str | Sequence[str] | None = "2eee35aa3cfc"
|
# Updated: the merge migration d6e7f8a9b0c1 was renamed to d6e7f8a9b0c2
|
||||||
|
# to avoid colliding with the case_insensitive_entities_trgm_index migration
|
||||||
|
# that shares the same revision ID.
|
||||||
|
down_revision: str | Sequence[str] | None = "d6e7f8a9b0c2"
|
||||||
branch_labels: str | Sequence[str] | None = None
|
branch_labels: str | Sequence[str] | None = None
|
||||||
depends_on: str | Sequence[str] | None = None
|
depends_on: str | Sequence[str] | None = None
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
"""Drop unused metadata column from documents table
|
|
||||||
|
|
||||||
Revision ID: d6e7f8a9b0c1
|
|
||||||
Revises: c2d3e4f5g6h7, c5d6e7f8a9b0
|
|
||||||
Create Date: 2026-03-30
|
|
||||||
|
|
||||||
The metadata column on documents was always stored as an empty dict {}.
|
|
||||||
Actual document metadata is stored inside retain_params.metadata.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from collections.abc import Sequence
|
|
||||||
|
|
||||||
from alembic import context, op
|
|
||||||
|
|
||||||
revision: str = "d6e7f8a9b0c1"
|
|
||||||
down_revision: str | Sequence[str] | None = ("c2d3e4f5g6h7", "c5d6e7f8a9b0")
|
|
||||||
branch_labels: str | Sequence[str] | None = None
|
|
||||||
depends_on: str | Sequence[str] | None = None
|
|
||||||
|
|
||||||
|
|
||||||
def _get_schema_prefix() -> str:
|
|
||||||
"""Get schema prefix for table names (required for multi-tenant support)."""
|
|
||||||
schema = context.config.get_main_option("target_schema")
|
|
||||||
return f'"{schema}".' if schema else ""
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade() -> None:
|
|
||||||
schema = _get_schema_prefix()
|
|
||||||
op.execute(f"ALTER TABLE {schema}documents DROP COLUMN IF EXISTS metadata")
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade() -> None:
|
|
||||||
schema = _get_schema_prefix()
|
|
||||||
op.execute(f"ALTER TABLE {schema}documents ADD COLUMN IF NOT EXISTS metadata jsonb DEFAULT '{{}}'")
|
|
||||||
|
|
@ -8,12 +8,13 @@ the FastAPI application with all API endpoints.
|
||||||
import asyncio
|
import asyncio
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
import uuid
|
import uuid
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
from typing import Any, Literal
|
from typing import Any, Literal
|
||||||
|
|
||||||
from fastapi import Depends, FastAPI, File, Form, Header, HTTPException, Query, UploadFile
|
from fastapi import Depends, FastAPI, File, Form, Header, HTTPException, Query, Request, UploadFile
|
||||||
|
|
||||||
from hindsight_api.engine.audit import AuditEntry, AuditLogger
|
from hindsight_api.engine.audit import AuditEntry, AuditLogger
|
||||||
from hindsight_api.extensions import AuthenticationError
|
from hindsight_api.extensions import AuthenticationError
|
||||||
|
|
@ -1611,6 +1612,186 @@ class UpdateMentalModelRequest(BaseModel):
|
||||||
trigger: MentalModelTrigger | None = Field(default=None, description="Trigger settings")
|
trigger: MentalModelTrigger | None = Field(default=None, description="Trigger settings")
|
||||||
|
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# Bank Templates (import/export)
|
||||||
|
# =========================================================================
|
||||||
|
|
||||||
|
# Current manifest schema version. Bump when making breaking changes.
|
||||||
|
BANK_TEMPLATE_CURRENT_VERSION = "1"
|
||||||
|
|
||||||
|
|
||||||
|
class BankTemplateMentalModel(BaseModel):
|
||||||
|
"""A mental model definition within a bank template manifest."""
|
||||||
|
|
||||||
|
id: str = Field(description="Unique ID for the mental model (alphanumeric lowercase with hyphens)")
|
||||||
|
name: str = Field(description="Human-readable name for the mental model")
|
||||||
|
source_query: str = Field(description="The query to run to generate content")
|
||||||
|
tags: list[str] = FieldWithDefault(list, description="Tags for scoped visibility")
|
||||||
|
max_tokens: int = Field(default=2048, ge=256, le=8192, description="Maximum tokens for generated content")
|
||||||
|
trigger: MentalModelTrigger = FieldWithDefault(MentalModelTrigger, description="Trigger settings")
|
||||||
|
|
||||||
|
@field_validator("id")
|
||||||
|
@classmethod
|
||||||
|
def validate_id(cls, v: str) -> str:
|
||||||
|
if not re.match(r"^[a-z0-9][a-z0-9-]*$", v):
|
||||||
|
raise ValueError(
|
||||||
|
f"Mental model id '{v}' must be alphanumeric lowercase with hyphens, starting with a letter or digit."
|
||||||
|
)
|
||||||
|
return v
|
||||||
|
|
||||||
|
|
||||||
|
class BankTemplateConfig(BaseModel):
|
||||||
|
"""Bank configuration fields within a template manifest.
|
||||||
|
|
||||||
|
Only includes configurable (per-bank) fields. Credential fields
|
||||||
|
(API keys, base URLs) are intentionally excluded for security.
|
||||||
|
"""
|
||||||
|
|
||||||
|
reflect_mission: str | None = Field(default=None, description="Mission/context for Reflect operations")
|
||||||
|
retain_mission: str | None = Field(default=None, description="Steers what gets extracted during retain")
|
||||||
|
retain_extraction_mode: str | None = Field(
|
||||||
|
default=None, description="Fact extraction mode: 'concise' (default), 'verbose', or 'custom'"
|
||||||
|
)
|
||||||
|
retain_custom_instructions: str | None = Field(
|
||||||
|
default=None, description="Custom extraction prompt (when mode='custom')"
|
||||||
|
)
|
||||||
|
retain_chunk_size: int | None = Field(default=None, description="Max token size for each content chunk")
|
||||||
|
enable_observations: bool | None = Field(default=None, description="Toggle observation consolidation")
|
||||||
|
observations_mission: str | None = Field(default=None, description="Controls what gets synthesised")
|
||||||
|
disposition_skepticism: int | None = Field(default=None, ge=1, le=5, description="Skepticism trait (1-5)")
|
||||||
|
disposition_literalism: int | None = Field(default=None, ge=1, le=5, description="Literalism trait (1-5)")
|
||||||
|
disposition_empathy: int | None = Field(default=None, ge=1, le=5, description="Empathy trait (1-5)")
|
||||||
|
entity_labels: list[str] | None = Field(default=None, description="Controlled vocabulary for entity labels")
|
||||||
|
entities_allow_free_form: bool | None = Field(
|
||||||
|
default=None, description="Allow entities outside the label vocabulary"
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_config_updates(self) -> dict[str, Any]:
|
||||||
|
"""Return only the fields that were explicitly set (non-None)."""
|
||||||
|
return {k: v for k, v in self.model_dump().items() if v is not None}
|
||||||
|
|
||||||
|
|
||||||
|
class BankTemplateDirective(BaseModel):
|
||||||
|
"""A directive definition within a bank template manifest.
|
||||||
|
|
||||||
|
Directives are matched by name on re-import: existing directives
|
||||||
|
with the same name are updated, new ones are created.
|
||||||
|
"""
|
||||||
|
|
||||||
|
name: str = Field(description="Human-readable name for the directive (used as match key on re-import)")
|
||||||
|
content: str = Field(description="The directive text to inject into prompts")
|
||||||
|
priority: int = Field(default=0, description="Higher priority directives are injected first")
|
||||||
|
is_active: bool = Field(default=True, description="Whether this directive is active")
|
||||||
|
tags: list[str] = FieldWithDefault(list, description="Tags for filtering")
|
||||||
|
|
||||||
|
|
||||||
|
class BankTemplateManifest(BaseModel):
|
||||||
|
"""A bank template manifest for import/export.
|
||||||
|
|
||||||
|
Version field enables forward-compatible schema evolution: the API
|
||||||
|
auto-upgrades older manifest versions to the current schema on import.
|
||||||
|
"""
|
||||||
|
|
||||||
|
model_config = ConfigDict(
|
||||||
|
json_schema_extra={
|
||||||
|
"example": {
|
||||||
|
"version": "1",
|
||||||
|
"bank": {
|
||||||
|
"reflect_mission": "You are helping a support agent remember customer interactions.",
|
||||||
|
"retain_mission": "Extract customer issues, resolutions, and sentiment.",
|
||||||
|
"disposition_empathy": 5,
|
||||||
|
"enable_observations": True,
|
||||||
|
},
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "sentiment-overview",
|
||||||
|
"name": "Customer Sentiment Overview",
|
||||||
|
"source_query": "What is the overall sentiment trend?",
|
||||||
|
"trigger": {"refresh_after_consolidation": True},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"directives": [
|
||||||
|
{
|
||||||
|
"name": "Always be empathetic",
|
||||||
|
"content": "Always respond with empathy and understanding.",
|
||||||
|
"priority": 10,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
version: str = Field(description="Manifest schema version (currently '1')")
|
||||||
|
bank: BankTemplateConfig | None = Field(
|
||||||
|
default=None, description="Bank configuration to apply. Omit to leave config unchanged."
|
||||||
|
)
|
||||||
|
mental_models: list[BankTemplateMentalModel] | None = Field(
|
||||||
|
default=None, description="Mental models to create or update (matched by id). Omit to leave unchanged."
|
||||||
|
)
|
||||||
|
directives: list[BankTemplateDirective] | None = Field(
|
||||||
|
default=None, description="Directives to create or update (matched by name). Omit to leave unchanged."
|
||||||
|
)
|
||||||
|
|
||||||
|
@field_validator("version")
|
||||||
|
@classmethod
|
||||||
|
def validate_version(cls, v: str) -> str:
|
||||||
|
try:
|
||||||
|
ver = int(v)
|
||||||
|
except ValueError:
|
||||||
|
raise ValueError(f"version must be a numeric string, got '{v}'")
|
||||||
|
if ver < 1:
|
||||||
|
raise ValueError("version must be >= 1")
|
||||||
|
if ver > int(BANK_TEMPLATE_CURRENT_VERSION):
|
||||||
|
raise ValueError(
|
||||||
|
f"version '{v}' is not supported by this server "
|
||||||
|
f"(max supported: {BANK_TEMPLATE_CURRENT_VERSION}). Please upgrade Hindsight."
|
||||||
|
)
|
||||||
|
return v
|
||||||
|
|
||||||
|
@field_validator("mental_models")
|
||||||
|
@classmethod
|
||||||
|
def validate_unique_mental_model_ids(
|
||||||
|
cls,
|
||||||
|
v: list[BankTemplateMentalModel] | None,
|
||||||
|
) -> list[BankTemplateMentalModel] | None:
|
||||||
|
if v is None:
|
||||||
|
return v
|
||||||
|
ids = [m.id for m in v]
|
||||||
|
duplicates = [mid for mid in ids if ids.count(mid) > 1]
|
||||||
|
if duplicates:
|
||||||
|
raise ValueError(f"Duplicate mental model ids: {sorted(set(duplicates))}")
|
||||||
|
return v
|
||||||
|
|
||||||
|
@field_validator("directives")
|
||||||
|
@classmethod
|
||||||
|
def validate_unique_directive_names(
|
||||||
|
cls,
|
||||||
|
v: list[BankTemplateDirective] | None,
|
||||||
|
) -> list[BankTemplateDirective] | None:
|
||||||
|
if v is None:
|
||||||
|
return v
|
||||||
|
names = [d.name for d in v]
|
||||||
|
duplicates = [n for n in names if names.count(n) > 1]
|
||||||
|
if duplicates:
|
||||||
|
raise ValueError(f"Duplicate directive names: {sorted(set(duplicates))}")
|
||||||
|
return v
|
||||||
|
|
||||||
|
|
||||||
|
class BankTemplateImportResponse(BaseModel):
|
||||||
|
"""Response model for the bank template import endpoint."""
|
||||||
|
|
||||||
|
bank_id: str = Field(description="Bank that was imported into")
|
||||||
|
config_applied: bool = Field(description="Whether bank config was updated")
|
||||||
|
mental_models_created: list[str] = FieldWithDefault(list, description="IDs of newly created mental models")
|
||||||
|
mental_models_updated: list[str] = FieldWithDefault(list, description="IDs of updated mental models")
|
||||||
|
directives_created: list[str] = FieldWithDefault(list, description="Names of newly created directives")
|
||||||
|
directives_updated: list[str] = FieldWithDefault(list, description="Names of updated directives")
|
||||||
|
operation_ids: list[str] = FieldWithDefault(
|
||||||
|
list, description="Operation IDs for mental model content generation (async)"
|
||||||
|
)
|
||||||
|
dry_run: bool = Field(default=False, description="True if this was a validation-only run")
|
||||||
|
|
||||||
|
|
||||||
class OperationResponse(BaseModel):
|
class OperationResponse(BaseModel):
|
||||||
"""Response model for a single async operation."""
|
"""Response model for a single async operation."""
|
||||||
|
|
||||||
|
|
@ -4176,6 +4357,304 @@ def _register_routes(app: FastAPI):
|
||||||
logger.error(f"Error in DELETE /v1/default/banks/{bank_id}: {error_detail}")
|
logger.error(f"Error in DELETE /v1/default/banks/{bank_id}: {error_detail}")
|
||||||
raise HTTPException(status_code=500, detail=str(e))
|
raise HTTPException(status_code=500, detail=str(e))
|
||||||
|
|
||||||
|
# =====================================================================
|
||||||
|
# Bank Template Import / Export
|
||||||
|
# =====================================================================
|
||||||
|
|
||||||
|
def _validate_template(manifest: BankTemplateManifest) -> list[str]:
|
||||||
|
"""Validate a parsed manifest beyond Pydantic's structural checks.
|
||||||
|
|
||||||
|
Returns a list of human-readable error strings (e.g. invalid
|
||||||
|
extraction mode values, conflicting settings).
|
||||||
|
"""
|
||||||
|
errors: list[str] = []
|
||||||
|
if manifest.bank:
|
||||||
|
bank = manifest.bank
|
||||||
|
if bank.retain_extraction_mode is not None:
|
||||||
|
valid_modes = ("concise", "verbose", "custom", "chunks")
|
||||||
|
if bank.retain_extraction_mode not in valid_modes:
|
||||||
|
errors.append(
|
||||||
|
f"bank.retain_extraction_mode: must be one of {valid_modes}, "
|
||||||
|
f"got '{bank.retain_extraction_mode}'"
|
||||||
|
)
|
||||||
|
if bank.retain_custom_instructions and bank.retain_extraction_mode != "custom":
|
||||||
|
errors.append("bank.retain_custom_instructions: requires retain_extraction_mode='custom'")
|
||||||
|
if manifest.mental_models:
|
||||||
|
for i, mm in enumerate(manifest.mental_models):
|
||||||
|
if not mm.name.strip():
|
||||||
|
errors.append(f"mental_models[{i}].name: must not be empty")
|
||||||
|
if not mm.source_query.strip():
|
||||||
|
errors.append(f"mental_models[{i}].source_query: must not be empty")
|
||||||
|
if manifest.directives:
|
||||||
|
for i, d in enumerate(manifest.directives):
|
||||||
|
if not d.name.strip():
|
||||||
|
errors.append(f"directives[{i}].name: must not be empty")
|
||||||
|
if not d.content.strip():
|
||||||
|
errors.append(f"directives[{i}].content: must not be empty")
|
||||||
|
return errors
|
||||||
|
|
||||||
|
@app.post(
|
||||||
|
"/v1/default/banks/{bank_id}/import",
|
||||||
|
response_model=BankTemplateImportResponse,
|
||||||
|
summary="Import bank template",
|
||||||
|
description="Import a bank template manifest to create or update a bank's configuration, mental models, "
|
||||||
|
"and directives. If the bank does not exist it is created. Config fields are applied as per-bank overrides. "
|
||||||
|
"Mental models are matched by id, directives by name — existing ones are updated, new ones are created. "
|
||||||
|
"Use dry_run=true to validate the manifest without applying changes.",
|
||||||
|
operation_id="import_bank_template",
|
||||||
|
tags=["Bank Templates"],
|
||||||
|
)
|
||||||
|
@audited("import_bank_template", request_param=None)
|
||||||
|
async def api_import_bank_template(
|
||||||
|
bank_id: str,
|
||||||
|
request: Request,
|
||||||
|
dry_run: bool = Query(default=False, description="Validate only, do not apply changes"),
|
||||||
|
request_context: RequestContext = Depends(get_request_context),
|
||||||
|
):
|
||||||
|
"""Import a bank template manifest."""
|
||||||
|
try:
|
||||||
|
# Parse raw JSON and validate against the Pydantic model manually
|
||||||
|
# so we can return clean error messages instead of raw 422s.
|
||||||
|
raw_body = await request.json()
|
||||||
|
from pydantic import ValidationError
|
||||||
|
|
||||||
|
try:
|
||||||
|
body = BankTemplateManifest.model_validate(raw_body)
|
||||||
|
except ValidationError as e:
|
||||||
|
errors = [f"{'.'.join(str(loc) for loc in err['loc'])}: {err['msg']}" for err in e.errors()]
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400,
|
||||||
|
detail=f"Template schema validation failed: {'; '.join(errors)}",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Semantic validation beyond Pydantic structural checks
|
||||||
|
validation_errors = _validate_template(body)
|
||||||
|
if validation_errors:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=400,
|
||||||
|
detail=f"Template validation failed: {'; '.join(validation_errors)}",
|
||||||
|
)
|
||||||
|
if dry_run:
|
||||||
|
return BankTemplateImportResponse(
|
||||||
|
bank_id=bank_id,
|
||||||
|
config_applied=body.bank is not None,
|
||||||
|
mental_models_created=[m.id for m in (body.mental_models or [])],
|
||||||
|
directives_created=[d.name for d in (body.directives or [])],
|
||||||
|
dry_run=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Ensure bank exists (auto-creates with defaults if needed)
|
||||||
|
await app.state.memory.get_bank_profile(bank_id, request_context=request_context)
|
||||||
|
|
||||||
|
config_applied = False
|
||||||
|
if body.bank:
|
||||||
|
config_updates = body.bank.get_config_updates()
|
||||||
|
if config_updates:
|
||||||
|
await app.state.memory._config_resolver.update_bank_config(bank_id, config_updates, request_context)
|
||||||
|
config_applied = True
|
||||||
|
|
||||||
|
created_ids: list[str] = []
|
||||||
|
updated_ids: list[str] = []
|
||||||
|
operation_ids: list[str] = []
|
||||||
|
|
||||||
|
if body.mental_models:
|
||||||
|
# Fetch existing mental models to decide create vs update
|
||||||
|
existing = await app.state.memory.list_mental_models(bank_id=bank_id, request_context=request_context)
|
||||||
|
existing_by_id = {m["id"]: m for m in existing}
|
||||||
|
|
||||||
|
for mm in body.mental_models:
|
||||||
|
if mm.id in existing_by_id:
|
||||||
|
# Update existing mental model metadata
|
||||||
|
await app.state.memory.update_mental_model(
|
||||||
|
bank_id=bank_id,
|
||||||
|
mental_model_id=mm.id,
|
||||||
|
name=mm.name,
|
||||||
|
source_query=mm.source_query,
|
||||||
|
max_tokens=mm.max_tokens,
|
||||||
|
tags=mm.tags if mm.tags else None,
|
||||||
|
trigger=mm.trigger.model_dump() if mm.trigger else None,
|
||||||
|
request_context=request_context,
|
||||||
|
)
|
||||||
|
# Schedule a refresh to regenerate content with updated query
|
||||||
|
result = await app.state.memory.submit_async_refresh_mental_model(
|
||||||
|
bank_id=bank_id,
|
||||||
|
mental_model_id=mm.id,
|
||||||
|
request_context=request_context,
|
||||||
|
)
|
||||||
|
operation_ids.append(result["operation_id"])
|
||||||
|
updated_ids.append(mm.id)
|
||||||
|
else:
|
||||||
|
# Create new mental model
|
||||||
|
mental_model = await app.state.memory.create_mental_model(
|
||||||
|
bank_id=bank_id,
|
||||||
|
name=mm.name,
|
||||||
|
source_query=mm.source_query,
|
||||||
|
content="Generating content...",
|
||||||
|
mental_model_id=mm.id,
|
||||||
|
tags=mm.tags if mm.tags else None,
|
||||||
|
max_tokens=mm.max_tokens,
|
||||||
|
trigger=mm.trigger.model_dump() if mm.trigger else None,
|
||||||
|
request_context=request_context,
|
||||||
|
)
|
||||||
|
result = await app.state.memory.submit_async_refresh_mental_model(
|
||||||
|
bank_id=bank_id,
|
||||||
|
mental_model_id=mental_model["id"],
|
||||||
|
request_context=request_context,
|
||||||
|
)
|
||||||
|
operation_ids.append(result["operation_id"])
|
||||||
|
created_ids.append(mm.id)
|
||||||
|
|
||||||
|
directives_created: list[str] = []
|
||||||
|
directives_updated: list[str] = []
|
||||||
|
|
||||||
|
if body.directives:
|
||||||
|
# Fetch existing directives to decide create vs update (matched by name)
|
||||||
|
existing_directives = await app.state.memory.list_directives(
|
||||||
|
bank_id=bank_id, active_only=False, request_context=request_context
|
||||||
|
)
|
||||||
|
existing_by_name = {d["name"]: d for d in existing_directives}
|
||||||
|
|
||||||
|
for directive in body.directives:
|
||||||
|
if directive.name in existing_by_name:
|
||||||
|
await app.state.memory.update_directive(
|
||||||
|
bank_id=bank_id,
|
||||||
|
directive_id=existing_by_name[directive.name]["id"],
|
||||||
|
content=directive.content,
|
||||||
|
priority=directive.priority,
|
||||||
|
is_active=directive.is_active,
|
||||||
|
tags=directive.tags if directive.tags else None,
|
||||||
|
request_context=request_context,
|
||||||
|
)
|
||||||
|
directives_updated.append(directive.name)
|
||||||
|
else:
|
||||||
|
await app.state.memory.create_directive(
|
||||||
|
bank_id=bank_id,
|
||||||
|
name=directive.name,
|
||||||
|
content=directive.content,
|
||||||
|
priority=directive.priority,
|
||||||
|
is_active=directive.is_active,
|
||||||
|
tags=directive.tags if directive.tags else None,
|
||||||
|
request_context=request_context,
|
||||||
|
)
|
||||||
|
directives_created.append(directive.name)
|
||||||
|
|
||||||
|
return BankTemplateImportResponse(
|
||||||
|
bank_id=bank_id,
|
||||||
|
config_applied=config_applied,
|
||||||
|
mental_models_created=created_ids,
|
||||||
|
mental_models_updated=updated_ids,
|
||||||
|
directives_created=directives_created,
|
||||||
|
directives_updated=directives_updated,
|
||||||
|
operation_ids=operation_ids,
|
||||||
|
dry_run=False,
|
||||||
|
)
|
||||||
|
except ValueError as e:
|
||||||
|
raise HTTPException(status_code=400, detail=str(e))
|
||||||
|
except OperationValidationError as e:
|
||||||
|
raise HTTPException(status_code=e.status_code, detail=e.reason)
|
||||||
|
except (AuthenticationError, HTTPException):
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
error_detail = f"{str(e)}\n\nTraceback:\n{traceback.format_exc()}"
|
||||||
|
logger.error(f"Error in POST /v1/default/banks/{bank_id}/import: {error_detail}")
|
||||||
|
raise HTTPException(status_code=500, detail=str(e))
|
||||||
|
|
||||||
|
@app.get(
|
||||||
|
"/v1/default/banks/{bank_id}/export",
|
||||||
|
response_model=BankTemplateManifest,
|
||||||
|
summary="Export bank template",
|
||||||
|
description="Export a bank's current configuration, mental models, and directives as a template manifest. "
|
||||||
|
"The exported manifest can be imported into another bank to replicate the setup.",
|
||||||
|
operation_id="export_bank_template",
|
||||||
|
tags=["Bank Templates"],
|
||||||
|
)
|
||||||
|
async def api_export_bank_template(
|
||||||
|
bank_id: str,
|
||||||
|
request_context: RequestContext = Depends(get_request_context),
|
||||||
|
):
|
||||||
|
"""Export a bank's config and mental models as a template manifest."""
|
||||||
|
try:
|
||||||
|
# Authenticate and ensure bank exists
|
||||||
|
profile = await app.state.memory.get_bank_profile(bank_id, request_context=request_context)
|
||||||
|
if profile is None:
|
||||||
|
raise HTTPException(status_code=404, detail=f"Bank '{bank_id}' not found")
|
||||||
|
|
||||||
|
# Get bank-specific config overrides (not the fully resolved config,
|
||||||
|
# so the template only contains what was explicitly set on this bank)
|
||||||
|
await app.state.memory._authenticate_tenant(request_context)
|
||||||
|
bank_overrides = await app.state.memory._config_resolver._load_bank_config(bank_id)
|
||||||
|
|
||||||
|
# Filter to only BankTemplateConfig fields (exclude credentials, static fields)
|
||||||
|
template_config_fields = set(BankTemplateConfig.model_fields.keys())
|
||||||
|
filtered_overrides = {k: v for k, v in bank_overrides.items() if k in template_config_fields}
|
||||||
|
bank_config = BankTemplateConfig(**filtered_overrides) if filtered_overrides else None
|
||||||
|
|
||||||
|
# Get mental models
|
||||||
|
mental_models_raw = await app.state.memory.list_mental_models(
|
||||||
|
bank_id=bank_id, request_context=request_context
|
||||||
|
)
|
||||||
|
template_mental_models: list[BankTemplateMentalModel] = []
|
||||||
|
for mm in mental_models_raw:
|
||||||
|
trigger_data = mm.get("trigger", {})
|
||||||
|
trigger = MentalModelTrigger(**trigger_data) if trigger_data else MentalModelTrigger()
|
||||||
|
template_mental_models.append(
|
||||||
|
BankTemplateMentalModel(
|
||||||
|
id=mm["id"],
|
||||||
|
name=mm["name"],
|
||||||
|
source_query=mm["source_query"],
|
||||||
|
tags=mm.get("tags", []),
|
||||||
|
max_tokens=mm.get("max_tokens", 2048),
|
||||||
|
trigger=trigger,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Get directives
|
||||||
|
directives_raw = await app.state.memory.list_directives(
|
||||||
|
bank_id=bank_id, active_only=False, request_context=request_context
|
||||||
|
)
|
||||||
|
template_directives: list[BankTemplateDirective] = []
|
||||||
|
for d in directives_raw:
|
||||||
|
template_directives.append(
|
||||||
|
BankTemplateDirective(
|
||||||
|
name=d["name"],
|
||||||
|
content=d["content"],
|
||||||
|
priority=d.get("priority", 0),
|
||||||
|
is_active=d.get("is_active", True),
|
||||||
|
tags=d.get("tags", []),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return BankTemplateManifest(
|
||||||
|
version=BANK_TEMPLATE_CURRENT_VERSION,
|
||||||
|
bank=bank_config,
|
||||||
|
mental_models=template_mental_models if template_mental_models else None,
|
||||||
|
directives=template_directives if template_directives else None,
|
||||||
|
)
|
||||||
|
except OperationValidationError as e:
|
||||||
|
raise HTTPException(status_code=e.status_code, detail=e.reason)
|
||||||
|
except (AuthenticationError, HTTPException):
|
||||||
|
raise
|
||||||
|
except Exception as e:
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
error_detail = f"{str(e)}\n\nTraceback:\n{traceback.format_exc()}"
|
||||||
|
logger.error(f"Error in GET /v1/default/banks/{bank_id}/export: {error_detail}")
|
||||||
|
raise HTTPException(status_code=500, detail=str(e))
|
||||||
|
|
||||||
|
@app.get(
|
||||||
|
"/v1/bank-template-schema",
|
||||||
|
summary="Get bank template JSON Schema",
|
||||||
|
description="Returns the JSON Schema for the bank template manifest format. "
|
||||||
|
"Use this to validate template manifests before importing.",
|
||||||
|
operation_id="get_bank_template_schema",
|
||||||
|
tags=["Bank Templates"],
|
||||||
|
)
|
||||||
|
async def api_get_bank_template_schema():
|
||||||
|
"""Return the JSON Schema for the bank template manifest."""
|
||||||
|
return BankTemplateManifest.model_json_schema()
|
||||||
|
|
||||||
@app.delete(
|
@app.delete(
|
||||||
"/v1/default/banks/{bank_id}/observations",
|
"/v1/default/banks/{bank_id}/observations",
|
||||||
response_model=DeleteResponse,
|
response_model=DeleteResponse,
|
||||||
|
|
|
||||||
|
|
@ -3830,7 +3830,6 @@ class MemoryEngine(MemoryEngineInterface):
|
||||||
bank_id: str,
|
bank_id: str,
|
||||||
fact_type: str | None = None,
|
fact_type: str | None = None,
|
||||||
*,
|
*,
|
||||||
delete_bank_profile: bool = True,
|
|
||||||
request_context: "RequestContext",
|
request_context: "RequestContext",
|
||||||
) -> dict[str, int]:
|
) -> dict[str, int]:
|
||||||
"""
|
"""
|
||||||
|
|
@ -3917,21 +3916,20 @@ class MemoryEngine(MemoryEngineInterface):
|
||||||
# Delete entities (cascades to unit_entities, entity_cooccurrences, memory_links with entity_id)
|
# Delete entities (cascades to unit_entities, entity_cooccurrences, memory_links with entity_id)
|
||||||
await conn.execute(f"DELETE FROM {fq_table('entities')} WHERE bank_id = $1", bank_id)
|
await conn.execute(f"DELETE FROM {fq_table('entities')} WHERE bank_id = $1", bank_id)
|
||||||
|
|
||||||
|
# Delete the bank profile and retrieve internal_id for HNSW index cleanup
|
||||||
|
internal_id = await conn.fetchval(
|
||||||
|
f"DELETE FROM {fq_table('banks')} WHERE bank_id = $1 RETURNING internal_id", bank_id
|
||||||
|
)
|
||||||
|
if internal_id:
|
||||||
|
bank_internal_id = str(internal_id)
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
"memory_units_deleted": units_count,
|
"memory_units_deleted": units_count,
|
||||||
"entities_deleted": entities_count,
|
"entities_deleted": entities_count,
|
||||||
"documents_deleted": documents_count,
|
"documents_deleted": documents_count,
|
||||||
|
"bank_deleted": True,
|
||||||
}
|
}
|
||||||
|
|
||||||
if delete_bank_profile:
|
|
||||||
# Delete the bank profile and retrieve internal_id for HNSW index cleanup
|
|
||||||
internal_id = await conn.fetchval(
|
|
||||||
f"DELETE FROM {fq_table('banks')} WHERE bank_id = $1 RETURNING internal_id", bank_id
|
|
||||||
)
|
|
||||||
if internal_id:
|
|
||||||
bank_internal_id = str(internal_id)
|
|
||||||
result["bank_deleted"] = True
|
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise Exception(f"Failed to delete agent data: {str(e)}")
|
raise Exception(f"Failed to delete agent data: {str(e)}")
|
||||||
|
|
||||||
|
|
@ -4332,9 +4330,8 @@ class MemoryEngine(MemoryEngineInterface):
|
||||||
link for link in links if link["from_unit_id"] in unit_id_set and link["to_unit_id"] in unit_id_set
|
link for link in links if link["from_unit_id"] in unit_id_set and link["to_unit_id"] in unit_id_set
|
||||||
]
|
]
|
||||||
|
|
||||||
# Get entity information — for visible units AND their source memories
|
# Get entity information — only for visible units
|
||||||
# (observations inherit entities from source memories)
|
if unit_ids:
|
||||||
if all_relevant_ids:
|
|
||||||
unit_entities = await conn.fetch(
|
unit_entities = await conn.fetch(
|
||||||
f"""
|
f"""
|
||||||
SELECT ue.unit_id, e.canonical_name
|
SELECT ue.unit_id, e.canonical_name
|
||||||
|
|
@ -4343,7 +4340,7 @@ class MemoryEngine(MemoryEngineInterface):
|
||||||
WHERE ue.unit_id = ANY($1::uuid[])
|
WHERE ue.unit_id = ANY($1::uuid[])
|
||||||
ORDER BY ue.unit_id
|
ORDER BY ue.unit_id
|
||||||
""",
|
""",
|
||||||
all_relevant_ids,
|
unit_ids,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
unit_entities = []
|
unit_entities = []
|
||||||
|
|
@ -6343,7 +6340,6 @@ class MemoryEngine(MemoryEngineInterface):
|
||||||
*,
|
*,
|
||||||
tags: list[str] | None = None,
|
tags: list[str] | None = None,
|
||||||
tags_match: str = "any",
|
tags_match: str = "any",
|
||||||
detail: str = "full",
|
|
||||||
limit: int = 100,
|
limit: int = 100,
|
||||||
offset: int = 0,
|
offset: int = 0,
|
||||||
request_context: "RequestContext",
|
request_context: "RequestContext",
|
||||||
|
|
@ -6354,7 +6350,6 @@ class MemoryEngine(MemoryEngineInterface):
|
||||||
bank_id: Bank identifier
|
bank_id: Bank identifier
|
||||||
tags: Optional tags to filter by
|
tags: Optional tags to filter by
|
||||||
tags_match: How to match tags - 'any', 'all', or 'exact'
|
tags_match: How to match tags - 'any', 'all', or 'exact'
|
||||||
detail: Detail level - 'metadata', 'content', or 'full'
|
|
||||||
limit: Maximum number of results
|
limit: Maximum number of results
|
||||||
offset: Offset for pagination
|
offset: Offset for pagination
|
||||||
request_context: Request context for authentication
|
request_context: Request context for authentication
|
||||||
|
|
@ -6396,14 +6391,13 @@ class MemoryEngine(MemoryEngineInterface):
|
||||||
*params,
|
*params,
|
||||||
)
|
)
|
||||||
|
|
||||||
return [self._row_to_mental_model(row, detail=detail) for row in rows]
|
return [self._row_to_mental_model(row) for row in rows]
|
||||||
|
|
||||||
async def get_mental_model(
|
async def get_mental_model(
|
||||||
self,
|
self,
|
||||||
bank_id: str,
|
bank_id: str,
|
||||||
mental_model_id: str,
|
mental_model_id: str,
|
||||||
*,
|
*,
|
||||||
detail: str = "full",
|
|
||||||
request_context: "RequestContext",
|
request_context: "RequestContext",
|
||||||
) -> dict[str, Any] | None:
|
) -> dict[str, Any] | None:
|
||||||
"""Get a single pinned mental model by ID.
|
"""Get a single pinned mental model by ID.
|
||||||
|
|
@ -6411,7 +6405,6 @@ class MemoryEngine(MemoryEngineInterface):
|
||||||
Args:
|
Args:
|
||||||
bank_id: Bank identifier
|
bank_id: Bank identifier
|
||||||
mental_model_id: Pinned mental model UUID
|
mental_model_id: Pinned mental model UUID
|
||||||
detail: Detail level - 'metadata', 'content', or 'full'
|
|
||||||
request_context: Request context for authentication
|
request_context: Request context for authentication
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
|
|
@ -6445,7 +6438,7 @@ class MemoryEngine(MemoryEngineInterface):
|
||||||
mental_model_id,
|
mental_model_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
result = self._row_to_mental_model(row, detail=detail) if row else None
|
result = self._row_to_mental_model(row) if row else None
|
||||||
|
|
||||||
# Post-operation hook (usage recording)
|
# Post-operation hook (usage recording)
|
||||||
if result and self._operation_validator:
|
if result and self._operation_validator:
|
||||||
|
|
@ -6843,47 +6836,34 @@ class MemoryEngine(MemoryEngineInterface):
|
||||||
|
|
||||||
return result == "DELETE 1"
|
return result == "DELETE 1"
|
||||||
|
|
||||||
_MENTAL_MODEL_METADATA_FIELDS = frozenset({"id", "bank_id", "name", "tags", "last_refreshed_at", "created_at"})
|
def _row_to_mental_model(self, row) -> dict[str, Any]:
|
||||||
|
"""Convert a database row to a mental model dict."""
|
||||||
def _row_to_mental_model(self, row, *, detail: str = "full") -> dict[str, Any]:
|
reflect_response = row.get("reflect_response")
|
||||||
"""Convert a database row to a mental model dict.
|
# Parse JSON string to dict if needed (asyncpg may return JSONB as string)
|
||||||
|
if isinstance(reflect_response, str):
|
||||||
Args:
|
try:
|
||||||
row: Database row
|
reflect_response = json.loads(reflect_response)
|
||||||
detail: Detail level - 'metadata', 'content', or 'full'
|
except json.JSONDecodeError:
|
||||||
"""
|
reflect_response = None
|
||||||
result: dict[str, Any] = {
|
|
||||||
"id": str(row["id"]),
|
|
||||||
"bank_id": row["bank_id"],
|
|
||||||
"name": row["name"],
|
|
||||||
"tags": row["tags"] or [],
|
|
||||||
"last_refreshed_at": row["last_refreshed_at"].isoformat() if row["last_refreshed_at"] else None,
|
|
||||||
"created_at": row["created_at"].isoformat() if row["created_at"] else None,
|
|
||||||
}
|
|
||||||
if detail == "metadata":
|
|
||||||
return result
|
|
||||||
|
|
||||||
trigger = row.get("trigger")
|
trigger = row.get("trigger")
|
||||||
if isinstance(trigger, str):
|
if isinstance(trigger, str):
|
||||||
try:
|
try:
|
||||||
trigger = json.loads(trigger)
|
trigger = json.loads(trigger)
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
trigger = None
|
trigger = None
|
||||||
result["source_query"] = row["source_query"]
|
return {
|
||||||
result["content"] = row["content"]
|
"id": str(row["id"]),
|
||||||
result["max_tokens"] = row.get("max_tokens")
|
"bank_id": row["bank_id"],
|
||||||
result["trigger"] = trigger
|
"name": row["name"],
|
||||||
|
"source_query": row["source_query"],
|
||||||
if detail == "full":
|
"content": row["content"],
|
||||||
reflect_response = row.get("reflect_response")
|
"tags": row["tags"] or [],
|
||||||
if isinstance(reflect_response, str):
|
"max_tokens": row.get("max_tokens"),
|
||||||
try:
|
"trigger": trigger,
|
||||||
reflect_response = json.loads(reflect_response)
|
"last_refreshed_at": row["last_refreshed_at"].isoformat() if row["last_refreshed_at"] else None,
|
||||||
except json.JSONDecodeError:
|
"created_at": row["created_at"].isoformat() if row["created_at"] else None,
|
||||||
reflect_response = None
|
"reflect_response": reflect_response,
|
||||||
result["reflect_response"] = reflect_response
|
}
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
# Directives - Hard rules injected into prompts
|
# Directives - Hard rules injected into prompts
|
||||||
|
|
|
||||||
600
hindsight-api-slim/tests/test_bank_templates.py
Normal file
600
hindsight-api-slim/tests/test_bank_templates.py
Normal file
|
|
@ -0,0 +1,600 @@
|
||||||
|
"""Integration tests for bank template import/export endpoints."""
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import pytest_asyncio
|
||||||
|
import httpx
|
||||||
|
from datetime import datetime
|
||||||
|
from hindsight_api.api import create_app
|
||||||
|
|
||||||
|
|
||||||
|
@pytest_asyncio.fixture
|
||||||
|
async def api_client(memory):
|
||||||
|
"""Create an async test client for the FastAPI app."""
|
||||||
|
app = create_app(memory, initialize_memory=False)
|
||||||
|
transport = httpx.ASGITransport(app=app)
|
||||||
|
async with httpx.AsyncClient(transport=transport, base_url="http://test") as client:
|
||||||
|
yield client
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def bank_id():
|
||||||
|
return f"template_test_{datetime.now().timestamp()}"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def sample_template():
|
||||||
|
return {
|
||||||
|
"version": "1",
|
||||||
|
"bank": {
|
||||||
|
"reflect_mission": "Test mission for reflect",
|
||||||
|
"retain_mission": "Extract test data carefully",
|
||||||
|
"retain_extraction_mode": "verbose",
|
||||||
|
"disposition_empathy": 5,
|
||||||
|
"disposition_skepticism": 2,
|
||||||
|
"enable_observations": True,
|
||||||
|
"observations_mission": "Track test patterns",
|
||||||
|
},
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "test-model-one",
|
||||||
|
"name": "Test Model One",
|
||||||
|
"source_query": "What are the key patterns?",
|
||||||
|
"tags": ["test"],
|
||||||
|
"max_tokens": 1024,
|
||||||
|
"trigger": {"refresh_after_consolidation": True},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "test-model-two",
|
||||||
|
"name": "Test Model Two",
|
||||||
|
"source_query": "What are the common issues?",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"directives": [
|
||||||
|
{
|
||||||
|
"name": "Be concise",
|
||||||
|
"content": "Always respond concisely.",
|
||||||
|
"priority": 10,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Use examples",
|
||||||
|
"content": "Include examples when explaining concepts.",
|
||||||
|
"tags": ["style"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class TestImportValidation:
|
||||||
|
"""Test template manifest validation."""
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_dry_run_valid(self, api_client, bank_id, sample_template):
|
||||||
|
"""dry_run=true with a valid manifest returns what would happen."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import?dry_run=true",
|
||||||
|
json=sample_template,
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
assert data["dry_run"] is True
|
||||||
|
assert data["config_applied"] is True
|
||||||
|
assert set(data["mental_models_created"]) == {"test-model-one", "test-model-two"}
|
||||||
|
assert set(data["directives_created"]) == {"Be concise", "Use examples"}
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_invalid_version(self, api_client, bank_id):
|
||||||
|
"""Reject manifest with unsupported version."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={"version": "999"},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 400
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_invalid_extraction_mode(self, api_client, bank_id):
|
||||||
|
"""Semantic validation catches bad extraction mode."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"bank": {"retain_extraction_mode": "invalid_mode"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 400
|
||||||
|
assert "retain_extraction_mode" in resp.json()["detail"]
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_custom_instructions_without_custom_mode(self, api_client, bank_id):
|
||||||
|
"""Validate that custom_instructions requires extraction_mode=custom."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"bank": {
|
||||||
|
"retain_extraction_mode": "verbose",
|
||||||
|
"retain_custom_instructions": "some custom prompt",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 400
|
||||||
|
assert "retain_custom_instructions" in resp.json()["detail"]
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_duplicate_mental_model_ids(self, api_client, bank_id):
|
||||||
|
"""Reject manifest with duplicate mental model IDs."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"mental_models": [
|
||||||
|
{"id": "dup-id", "name": "First", "source_query": "q1"},
|
||||||
|
{"id": "dup-id", "name": "Second", "source_query": "q2"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 400
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_duplicate_directive_names(self, api_client, bank_id):
|
||||||
|
"""Reject manifest with duplicate directive names."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"directives": [
|
||||||
|
{"name": "Same Name", "content": "First"},
|
||||||
|
{"name": "Same Name", "content": "Second"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 400
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_missing_mental_model_id(self, api_client, bank_id):
|
||||||
|
"""Mental model without id is rejected."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"mental_models": [
|
||||||
|
{"name": "No ID Model", "source_query": "test query"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 400
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_invalid_mental_model_id_format(self, api_client, bank_id):
|
||||||
|
"""Mental model with invalid ID format is rejected."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"mental_models": [
|
||||||
|
{"id": "UPPERCASE-NOT-ALLOWED", "name": "Bad", "source_query": "q"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 400
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_empty_manifest(self, api_client, bank_id):
|
||||||
|
"""Import with no bank or mental_models is valid (no-op)."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={"version": "1"},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
assert data["config_applied"] is False
|
||||||
|
assert data["mental_models_created"] == []
|
||||||
|
assert data["directives_created"] == []
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_empty_mental_model_name(self, api_client, bank_id):
|
||||||
|
"""Semantic validation catches empty mental model name."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"mental_models": [
|
||||||
|
{"id": "test-mm", "name": " ", "source_query": "q"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 400
|
||||||
|
assert "name" in resp.json()["detail"]
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_empty_directive_content(self, api_client, bank_id):
|
||||||
|
"""Semantic validation catches empty directive content."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"directives": [
|
||||||
|
{"name": "Bad Directive", "content": " "},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 400
|
||||||
|
assert "content" in resp.json()["detail"]
|
||||||
|
|
||||||
|
|
||||||
|
class TestImportApply:
|
||||||
|
"""Test that import actually applies config, mental models, and directives."""
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_applies_config(self, api_client, bank_id):
|
||||||
|
"""Import with bank config applies config overrides on a new bank."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"bank": {
|
||||||
|
"reflect_mission": "Imported mission",
|
||||||
|
"disposition_empathy": 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
assert data["config_applied"] is True
|
||||||
|
assert data["dry_run"] is False
|
||||||
|
|
||||||
|
# Verify config was actually applied
|
||||||
|
config_resp = await api_client.get(f"/v1/default/banks/{bank_id}/config")
|
||||||
|
assert config_resp.status_code == 200
|
||||||
|
config = config_resp.json()
|
||||||
|
assert config["overrides"]["reflect_mission"] == "Imported mission"
|
||||||
|
assert config["overrides"]["disposition_empathy"] == 4
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_into_existing_bank(self, api_client, bank_id):
|
||||||
|
"""Import into an already-existing bank applies config and creates resources."""
|
||||||
|
# Pre-create the bank
|
||||||
|
await api_client.put(f"/v1/default/banks/{bank_id}", json={})
|
||||||
|
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"bank": {"reflect_mission": "Existing bank mission"},
|
||||||
|
"mental_models": [
|
||||||
|
{"id": "existing-bank-mm", "name": "MM", "source_query": "q"},
|
||||||
|
],
|
||||||
|
"directives": [
|
||||||
|
{"name": "Existing Bank Directive", "content": "Be helpful"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
assert data["config_applied"] is True
|
||||||
|
assert "existing-bank-mm" in data["mental_models_created"]
|
||||||
|
assert "Existing Bank Directive" in data["directives_created"]
|
||||||
|
|
||||||
|
# Verify everything exists
|
||||||
|
config_resp = await api_client.get(f"/v1/default/banks/{bank_id}/config")
|
||||||
|
assert config_resp.json()["overrides"]["reflect_mission"] == "Existing bank mission"
|
||||||
|
|
||||||
|
mm_resp = await api_client.get(f"/v1/default/banks/{bank_id}/mental-models/existing-bank-mm")
|
||||||
|
assert mm_resp.status_code == 200
|
||||||
|
|
||||||
|
dir_resp = await api_client.get(f"/v1/default/banks/{bank_id}/directives")
|
||||||
|
assert dir_resp.status_code == 200
|
||||||
|
names = [d["name"] for d in dir_resp.json()["items"]]
|
||||||
|
assert "Existing Bank Directive" in names
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_creates_mental_models(self, api_client, bank_id):
|
||||||
|
"""Import creates mental models and returns operation IDs."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "import-mm-1",
|
||||||
|
"name": "Imported Model",
|
||||||
|
"source_query": "What patterns exist?",
|
||||||
|
"tags": ["imported"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
assert "import-mm-1" in data["mental_models_created"]
|
||||||
|
assert len(data["operation_ids"]) == 1
|
||||||
|
|
||||||
|
# Verify mental model exists
|
||||||
|
mm_resp = await api_client.get(f"/v1/default/banks/{bank_id}/mental-models/import-mm-1")
|
||||||
|
assert mm_resp.status_code == 200
|
||||||
|
mm = mm_resp.json()
|
||||||
|
assert mm["name"] == "Imported Model"
|
||||||
|
assert mm["source_query"] == "What patterns exist?"
|
||||||
|
assert mm["tags"] == ["imported"]
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_updates_existing_mental_models(self, api_client, bank_id):
|
||||||
|
"""Re-importing updates existing mental models matched by ID."""
|
||||||
|
# First import
|
||||||
|
await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "reusable-mm",
|
||||||
|
"name": "Original Name",
|
||||||
|
"source_query": "Original query",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
# Second import with same ID but different content
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "reusable-mm",
|
||||||
|
"name": "Updated Name",
|
||||||
|
"source_query": "Updated query",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
assert "reusable-mm" in data["mental_models_updated"]
|
||||||
|
assert data["mental_models_created"] == []
|
||||||
|
|
||||||
|
# Verify update
|
||||||
|
mm_resp = await api_client.get(f"/v1/default/banks/{bank_id}/mental-models/reusable-mm")
|
||||||
|
assert mm_resp.status_code == 200
|
||||||
|
mm = mm_resp.json()
|
||||||
|
assert mm["name"] == "Updated Name"
|
||||||
|
assert mm["source_query"] == "Updated query"
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_creates_directives(self, api_client, bank_id):
|
||||||
|
"""Import creates directives."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"directives": [
|
||||||
|
{
|
||||||
|
"name": "Test Directive",
|
||||||
|
"content": "Always be helpful and precise.",
|
||||||
|
"priority": 5,
|
||||||
|
"tags": ["test"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
assert "Test Directive" in data["directives_created"]
|
||||||
|
assert data["directives_updated"] == []
|
||||||
|
|
||||||
|
# Verify directive exists
|
||||||
|
dir_resp = await api_client.get(f"/v1/default/banks/{bank_id}/directives")
|
||||||
|
assert dir_resp.status_code == 200
|
||||||
|
items = dir_resp.json()["items"]
|
||||||
|
assert len(items) == 1
|
||||||
|
assert items[0]["name"] == "Test Directive"
|
||||||
|
assert items[0]["content"] == "Always be helpful and precise."
|
||||||
|
assert items[0]["priority"] == 5
|
||||||
|
assert items[0]["tags"] == ["test"]
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_updates_existing_directives(self, api_client, bank_id):
|
||||||
|
"""Re-importing updates existing directives matched by name."""
|
||||||
|
# First import
|
||||||
|
await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"directives": [
|
||||||
|
{"name": "Reusable Directive", "content": "Original content", "priority": 1},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
# Second import with same name but different content
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"directives": [
|
||||||
|
{"name": "Reusable Directive", "content": "Updated content", "priority": 10},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
assert "Reusable Directive" in data["directives_updated"]
|
||||||
|
assert data["directives_created"] == []
|
||||||
|
|
||||||
|
# Verify update
|
||||||
|
dir_resp = await api_client.get(f"/v1/default/banks/{bank_id}/directives")
|
||||||
|
items = dir_resp.json()["items"]
|
||||||
|
directive = [d for d in items if d["name"] == "Reusable Directive"][0]
|
||||||
|
assert directive["content"] == "Updated content"
|
||||||
|
assert directive["priority"] == 10
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_config_only(self, api_client, bank_id):
|
||||||
|
"""Import with only bank config (no mental_models or directives) works."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"bank": {"retain_extraction_mode": "verbose"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
assert data["config_applied"] is True
|
||||||
|
assert data["mental_models_created"] == []
|
||||||
|
assert data["directives_created"] == []
|
||||||
|
assert data["operation_ids"] == []
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_mental_models_only(self, api_client, bank_id):
|
||||||
|
"""Import with only mental_models works."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"mental_models": [
|
||||||
|
{"id": "mm-only", "name": "MM Only", "source_query": "test"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
assert data["config_applied"] is False
|
||||||
|
assert "mm-only" in data["mental_models_created"]
|
||||||
|
assert data["directives_created"] == []
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_import_directives_only(self, api_client, bank_id):
|
||||||
|
"""Import with only directives works."""
|
||||||
|
resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"directives": [
|
||||||
|
{"name": "Dir Only", "content": "test directive"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
assert data["config_applied"] is False
|
||||||
|
assert data["mental_models_created"] == []
|
||||||
|
assert "Dir Only" in data["directives_created"]
|
||||||
|
|
||||||
|
|
||||||
|
class TestExport:
|
||||||
|
"""Test bank template export."""
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_export_empty_bank(self, api_client, bank_id):
|
||||||
|
"""Export a bank with no overrides returns minimal manifest."""
|
||||||
|
# Create bank
|
||||||
|
await api_client.put(f"/v1/default/banks/{bank_id}", json={})
|
||||||
|
|
||||||
|
resp = await api_client.get(f"/v1/default/banks/{bank_id}/export")
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
assert data["version"] == "1"
|
||||||
|
assert data["bank"] is None
|
||||||
|
assert data["mental_models"] is None
|
||||||
|
assert data["directives"] is None
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_export_after_import(self, api_client, bank_id):
|
||||||
|
"""Export after import returns the imported config, mental models, and directives."""
|
||||||
|
template = {
|
||||||
|
"version": "1",
|
||||||
|
"bank": {
|
||||||
|
"reflect_mission": "Roundtrip mission",
|
||||||
|
"disposition_empathy": 3,
|
||||||
|
},
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "roundtrip-mm",
|
||||||
|
"name": "Roundtrip Model",
|
||||||
|
"source_query": "What happened?",
|
||||||
|
"tags": ["roundtrip"],
|
||||||
|
"max_tokens": 512,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"directives": [
|
||||||
|
{
|
||||||
|
"name": "Roundtrip Directive",
|
||||||
|
"content": "Be thorough.",
|
||||||
|
"priority": 3,
|
||||||
|
"tags": ["roundtrip"],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
# Import
|
||||||
|
import_resp = await api_client.post(f"/v1/default/banks/{bank_id}/import", json=template)
|
||||||
|
assert import_resp.status_code == 200
|
||||||
|
|
||||||
|
# Export
|
||||||
|
resp = await api_client.get(f"/v1/default/banks/{bank_id}/export")
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
|
||||||
|
assert data["version"] == "1"
|
||||||
|
assert data["bank"]["reflect_mission"] == "Roundtrip mission"
|
||||||
|
assert data["bank"]["disposition_empathy"] == 3
|
||||||
|
|
||||||
|
assert len(data["mental_models"]) == 1
|
||||||
|
mm = data["mental_models"][0]
|
||||||
|
assert mm["id"] == "roundtrip-mm"
|
||||||
|
assert mm["name"] == "Roundtrip Model"
|
||||||
|
assert mm["source_query"] == "What happened?"
|
||||||
|
assert mm["tags"] == ["roundtrip"]
|
||||||
|
assert mm["max_tokens"] == 512
|
||||||
|
|
||||||
|
assert len(data["directives"]) == 1
|
||||||
|
d = data["directives"][0]
|
||||||
|
assert d["name"] == "Roundtrip Directive"
|
||||||
|
assert d["content"] == "Be thorough."
|
||||||
|
assert d["priority"] == 3
|
||||||
|
assert d["tags"] == ["roundtrip"]
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_export_reimport_roundtrip(self, api_client, bank_id):
|
||||||
|
"""Exported manifest can be re-imported into a new bank."""
|
||||||
|
# Set up source bank
|
||||||
|
await api_client.post(
|
||||||
|
f"/v1/default/banks/{bank_id}/import",
|
||||||
|
json={
|
||||||
|
"version": "1",
|
||||||
|
"bank": {"retain_mission": "Roundtrip test"},
|
||||||
|
"mental_models": [
|
||||||
|
{"id": "rt-mm", "name": "RT Model", "source_query": "test query"},
|
||||||
|
],
|
||||||
|
"directives": [
|
||||||
|
{"name": "RT Directive", "content": "test directive"},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
# Export
|
||||||
|
export_resp = await api_client.get(f"/v1/default/banks/{bank_id}/export")
|
||||||
|
assert export_resp.status_code == 200
|
||||||
|
exported = export_resp.json()
|
||||||
|
|
||||||
|
# Import into a new bank
|
||||||
|
new_bank_id = f"{bank_id}_clone"
|
||||||
|
import_resp = await api_client.post(
|
||||||
|
f"/v1/default/banks/{new_bank_id}/import",
|
||||||
|
json=exported,
|
||||||
|
)
|
||||||
|
assert import_resp.status_code == 200
|
||||||
|
data = import_resp.json()
|
||||||
|
assert data["config_applied"] is True
|
||||||
|
assert "rt-mm" in data["mental_models_created"]
|
||||||
|
assert "RT Directive" in data["directives_created"]
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_export_nonexistent_bank(self, api_client):
|
||||||
|
"""Export from a nonexistent bank returns the bank with defaults (auto-created)."""
|
||||||
|
resp = await api_client.get("/v1/default/banks/nonexistent-export-test/export")
|
||||||
|
# get_bank_profile auto-creates, so this returns a valid empty manifest
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.json()
|
||||||
|
assert data["version"] == "1"
|
||||||
|
|
@ -2102,6 +2102,111 @@ paths:
|
||||||
summary: Create or update memory bank
|
summary: Create or update memory bank
|
||||||
tags:
|
tags:
|
||||||
- Banks
|
- Banks
|
||||||
|
/v1/default/banks/{bank_id}/import:
|
||||||
|
post:
|
||||||
|
description: "Import a bank template manifest to create or update a bank's configuration,\
|
||||||
|
\ mental models, and directives. If the bank does not exist it is created.\
|
||||||
|
\ Config fields are applied as per-bank overrides. Mental models are matched\
|
||||||
|
\ by id, directives by name — existing ones are updated, new ones are created.\
|
||||||
|
\ Use dry_run=true to validate the manifest without applying changes."
|
||||||
|
operationId: import_bank_template
|
||||||
|
parameters:
|
||||||
|
- explode: false
|
||||||
|
in: path
|
||||||
|
name: bank_id
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
title: Bank Id
|
||||||
|
type: string
|
||||||
|
style: simple
|
||||||
|
- description: "Validate only, do not apply changes"
|
||||||
|
explode: true
|
||||||
|
in: query
|
||||||
|
name: dry_run
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
default: false
|
||||||
|
description: "Validate only, do not apply changes"
|
||||||
|
title: Dry Run
|
||||||
|
type: boolean
|
||||||
|
style: form
|
||||||
|
- explode: false
|
||||||
|
in: header
|
||||||
|
name: authorization
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
nullable: true
|
||||||
|
type: string
|
||||||
|
style: simple
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/BankTemplateImportResponse'
|
||||||
|
description: Successful Response
|
||||||
|
"422":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/HTTPValidationError'
|
||||||
|
description: Validation Error
|
||||||
|
summary: Import bank template
|
||||||
|
tags:
|
||||||
|
- Bank Templates
|
||||||
|
/v1/default/banks/{bank_id}/export:
|
||||||
|
get:
|
||||||
|
description: "Export a bank's current configuration, mental models, and directives\
|
||||||
|
\ as a template manifest. The exported manifest can be imported into another\
|
||||||
|
\ bank to replicate the setup."
|
||||||
|
operationId: export_bank_template
|
||||||
|
parameters:
|
||||||
|
- explode: false
|
||||||
|
in: path
|
||||||
|
name: bank_id
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
title: Bank Id
|
||||||
|
type: string
|
||||||
|
style: simple
|
||||||
|
- explode: false
|
||||||
|
in: header
|
||||||
|
name: authorization
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
nullable: true
|
||||||
|
type: string
|
||||||
|
style: simple
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/BankTemplateManifest'
|
||||||
|
description: Successful Response
|
||||||
|
"422":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/HTTPValidationError'
|
||||||
|
description: Validation Error
|
||||||
|
summary: Export bank template
|
||||||
|
tags:
|
||||||
|
- Bank Templates
|
||||||
|
/v1/bank-template-schema:
|
||||||
|
get:
|
||||||
|
description: Returns the JSON Schema for the bank template manifest format.
|
||||||
|
Use this to validate template manifests before importing.
|
||||||
|
operationId: get_bank_template_schema
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema: {}
|
||||||
|
description: Successful Response
|
||||||
|
summary: Get bank template JSON Schema
|
||||||
|
tags:
|
||||||
|
- Bank Templates
|
||||||
/v1/default/banks/{bank_id}/observations:
|
/v1/default/banks/{bank_id}/observations:
|
||||||
delete:
|
delete:
|
||||||
description: Delete all observations for a memory bank. This is useful for resetting
|
description: Delete all observations for a memory bank. This is useful for resetting
|
||||||
|
|
@ -3420,6 +3525,242 @@ components:
|
||||||
- total_links
|
- total_links
|
||||||
- total_nodes
|
- total_nodes
|
||||||
title: BankStatsResponse
|
title: BankStatsResponse
|
||||||
|
BankTemplateConfig:
|
||||||
|
description: |-
|
||||||
|
Bank configuration fields within a template manifest.
|
||||||
|
|
||||||
|
Only includes configurable (per-bank) fields. Credential fields
|
||||||
|
(API keys, base URLs) are intentionally excluded for security.
|
||||||
|
properties:
|
||||||
|
reflect_mission:
|
||||||
|
nullable: true
|
||||||
|
type: string
|
||||||
|
retain_mission:
|
||||||
|
nullable: true
|
||||||
|
type: string
|
||||||
|
retain_extraction_mode:
|
||||||
|
nullable: true
|
||||||
|
type: string
|
||||||
|
retain_custom_instructions:
|
||||||
|
nullable: true
|
||||||
|
type: string
|
||||||
|
retain_chunk_size:
|
||||||
|
nullable: true
|
||||||
|
type: integer
|
||||||
|
enable_observations:
|
||||||
|
nullable: true
|
||||||
|
type: boolean
|
||||||
|
observations_mission:
|
||||||
|
nullable: true
|
||||||
|
type: string
|
||||||
|
disposition_skepticism:
|
||||||
|
maximum: 5.0
|
||||||
|
minimum: 1.0
|
||||||
|
nullable: true
|
||||||
|
type: integer
|
||||||
|
disposition_literalism:
|
||||||
|
maximum: 5.0
|
||||||
|
minimum: 1.0
|
||||||
|
nullable: true
|
||||||
|
type: integer
|
||||||
|
disposition_empathy:
|
||||||
|
maximum: 5.0
|
||||||
|
minimum: 1.0
|
||||||
|
nullable: true
|
||||||
|
type: integer
|
||||||
|
entity_labels:
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
nullable: true
|
||||||
|
type: array
|
||||||
|
entities_allow_free_form:
|
||||||
|
nullable: true
|
||||||
|
type: boolean
|
||||||
|
title: BankTemplateConfig
|
||||||
|
BankTemplateDirective:
|
||||||
|
description: |-
|
||||||
|
A directive definition within a bank template manifest.
|
||||||
|
|
||||||
|
Directives are matched by name on re-import: existing directives
|
||||||
|
with the same name are updated, new ones are created.
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
description: Human-readable name for the directive (used as match key on
|
||||||
|
re-import)
|
||||||
|
title: Name
|
||||||
|
type: string
|
||||||
|
content:
|
||||||
|
description: The directive text to inject into prompts
|
||||||
|
title: Content
|
||||||
|
type: string
|
||||||
|
priority:
|
||||||
|
default: 0
|
||||||
|
description: Higher priority directives are injected first
|
||||||
|
title: Priority
|
||||||
|
type: integer
|
||||||
|
is_active:
|
||||||
|
default: true
|
||||||
|
description: Whether this directive is active
|
||||||
|
title: Is Active
|
||||||
|
type: boolean
|
||||||
|
tags:
|
||||||
|
default: []
|
||||||
|
description: Tags for filtering
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
required:
|
||||||
|
- content
|
||||||
|
- name
|
||||||
|
title: BankTemplateDirective
|
||||||
|
BankTemplateImportResponse:
|
||||||
|
description: Response model for the bank template import endpoint.
|
||||||
|
example:
|
||||||
|
operation_ids:
|
||||||
|
- operation_ids
|
||||||
|
- operation_ids
|
||||||
|
directives_created:
|
||||||
|
- directives_created
|
||||||
|
- directives_created
|
||||||
|
bank_id: bank_id
|
||||||
|
mental_models_updated:
|
||||||
|
- mental_models_updated
|
||||||
|
- mental_models_updated
|
||||||
|
directives_updated:
|
||||||
|
- directives_updated
|
||||||
|
- directives_updated
|
||||||
|
config_applied: true
|
||||||
|
mental_models_created:
|
||||||
|
- mental_models_created
|
||||||
|
- mental_models_created
|
||||||
|
dry_run: false
|
||||||
|
properties:
|
||||||
|
bank_id:
|
||||||
|
description: Bank that was imported into
|
||||||
|
title: Bank Id
|
||||||
|
type: string
|
||||||
|
config_applied:
|
||||||
|
description: Whether bank config was updated
|
||||||
|
title: Config Applied
|
||||||
|
type: boolean
|
||||||
|
mental_models_created:
|
||||||
|
default: []
|
||||||
|
description: IDs of newly created mental models
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
mental_models_updated:
|
||||||
|
default: []
|
||||||
|
description: IDs of updated mental models
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
directives_created:
|
||||||
|
default: []
|
||||||
|
description: Names of newly created directives
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
directives_updated:
|
||||||
|
default: []
|
||||||
|
description: Names of updated directives
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
operation_ids:
|
||||||
|
default: []
|
||||||
|
description: Operation IDs for mental model content generation (async)
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
dry_run:
|
||||||
|
default: false
|
||||||
|
description: True if this was a validation-only run
|
||||||
|
title: Dry Run
|
||||||
|
type: boolean
|
||||||
|
required:
|
||||||
|
- bank_id
|
||||||
|
- config_applied
|
||||||
|
title: BankTemplateImportResponse
|
||||||
|
BankTemplateManifest:
|
||||||
|
description: |-
|
||||||
|
A bank template manifest for import/export.
|
||||||
|
|
||||||
|
Version field enables forward-compatible schema evolution: the API
|
||||||
|
auto-upgrades older manifest versions to the current schema on import.
|
||||||
|
example:
|
||||||
|
bank:
|
||||||
|
disposition_empathy: 5
|
||||||
|
enable_observations: true
|
||||||
|
reflect_mission: You are helping a support agent remember customer interactions.
|
||||||
|
retain_mission: "Extract customer issues, resolutions, and sentiment."
|
||||||
|
directives:
|
||||||
|
- content: Always respond with empathy and understanding.
|
||||||
|
name: Always be empathetic
|
||||||
|
priority: 10
|
||||||
|
mental_models:
|
||||||
|
- id: sentiment-overview
|
||||||
|
name: Customer Sentiment Overview
|
||||||
|
source_query: What is the overall sentiment trend?
|
||||||
|
trigger:
|
||||||
|
refresh_after_consolidation: true
|
||||||
|
version: "1"
|
||||||
|
properties:
|
||||||
|
version:
|
||||||
|
description: Manifest schema version (currently '1')
|
||||||
|
title: Version
|
||||||
|
type: string
|
||||||
|
bank:
|
||||||
|
$ref: '#/components/schemas/BankTemplateConfig'
|
||||||
|
mental_models:
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/BankTemplateMentalModel'
|
||||||
|
nullable: true
|
||||||
|
type: array
|
||||||
|
directives:
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/BankTemplateDirective'
|
||||||
|
nullable: true
|
||||||
|
type: array
|
||||||
|
required:
|
||||||
|
- version
|
||||||
|
title: BankTemplateManifest
|
||||||
|
BankTemplateMentalModel:
|
||||||
|
description: A mental model definition within a bank template manifest.
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
description: Unique ID for the mental model (alphanumeric lowercase with
|
||||||
|
hyphens)
|
||||||
|
title: Id
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
description: Human-readable name for the mental model
|
||||||
|
title: Name
|
||||||
|
type: string
|
||||||
|
source_query:
|
||||||
|
description: The query to run to generate content
|
||||||
|
title: Source Query
|
||||||
|
type: string
|
||||||
|
tags:
|
||||||
|
default: []
|
||||||
|
description: Tags for scoped visibility
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
max_tokens:
|
||||||
|
default: 2048
|
||||||
|
description: Maximum tokens for generated content
|
||||||
|
maximum: 8192.0
|
||||||
|
minimum: 256.0
|
||||||
|
title: Max Tokens
|
||||||
|
type: integer
|
||||||
|
trigger:
|
||||||
|
$ref: '#/components/schemas/MentalModelTrigger-Output'
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- name
|
||||||
|
- source_query
|
||||||
|
title: BankTemplateMentalModel
|
||||||
Body_file_retain:
|
Body_file_retain:
|
||||||
properties:
|
properties:
|
||||||
files:
|
files:
|
||||||
|
|
|
||||||
380
hindsight-clients/go/api_bank_templates.go
Normal file
380
hindsight-clients/go/api_bank_templates.go
Normal file
|
|
@ -0,0 +1,380 @@
|
||||||
|
/*
|
||||||
|
Hindsight HTTP API
|
||||||
|
|
||||||
|
HTTP API for Hindsight
|
||||||
|
|
||||||
|
API version: 0.4.22
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||||
|
|
||||||
|
package hindsight
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// BankTemplatesAPIService BankTemplatesAPI service
|
||||||
|
type BankTemplatesAPIService service
|
||||||
|
|
||||||
|
type ApiExportBankTemplateRequest struct {
|
||||||
|
ctx context.Context
|
||||||
|
ApiService *BankTemplatesAPIService
|
||||||
|
bankId string
|
||||||
|
authorization *string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r ApiExportBankTemplateRequest) Authorization(authorization string) ApiExportBankTemplateRequest {
|
||||||
|
r.authorization = &authorization
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r ApiExportBankTemplateRequest) Execute() (*BankTemplateManifest, *http.Response, error) {
|
||||||
|
return r.ApiService.ExportBankTemplateExecute(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ExportBankTemplate Export bank template
|
||||||
|
|
||||||
|
Export a bank's current configuration, mental models, and directives as a template manifest. The exported manifest can be imported into another bank to replicate the setup.
|
||||||
|
|
||||||
|
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||||
|
@param bankId
|
||||||
|
@return ApiExportBankTemplateRequest
|
||||||
|
*/
|
||||||
|
func (a *BankTemplatesAPIService) ExportBankTemplate(ctx context.Context, bankId string) ApiExportBankTemplateRequest {
|
||||||
|
return ApiExportBankTemplateRequest{
|
||||||
|
ApiService: a,
|
||||||
|
ctx: ctx,
|
||||||
|
bankId: bankId,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute executes the request
|
||||||
|
// @return BankTemplateManifest
|
||||||
|
func (a *BankTemplatesAPIService) ExportBankTemplateExecute(r ApiExportBankTemplateRequest) (*BankTemplateManifest, *http.Response, error) {
|
||||||
|
var (
|
||||||
|
localVarHTTPMethod = http.MethodGet
|
||||||
|
localVarPostBody interface{}
|
||||||
|
formFiles []formFile
|
||||||
|
localVarReturnValue *BankTemplateManifest
|
||||||
|
)
|
||||||
|
|
||||||
|
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BankTemplatesAPIService.ExportBankTemplate")
|
||||||
|
if err != nil {
|
||||||
|
return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}
|
||||||
|
}
|
||||||
|
|
||||||
|
localVarPath := localBasePath + "/v1/default/banks/{bank_id}/export"
|
||||||
|
localVarPath = strings.Replace(localVarPath, "{"+"bank_id"+"}", url.PathEscape(parameterValueToString(r.bankId, "bankId")), -1)
|
||||||
|
|
||||||
|
localVarHeaderParams := make(map[string]string)
|
||||||
|
localVarQueryParams := url.Values{}
|
||||||
|
localVarFormParams := url.Values{}
|
||||||
|
|
||||||
|
// to determine the Content-Type header
|
||||||
|
localVarHTTPContentTypes := []string{}
|
||||||
|
|
||||||
|
// set Content-Type header
|
||||||
|
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
|
||||||
|
if localVarHTTPContentType != "" {
|
||||||
|
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
|
||||||
|
}
|
||||||
|
|
||||||
|
// to determine the Accept header
|
||||||
|
localVarHTTPHeaderAccepts := []string{"application/json"}
|
||||||
|
|
||||||
|
// set Accept header
|
||||||
|
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
|
||||||
|
if localVarHTTPHeaderAccept != "" {
|
||||||
|
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
|
||||||
|
}
|
||||||
|
if r.authorization != nil {
|
||||||
|
parameterAddToHeaderOrQuery(localVarHeaderParams, "authorization", r.authorization, "simple", "")
|
||||||
|
}
|
||||||
|
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)
|
||||||
|
if err != nil {
|
||||||
|
return localVarReturnValue, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
localVarHTTPResponse, err := a.client.callAPI(req)
|
||||||
|
if err != nil || localVarHTTPResponse == nil {
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, err
|
||||||
|
}
|
||||||
|
|
||||||
|
localVarBody, err := io.ReadAll(localVarHTTPResponse.Body)
|
||||||
|
localVarHTTPResponse.Body.Close()
|
||||||
|
localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
|
||||||
|
if err != nil {
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if localVarHTTPResponse.StatusCode >= 300 {
|
||||||
|
newErr := &GenericOpenAPIError{
|
||||||
|
body: localVarBody,
|
||||||
|
error: localVarHTTPResponse.Status,
|
||||||
|
}
|
||||||
|
if localVarHTTPResponse.StatusCode == 422 {
|
||||||
|
var v HTTPValidationError
|
||||||
|
err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
newErr.error = err.Error()
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||||
|
}
|
||||||
|
newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v)
|
||||||
|
newErr.model = v
|
||||||
|
}
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||||
|
}
|
||||||
|
|
||||||
|
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
newErr := &GenericOpenAPIError{
|
||||||
|
body: localVarBody,
|
||||||
|
error: err.Error(),
|
||||||
|
}
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ApiGetBankTemplateSchemaRequest struct {
|
||||||
|
ctx context.Context
|
||||||
|
ApiService *BankTemplatesAPIService
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r ApiGetBankTemplateSchemaRequest) Execute() (interface{}, *http.Response, error) {
|
||||||
|
return r.ApiService.GetBankTemplateSchemaExecute(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
GetBankTemplateSchema Get bank template JSON Schema
|
||||||
|
|
||||||
|
Returns the JSON Schema for the bank template manifest format. Use this to validate template manifests before importing.
|
||||||
|
|
||||||
|
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||||
|
@return ApiGetBankTemplateSchemaRequest
|
||||||
|
*/
|
||||||
|
func (a *BankTemplatesAPIService) GetBankTemplateSchema(ctx context.Context) ApiGetBankTemplateSchemaRequest {
|
||||||
|
return ApiGetBankTemplateSchemaRequest{
|
||||||
|
ApiService: a,
|
||||||
|
ctx: ctx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute executes the request
|
||||||
|
// @return interface{}
|
||||||
|
func (a *BankTemplatesAPIService) GetBankTemplateSchemaExecute(r ApiGetBankTemplateSchemaRequest) (interface{}, *http.Response, error) {
|
||||||
|
var (
|
||||||
|
localVarHTTPMethod = http.MethodGet
|
||||||
|
localVarPostBody interface{}
|
||||||
|
formFiles []formFile
|
||||||
|
localVarReturnValue interface{}
|
||||||
|
)
|
||||||
|
|
||||||
|
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BankTemplatesAPIService.GetBankTemplateSchema")
|
||||||
|
if err != nil {
|
||||||
|
return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}
|
||||||
|
}
|
||||||
|
|
||||||
|
localVarPath := localBasePath + "/v1/bank-template-schema"
|
||||||
|
|
||||||
|
localVarHeaderParams := make(map[string]string)
|
||||||
|
localVarQueryParams := url.Values{}
|
||||||
|
localVarFormParams := url.Values{}
|
||||||
|
|
||||||
|
// to determine the Content-Type header
|
||||||
|
localVarHTTPContentTypes := []string{}
|
||||||
|
|
||||||
|
// set Content-Type header
|
||||||
|
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
|
||||||
|
if localVarHTTPContentType != "" {
|
||||||
|
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
|
||||||
|
}
|
||||||
|
|
||||||
|
// to determine the Accept header
|
||||||
|
localVarHTTPHeaderAccepts := []string{"application/json"}
|
||||||
|
|
||||||
|
// set Accept header
|
||||||
|
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
|
||||||
|
if localVarHTTPHeaderAccept != "" {
|
||||||
|
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
|
||||||
|
}
|
||||||
|
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)
|
||||||
|
if err != nil {
|
||||||
|
return localVarReturnValue, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
localVarHTTPResponse, err := a.client.callAPI(req)
|
||||||
|
if err != nil || localVarHTTPResponse == nil {
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, err
|
||||||
|
}
|
||||||
|
|
||||||
|
localVarBody, err := io.ReadAll(localVarHTTPResponse.Body)
|
||||||
|
localVarHTTPResponse.Body.Close()
|
||||||
|
localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
|
||||||
|
if err != nil {
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if localVarHTTPResponse.StatusCode >= 300 {
|
||||||
|
newErr := &GenericOpenAPIError{
|
||||||
|
body: localVarBody,
|
||||||
|
error: localVarHTTPResponse.Status,
|
||||||
|
}
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||||
|
}
|
||||||
|
|
||||||
|
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
newErr := &GenericOpenAPIError{
|
||||||
|
body: localVarBody,
|
||||||
|
error: err.Error(),
|
||||||
|
}
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ApiImportBankTemplateRequest struct {
|
||||||
|
ctx context.Context
|
||||||
|
ApiService *BankTemplatesAPIService
|
||||||
|
bankId string
|
||||||
|
dryRun *bool
|
||||||
|
authorization *string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate only, do not apply changes
|
||||||
|
func (r ApiImportBankTemplateRequest) DryRun(dryRun bool) ApiImportBankTemplateRequest {
|
||||||
|
r.dryRun = &dryRun
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r ApiImportBankTemplateRequest) Authorization(authorization string) ApiImportBankTemplateRequest {
|
||||||
|
r.authorization = &authorization
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r ApiImportBankTemplateRequest) Execute() (*BankTemplateImportResponse, *http.Response, error) {
|
||||||
|
return r.ApiService.ImportBankTemplateExecute(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ImportBankTemplate Import bank template
|
||||||
|
|
||||||
|
Import a bank template manifest to create or update a bank's configuration, mental models, and directives. If the bank does not exist it is created. Config fields are applied as per-bank overrides. Mental models are matched by id, directives by name — existing ones are updated, new ones are created. Use dry_run=true to validate the manifest without applying changes.
|
||||||
|
|
||||||
|
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||||
|
@param bankId
|
||||||
|
@return ApiImportBankTemplateRequest
|
||||||
|
*/
|
||||||
|
func (a *BankTemplatesAPIService) ImportBankTemplate(ctx context.Context, bankId string) ApiImportBankTemplateRequest {
|
||||||
|
return ApiImportBankTemplateRequest{
|
||||||
|
ApiService: a,
|
||||||
|
ctx: ctx,
|
||||||
|
bankId: bankId,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute executes the request
|
||||||
|
// @return BankTemplateImportResponse
|
||||||
|
func (a *BankTemplatesAPIService) ImportBankTemplateExecute(r ApiImportBankTemplateRequest) (*BankTemplateImportResponse, *http.Response, error) {
|
||||||
|
var (
|
||||||
|
localVarHTTPMethod = http.MethodPost
|
||||||
|
localVarPostBody interface{}
|
||||||
|
formFiles []formFile
|
||||||
|
localVarReturnValue *BankTemplateImportResponse
|
||||||
|
)
|
||||||
|
|
||||||
|
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "BankTemplatesAPIService.ImportBankTemplate")
|
||||||
|
if err != nil {
|
||||||
|
return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}
|
||||||
|
}
|
||||||
|
|
||||||
|
localVarPath := localBasePath + "/v1/default/banks/{bank_id}/import"
|
||||||
|
localVarPath = strings.Replace(localVarPath, "{"+"bank_id"+"}", url.PathEscape(parameterValueToString(r.bankId, "bankId")), -1)
|
||||||
|
|
||||||
|
localVarHeaderParams := make(map[string]string)
|
||||||
|
localVarQueryParams := url.Values{}
|
||||||
|
localVarFormParams := url.Values{}
|
||||||
|
|
||||||
|
if r.dryRun != nil {
|
||||||
|
parameterAddToHeaderOrQuery(localVarQueryParams, "dry_run", r.dryRun, "form", "")
|
||||||
|
} else {
|
||||||
|
var defaultValue bool = false
|
||||||
|
r.dryRun = &defaultValue
|
||||||
|
}
|
||||||
|
// to determine the Content-Type header
|
||||||
|
localVarHTTPContentTypes := []string{}
|
||||||
|
|
||||||
|
// set Content-Type header
|
||||||
|
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
|
||||||
|
if localVarHTTPContentType != "" {
|
||||||
|
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
|
||||||
|
}
|
||||||
|
|
||||||
|
// to determine the Accept header
|
||||||
|
localVarHTTPHeaderAccepts := []string{"application/json"}
|
||||||
|
|
||||||
|
// set Accept header
|
||||||
|
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
|
||||||
|
if localVarHTTPHeaderAccept != "" {
|
||||||
|
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
|
||||||
|
}
|
||||||
|
if r.authorization != nil {
|
||||||
|
parameterAddToHeaderOrQuery(localVarHeaderParams, "authorization", r.authorization, "simple", "")
|
||||||
|
}
|
||||||
|
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)
|
||||||
|
if err != nil {
|
||||||
|
return localVarReturnValue, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
localVarHTTPResponse, err := a.client.callAPI(req)
|
||||||
|
if err != nil || localVarHTTPResponse == nil {
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, err
|
||||||
|
}
|
||||||
|
|
||||||
|
localVarBody, err := io.ReadAll(localVarHTTPResponse.Body)
|
||||||
|
localVarHTTPResponse.Body.Close()
|
||||||
|
localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
|
||||||
|
if err != nil {
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if localVarHTTPResponse.StatusCode >= 300 {
|
||||||
|
newErr := &GenericOpenAPIError{
|
||||||
|
body: localVarBody,
|
||||||
|
error: localVarHTTPResponse.Status,
|
||||||
|
}
|
||||||
|
if localVarHTTPResponse.StatusCode == 422 {
|
||||||
|
var v HTTPValidationError
|
||||||
|
err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
newErr.error = err.Error()
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||||
|
}
|
||||||
|
newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v)
|
||||||
|
newErr.model = v
|
||||||
|
}
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||||
|
}
|
||||||
|
|
||||||
|
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
newErr := &GenericOpenAPIError{
|
||||||
|
body: localVarBody,
|
||||||
|
error: err.Error(),
|
||||||
|
}
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, nil
|
||||||
|
}
|
||||||
|
|
@ -51,6 +51,8 @@ type APIClient struct {
|
||||||
|
|
||||||
AuditAPI *AuditAPIService
|
AuditAPI *AuditAPIService
|
||||||
|
|
||||||
|
BankTemplatesAPI *BankTemplatesAPIService
|
||||||
|
|
||||||
BanksAPI *BanksAPIService
|
BanksAPI *BanksAPIService
|
||||||
|
|
||||||
DirectivesAPI *DirectivesAPIService
|
DirectivesAPI *DirectivesAPIService
|
||||||
|
|
@ -89,6 +91,7 @@ func NewAPIClient(cfg *Configuration) *APIClient {
|
||||||
|
|
||||||
// API Services
|
// API Services
|
||||||
c.AuditAPI = (*AuditAPIService)(&c.common)
|
c.AuditAPI = (*AuditAPIService)(&c.common)
|
||||||
|
c.BankTemplatesAPI = (*BankTemplatesAPIService)(&c.common)
|
||||||
c.BanksAPI = (*BanksAPIService)(&c.common)
|
c.BanksAPI = (*BanksAPIService)(&c.common)
|
||||||
c.DirectivesAPI = (*DirectivesAPIService)(&c.common)
|
c.DirectivesAPI = (*DirectivesAPIService)(&c.common)
|
||||||
c.DocumentsAPI = (*DocumentsAPIService)(&c.common)
|
c.DocumentsAPI = (*DocumentsAPIService)(&c.common)
|
||||||
|
|
|
||||||
633
hindsight-clients/go/model_bank_template_config.go
Normal file
633
hindsight-clients/go/model_bank_template_config.go
Normal file
|
|
@ -0,0 +1,633 @@
|
||||||
|
/*
|
||||||
|
Hindsight HTTP API
|
||||||
|
|
||||||
|
HTTP API for Hindsight
|
||||||
|
|
||||||
|
API version: 0.4.22
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||||
|
|
||||||
|
package hindsight
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
// checks if the BankTemplateConfig type satisfies the MappedNullable interface at compile time
|
||||||
|
var _ MappedNullable = &BankTemplateConfig{}
|
||||||
|
|
||||||
|
// BankTemplateConfig Bank configuration fields within a template manifest. Only includes configurable (per-bank) fields. Credential fields (API keys, base URLs) are intentionally excluded for security.
|
||||||
|
type BankTemplateConfig struct {
|
||||||
|
ReflectMission NullableString `json:"reflect_mission,omitempty"`
|
||||||
|
RetainMission NullableString `json:"retain_mission,omitempty"`
|
||||||
|
RetainExtractionMode NullableString `json:"retain_extraction_mode,omitempty"`
|
||||||
|
RetainCustomInstructions NullableString `json:"retain_custom_instructions,omitempty"`
|
||||||
|
RetainChunkSize NullableInt32 `json:"retain_chunk_size,omitempty"`
|
||||||
|
EnableObservations NullableBool `json:"enable_observations,omitempty"`
|
||||||
|
ObservationsMission NullableString `json:"observations_mission,omitempty"`
|
||||||
|
DispositionSkepticism NullableInt32 `json:"disposition_skepticism,omitempty"`
|
||||||
|
DispositionLiteralism NullableInt32 `json:"disposition_literalism,omitempty"`
|
||||||
|
DispositionEmpathy NullableInt32 `json:"disposition_empathy,omitempty"`
|
||||||
|
EntityLabels []string `json:"entity_labels,omitempty"`
|
||||||
|
EntitiesAllowFreeForm NullableBool `json:"entities_allow_free_form,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBankTemplateConfig instantiates a new BankTemplateConfig object
|
||||||
|
// This constructor will assign default values to properties that have it defined,
|
||||||
|
// and makes sure properties required by API are set, but the set of arguments
|
||||||
|
// will change when the set of required properties is changed
|
||||||
|
func NewBankTemplateConfig() *BankTemplateConfig {
|
||||||
|
this := BankTemplateConfig{}
|
||||||
|
return &this
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBankTemplateConfigWithDefaults instantiates a new BankTemplateConfig object
|
||||||
|
// This constructor will only assign default values to properties that have it defined,
|
||||||
|
// but it doesn't guarantee that properties required by API are set
|
||||||
|
func NewBankTemplateConfigWithDefaults() *BankTemplateConfig {
|
||||||
|
this := BankTemplateConfig{}
|
||||||
|
return &this
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetReflectMission returns the ReflectMission field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
|
func (o *BankTemplateConfig) GetReflectMission() string {
|
||||||
|
if o == nil || IsNil(o.ReflectMission.Get()) {
|
||||||
|
var ret string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.ReflectMission.Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetReflectMissionOk returns a tuple with the ReflectMission field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
|
func (o *BankTemplateConfig) GetReflectMissionOk() (*string, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.ReflectMission.Get(), o.ReflectMission.IsSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasReflectMission returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateConfig) HasReflectMission() bool {
|
||||||
|
if o != nil && o.ReflectMission.IsSet() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetReflectMission gets a reference to the given NullableString and assigns it to the ReflectMission field.
|
||||||
|
func (o *BankTemplateConfig) SetReflectMission(v string) {
|
||||||
|
o.ReflectMission.Set(&v)
|
||||||
|
}
|
||||||
|
// SetReflectMissionNil sets the value for ReflectMission to be an explicit nil
|
||||||
|
func (o *BankTemplateConfig) SetReflectMissionNil() {
|
||||||
|
o.ReflectMission.Set(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsetReflectMission ensures that no value is present for ReflectMission, not even an explicit nil
|
||||||
|
func (o *BankTemplateConfig) UnsetReflectMission() {
|
||||||
|
o.ReflectMission.Unset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRetainMission returns the RetainMission field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
|
func (o *BankTemplateConfig) GetRetainMission() string {
|
||||||
|
if o == nil || IsNil(o.RetainMission.Get()) {
|
||||||
|
var ret string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.RetainMission.Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRetainMissionOk returns a tuple with the RetainMission field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
|
func (o *BankTemplateConfig) GetRetainMissionOk() (*string, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.RetainMission.Get(), o.RetainMission.IsSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasRetainMission returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateConfig) HasRetainMission() bool {
|
||||||
|
if o != nil && o.RetainMission.IsSet() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRetainMission gets a reference to the given NullableString and assigns it to the RetainMission field.
|
||||||
|
func (o *BankTemplateConfig) SetRetainMission(v string) {
|
||||||
|
o.RetainMission.Set(&v)
|
||||||
|
}
|
||||||
|
// SetRetainMissionNil sets the value for RetainMission to be an explicit nil
|
||||||
|
func (o *BankTemplateConfig) SetRetainMissionNil() {
|
||||||
|
o.RetainMission.Set(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsetRetainMission ensures that no value is present for RetainMission, not even an explicit nil
|
||||||
|
func (o *BankTemplateConfig) UnsetRetainMission() {
|
||||||
|
o.RetainMission.Unset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRetainExtractionMode returns the RetainExtractionMode field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
|
func (o *BankTemplateConfig) GetRetainExtractionMode() string {
|
||||||
|
if o == nil || IsNil(o.RetainExtractionMode.Get()) {
|
||||||
|
var ret string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.RetainExtractionMode.Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRetainExtractionModeOk returns a tuple with the RetainExtractionMode field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
|
func (o *BankTemplateConfig) GetRetainExtractionModeOk() (*string, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.RetainExtractionMode.Get(), o.RetainExtractionMode.IsSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasRetainExtractionMode returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateConfig) HasRetainExtractionMode() bool {
|
||||||
|
if o != nil && o.RetainExtractionMode.IsSet() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRetainExtractionMode gets a reference to the given NullableString and assigns it to the RetainExtractionMode field.
|
||||||
|
func (o *BankTemplateConfig) SetRetainExtractionMode(v string) {
|
||||||
|
o.RetainExtractionMode.Set(&v)
|
||||||
|
}
|
||||||
|
// SetRetainExtractionModeNil sets the value for RetainExtractionMode to be an explicit nil
|
||||||
|
func (o *BankTemplateConfig) SetRetainExtractionModeNil() {
|
||||||
|
o.RetainExtractionMode.Set(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsetRetainExtractionMode ensures that no value is present for RetainExtractionMode, not even an explicit nil
|
||||||
|
func (o *BankTemplateConfig) UnsetRetainExtractionMode() {
|
||||||
|
o.RetainExtractionMode.Unset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRetainCustomInstructions returns the RetainCustomInstructions field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
|
func (o *BankTemplateConfig) GetRetainCustomInstructions() string {
|
||||||
|
if o == nil || IsNil(o.RetainCustomInstructions.Get()) {
|
||||||
|
var ret string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.RetainCustomInstructions.Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRetainCustomInstructionsOk returns a tuple with the RetainCustomInstructions field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
|
func (o *BankTemplateConfig) GetRetainCustomInstructionsOk() (*string, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.RetainCustomInstructions.Get(), o.RetainCustomInstructions.IsSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasRetainCustomInstructions returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateConfig) HasRetainCustomInstructions() bool {
|
||||||
|
if o != nil && o.RetainCustomInstructions.IsSet() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRetainCustomInstructions gets a reference to the given NullableString and assigns it to the RetainCustomInstructions field.
|
||||||
|
func (o *BankTemplateConfig) SetRetainCustomInstructions(v string) {
|
||||||
|
o.RetainCustomInstructions.Set(&v)
|
||||||
|
}
|
||||||
|
// SetRetainCustomInstructionsNil sets the value for RetainCustomInstructions to be an explicit nil
|
||||||
|
func (o *BankTemplateConfig) SetRetainCustomInstructionsNil() {
|
||||||
|
o.RetainCustomInstructions.Set(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsetRetainCustomInstructions ensures that no value is present for RetainCustomInstructions, not even an explicit nil
|
||||||
|
func (o *BankTemplateConfig) UnsetRetainCustomInstructions() {
|
||||||
|
o.RetainCustomInstructions.Unset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRetainChunkSize returns the RetainChunkSize field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
|
func (o *BankTemplateConfig) GetRetainChunkSize() int32 {
|
||||||
|
if o == nil || IsNil(o.RetainChunkSize.Get()) {
|
||||||
|
var ret int32
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.RetainChunkSize.Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRetainChunkSizeOk returns a tuple with the RetainChunkSize field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
|
func (o *BankTemplateConfig) GetRetainChunkSizeOk() (*int32, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.RetainChunkSize.Get(), o.RetainChunkSize.IsSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasRetainChunkSize returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateConfig) HasRetainChunkSize() bool {
|
||||||
|
if o != nil && o.RetainChunkSize.IsSet() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRetainChunkSize gets a reference to the given NullableInt32 and assigns it to the RetainChunkSize field.
|
||||||
|
func (o *BankTemplateConfig) SetRetainChunkSize(v int32) {
|
||||||
|
o.RetainChunkSize.Set(&v)
|
||||||
|
}
|
||||||
|
// SetRetainChunkSizeNil sets the value for RetainChunkSize to be an explicit nil
|
||||||
|
func (o *BankTemplateConfig) SetRetainChunkSizeNil() {
|
||||||
|
o.RetainChunkSize.Set(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsetRetainChunkSize ensures that no value is present for RetainChunkSize, not even an explicit nil
|
||||||
|
func (o *BankTemplateConfig) UnsetRetainChunkSize() {
|
||||||
|
o.RetainChunkSize.Unset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEnableObservations returns the EnableObservations field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
|
func (o *BankTemplateConfig) GetEnableObservations() bool {
|
||||||
|
if o == nil || IsNil(o.EnableObservations.Get()) {
|
||||||
|
var ret bool
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.EnableObservations.Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEnableObservationsOk returns a tuple with the EnableObservations field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
|
func (o *BankTemplateConfig) GetEnableObservationsOk() (*bool, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.EnableObservations.Get(), o.EnableObservations.IsSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasEnableObservations returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateConfig) HasEnableObservations() bool {
|
||||||
|
if o != nil && o.EnableObservations.IsSet() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetEnableObservations gets a reference to the given NullableBool and assigns it to the EnableObservations field.
|
||||||
|
func (o *BankTemplateConfig) SetEnableObservations(v bool) {
|
||||||
|
o.EnableObservations.Set(&v)
|
||||||
|
}
|
||||||
|
// SetEnableObservationsNil sets the value for EnableObservations to be an explicit nil
|
||||||
|
func (o *BankTemplateConfig) SetEnableObservationsNil() {
|
||||||
|
o.EnableObservations.Set(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsetEnableObservations ensures that no value is present for EnableObservations, not even an explicit nil
|
||||||
|
func (o *BankTemplateConfig) UnsetEnableObservations() {
|
||||||
|
o.EnableObservations.Unset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetObservationsMission returns the ObservationsMission field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
|
func (o *BankTemplateConfig) GetObservationsMission() string {
|
||||||
|
if o == nil || IsNil(o.ObservationsMission.Get()) {
|
||||||
|
var ret string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.ObservationsMission.Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetObservationsMissionOk returns a tuple with the ObservationsMission field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
|
func (o *BankTemplateConfig) GetObservationsMissionOk() (*string, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.ObservationsMission.Get(), o.ObservationsMission.IsSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasObservationsMission returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateConfig) HasObservationsMission() bool {
|
||||||
|
if o != nil && o.ObservationsMission.IsSet() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetObservationsMission gets a reference to the given NullableString and assigns it to the ObservationsMission field.
|
||||||
|
func (o *BankTemplateConfig) SetObservationsMission(v string) {
|
||||||
|
o.ObservationsMission.Set(&v)
|
||||||
|
}
|
||||||
|
// SetObservationsMissionNil sets the value for ObservationsMission to be an explicit nil
|
||||||
|
func (o *BankTemplateConfig) SetObservationsMissionNil() {
|
||||||
|
o.ObservationsMission.Set(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsetObservationsMission ensures that no value is present for ObservationsMission, not even an explicit nil
|
||||||
|
func (o *BankTemplateConfig) UnsetObservationsMission() {
|
||||||
|
o.ObservationsMission.Unset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDispositionSkepticism returns the DispositionSkepticism field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
|
func (o *BankTemplateConfig) GetDispositionSkepticism() int32 {
|
||||||
|
if o == nil || IsNil(o.DispositionSkepticism.Get()) {
|
||||||
|
var ret int32
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.DispositionSkepticism.Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDispositionSkepticismOk returns a tuple with the DispositionSkepticism field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
|
func (o *BankTemplateConfig) GetDispositionSkepticismOk() (*int32, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.DispositionSkepticism.Get(), o.DispositionSkepticism.IsSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasDispositionSkepticism returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateConfig) HasDispositionSkepticism() bool {
|
||||||
|
if o != nil && o.DispositionSkepticism.IsSet() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDispositionSkepticism gets a reference to the given NullableInt32 and assigns it to the DispositionSkepticism field.
|
||||||
|
func (o *BankTemplateConfig) SetDispositionSkepticism(v int32) {
|
||||||
|
o.DispositionSkepticism.Set(&v)
|
||||||
|
}
|
||||||
|
// SetDispositionSkepticismNil sets the value for DispositionSkepticism to be an explicit nil
|
||||||
|
func (o *BankTemplateConfig) SetDispositionSkepticismNil() {
|
||||||
|
o.DispositionSkepticism.Set(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsetDispositionSkepticism ensures that no value is present for DispositionSkepticism, not even an explicit nil
|
||||||
|
func (o *BankTemplateConfig) UnsetDispositionSkepticism() {
|
||||||
|
o.DispositionSkepticism.Unset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDispositionLiteralism returns the DispositionLiteralism field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
|
func (o *BankTemplateConfig) GetDispositionLiteralism() int32 {
|
||||||
|
if o == nil || IsNil(o.DispositionLiteralism.Get()) {
|
||||||
|
var ret int32
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.DispositionLiteralism.Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDispositionLiteralismOk returns a tuple with the DispositionLiteralism field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
|
func (o *BankTemplateConfig) GetDispositionLiteralismOk() (*int32, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.DispositionLiteralism.Get(), o.DispositionLiteralism.IsSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasDispositionLiteralism returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateConfig) HasDispositionLiteralism() bool {
|
||||||
|
if o != nil && o.DispositionLiteralism.IsSet() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDispositionLiteralism gets a reference to the given NullableInt32 and assigns it to the DispositionLiteralism field.
|
||||||
|
func (o *BankTemplateConfig) SetDispositionLiteralism(v int32) {
|
||||||
|
o.DispositionLiteralism.Set(&v)
|
||||||
|
}
|
||||||
|
// SetDispositionLiteralismNil sets the value for DispositionLiteralism to be an explicit nil
|
||||||
|
func (o *BankTemplateConfig) SetDispositionLiteralismNil() {
|
||||||
|
o.DispositionLiteralism.Set(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsetDispositionLiteralism ensures that no value is present for DispositionLiteralism, not even an explicit nil
|
||||||
|
func (o *BankTemplateConfig) UnsetDispositionLiteralism() {
|
||||||
|
o.DispositionLiteralism.Unset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDispositionEmpathy returns the DispositionEmpathy field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
|
func (o *BankTemplateConfig) GetDispositionEmpathy() int32 {
|
||||||
|
if o == nil || IsNil(o.DispositionEmpathy.Get()) {
|
||||||
|
var ret int32
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.DispositionEmpathy.Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDispositionEmpathyOk returns a tuple with the DispositionEmpathy field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
|
func (o *BankTemplateConfig) GetDispositionEmpathyOk() (*int32, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.DispositionEmpathy.Get(), o.DispositionEmpathy.IsSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasDispositionEmpathy returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateConfig) HasDispositionEmpathy() bool {
|
||||||
|
if o != nil && o.DispositionEmpathy.IsSet() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDispositionEmpathy gets a reference to the given NullableInt32 and assigns it to the DispositionEmpathy field.
|
||||||
|
func (o *BankTemplateConfig) SetDispositionEmpathy(v int32) {
|
||||||
|
o.DispositionEmpathy.Set(&v)
|
||||||
|
}
|
||||||
|
// SetDispositionEmpathyNil sets the value for DispositionEmpathy to be an explicit nil
|
||||||
|
func (o *BankTemplateConfig) SetDispositionEmpathyNil() {
|
||||||
|
o.DispositionEmpathy.Set(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsetDispositionEmpathy ensures that no value is present for DispositionEmpathy, not even an explicit nil
|
||||||
|
func (o *BankTemplateConfig) UnsetDispositionEmpathy() {
|
||||||
|
o.DispositionEmpathy.Unset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEntityLabels returns the EntityLabels field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
|
func (o *BankTemplateConfig) GetEntityLabels() []string {
|
||||||
|
if o == nil {
|
||||||
|
var ret []string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return o.EntityLabels
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEntityLabelsOk returns a tuple with the EntityLabels field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
|
func (o *BankTemplateConfig) GetEntityLabelsOk() ([]string, bool) {
|
||||||
|
if o == nil || IsNil(o.EntityLabels) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.EntityLabels, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasEntityLabels returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateConfig) HasEntityLabels() bool {
|
||||||
|
if o != nil && !IsNil(o.EntityLabels) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetEntityLabels gets a reference to the given []string and assigns it to the EntityLabels field.
|
||||||
|
func (o *BankTemplateConfig) SetEntityLabels(v []string) {
|
||||||
|
o.EntityLabels = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEntitiesAllowFreeForm returns the EntitiesAllowFreeForm field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
|
func (o *BankTemplateConfig) GetEntitiesAllowFreeForm() bool {
|
||||||
|
if o == nil || IsNil(o.EntitiesAllowFreeForm.Get()) {
|
||||||
|
var ret bool
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.EntitiesAllowFreeForm.Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEntitiesAllowFreeFormOk returns a tuple with the EntitiesAllowFreeForm field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
|
func (o *BankTemplateConfig) GetEntitiesAllowFreeFormOk() (*bool, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.EntitiesAllowFreeForm.Get(), o.EntitiesAllowFreeForm.IsSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasEntitiesAllowFreeForm returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateConfig) HasEntitiesAllowFreeForm() bool {
|
||||||
|
if o != nil && o.EntitiesAllowFreeForm.IsSet() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetEntitiesAllowFreeForm gets a reference to the given NullableBool and assigns it to the EntitiesAllowFreeForm field.
|
||||||
|
func (o *BankTemplateConfig) SetEntitiesAllowFreeForm(v bool) {
|
||||||
|
o.EntitiesAllowFreeForm.Set(&v)
|
||||||
|
}
|
||||||
|
// SetEntitiesAllowFreeFormNil sets the value for EntitiesAllowFreeForm to be an explicit nil
|
||||||
|
func (o *BankTemplateConfig) SetEntitiesAllowFreeFormNil() {
|
||||||
|
o.EntitiesAllowFreeForm.Set(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsetEntitiesAllowFreeForm ensures that no value is present for EntitiesAllowFreeForm, not even an explicit nil
|
||||||
|
func (o *BankTemplateConfig) UnsetEntitiesAllowFreeForm() {
|
||||||
|
o.EntitiesAllowFreeForm.Unset()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o BankTemplateConfig) MarshalJSON() ([]byte, error) {
|
||||||
|
toSerialize,err := o.ToMap()
|
||||||
|
if err != nil {
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
return json.Marshal(toSerialize)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o BankTemplateConfig) ToMap() (map[string]interface{}, error) {
|
||||||
|
toSerialize := map[string]interface{}{}
|
||||||
|
if o.ReflectMission.IsSet() {
|
||||||
|
toSerialize["reflect_mission"] = o.ReflectMission.Get()
|
||||||
|
}
|
||||||
|
if o.RetainMission.IsSet() {
|
||||||
|
toSerialize["retain_mission"] = o.RetainMission.Get()
|
||||||
|
}
|
||||||
|
if o.RetainExtractionMode.IsSet() {
|
||||||
|
toSerialize["retain_extraction_mode"] = o.RetainExtractionMode.Get()
|
||||||
|
}
|
||||||
|
if o.RetainCustomInstructions.IsSet() {
|
||||||
|
toSerialize["retain_custom_instructions"] = o.RetainCustomInstructions.Get()
|
||||||
|
}
|
||||||
|
if o.RetainChunkSize.IsSet() {
|
||||||
|
toSerialize["retain_chunk_size"] = o.RetainChunkSize.Get()
|
||||||
|
}
|
||||||
|
if o.EnableObservations.IsSet() {
|
||||||
|
toSerialize["enable_observations"] = o.EnableObservations.Get()
|
||||||
|
}
|
||||||
|
if o.ObservationsMission.IsSet() {
|
||||||
|
toSerialize["observations_mission"] = o.ObservationsMission.Get()
|
||||||
|
}
|
||||||
|
if o.DispositionSkepticism.IsSet() {
|
||||||
|
toSerialize["disposition_skepticism"] = o.DispositionSkepticism.Get()
|
||||||
|
}
|
||||||
|
if o.DispositionLiteralism.IsSet() {
|
||||||
|
toSerialize["disposition_literalism"] = o.DispositionLiteralism.Get()
|
||||||
|
}
|
||||||
|
if o.DispositionEmpathy.IsSet() {
|
||||||
|
toSerialize["disposition_empathy"] = o.DispositionEmpathy.Get()
|
||||||
|
}
|
||||||
|
if o.EntityLabels != nil {
|
||||||
|
toSerialize["entity_labels"] = o.EntityLabels
|
||||||
|
}
|
||||||
|
if o.EntitiesAllowFreeForm.IsSet() {
|
||||||
|
toSerialize["entities_allow_free_form"] = o.EntitiesAllowFreeForm.Get()
|
||||||
|
}
|
||||||
|
return toSerialize, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type NullableBankTemplateConfig struct {
|
||||||
|
value *BankTemplateConfig
|
||||||
|
isSet bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v NullableBankTemplateConfig) Get() *BankTemplateConfig {
|
||||||
|
return v.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *NullableBankTemplateConfig) Set(val *BankTemplateConfig) {
|
||||||
|
v.value = val
|
||||||
|
v.isSet = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v NullableBankTemplateConfig) IsSet() bool {
|
||||||
|
return v.isSet
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *NullableBankTemplateConfig) Unset() {
|
||||||
|
v.value = nil
|
||||||
|
v.isSet = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNullableBankTemplateConfig(val *BankTemplateConfig) *NullableBankTemplateConfig {
|
||||||
|
return &NullableBankTemplateConfig{value: val, isSet: true}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v NullableBankTemplateConfig) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(v.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *NullableBankTemplateConfig) UnmarshalJSON(src []byte) error {
|
||||||
|
v.isSet = true
|
||||||
|
return json.Unmarshal(src, &v.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
307
hindsight-clients/go/model_bank_template_directive.go
Normal file
307
hindsight-clients/go/model_bank_template_directive.go
Normal file
|
|
@ -0,0 +1,307 @@
|
||||||
|
/*
|
||||||
|
Hindsight HTTP API
|
||||||
|
|
||||||
|
HTTP API for Hindsight
|
||||||
|
|
||||||
|
API version: 0.4.22
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||||
|
|
||||||
|
package hindsight
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// checks if the BankTemplateDirective type satisfies the MappedNullable interface at compile time
|
||||||
|
var _ MappedNullable = &BankTemplateDirective{}
|
||||||
|
|
||||||
|
// BankTemplateDirective A directive definition within a bank template manifest. Directives are matched by name on re-import: existing directives with the same name are updated, new ones are created.
|
||||||
|
type BankTemplateDirective struct {
|
||||||
|
// Human-readable name for the directive (used as match key on re-import)
|
||||||
|
Name string `json:"name"`
|
||||||
|
// The directive text to inject into prompts
|
||||||
|
Content string `json:"content"`
|
||||||
|
// Higher priority directives are injected first
|
||||||
|
Priority *int32 `json:"priority,omitempty"`
|
||||||
|
// Whether this directive is active
|
||||||
|
IsActive *bool `json:"is_active,omitempty"`
|
||||||
|
// Tags for filtering
|
||||||
|
Tags []string `json:"tags,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type _BankTemplateDirective BankTemplateDirective
|
||||||
|
|
||||||
|
// NewBankTemplateDirective instantiates a new BankTemplateDirective object
|
||||||
|
// This constructor will assign default values to properties that have it defined,
|
||||||
|
// and makes sure properties required by API are set, but the set of arguments
|
||||||
|
// will change when the set of required properties is changed
|
||||||
|
func NewBankTemplateDirective(name string, content string) *BankTemplateDirective {
|
||||||
|
this := BankTemplateDirective{}
|
||||||
|
this.Name = name
|
||||||
|
this.Content = content
|
||||||
|
var priority int32 = 0
|
||||||
|
this.Priority = &priority
|
||||||
|
var isActive bool = true
|
||||||
|
this.IsActive = &isActive
|
||||||
|
return &this
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBankTemplateDirectiveWithDefaults instantiates a new BankTemplateDirective object
|
||||||
|
// This constructor will only assign default values to properties that have it defined,
|
||||||
|
// but it doesn't guarantee that properties required by API are set
|
||||||
|
func NewBankTemplateDirectiveWithDefaults() *BankTemplateDirective {
|
||||||
|
this := BankTemplateDirective{}
|
||||||
|
var priority int32 = 0
|
||||||
|
this.Priority = &priority
|
||||||
|
var isActive bool = true
|
||||||
|
this.IsActive = &isActive
|
||||||
|
return &this
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetName returns the Name field value
|
||||||
|
func (o *BankTemplateDirective) GetName() string {
|
||||||
|
if o == nil {
|
||||||
|
var ret string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNameOk returns a tuple with the Name field value
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateDirective) GetNameOk() (*string, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return &o.Name, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetName sets field value
|
||||||
|
func (o *BankTemplateDirective) SetName(v string) {
|
||||||
|
o.Name = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetContent returns the Content field value
|
||||||
|
func (o *BankTemplateDirective) GetContent() string {
|
||||||
|
if o == nil {
|
||||||
|
var ret string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.Content
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetContentOk returns a tuple with the Content field value
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateDirective) GetContentOk() (*string, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return &o.Content, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetContent sets field value
|
||||||
|
func (o *BankTemplateDirective) SetContent(v string) {
|
||||||
|
o.Content = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPriority returns the Priority field value if set, zero value otherwise.
|
||||||
|
func (o *BankTemplateDirective) GetPriority() int32 {
|
||||||
|
if o == nil || IsNil(o.Priority) {
|
||||||
|
var ret int32
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.Priority
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPriorityOk returns a tuple with the Priority field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateDirective) GetPriorityOk() (*int32, bool) {
|
||||||
|
if o == nil || IsNil(o.Priority) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.Priority, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasPriority returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateDirective) HasPriority() bool {
|
||||||
|
if o != nil && !IsNil(o.Priority) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPriority gets a reference to the given int32 and assigns it to the Priority field.
|
||||||
|
func (o *BankTemplateDirective) SetPriority(v int32) {
|
||||||
|
o.Priority = &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetIsActive returns the IsActive field value if set, zero value otherwise.
|
||||||
|
func (o *BankTemplateDirective) GetIsActive() bool {
|
||||||
|
if o == nil || IsNil(o.IsActive) {
|
||||||
|
var ret bool
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.IsActive
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetIsActiveOk returns a tuple with the IsActive field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateDirective) GetIsActiveOk() (*bool, bool) {
|
||||||
|
if o == nil || IsNil(o.IsActive) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.IsActive, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasIsActive returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateDirective) HasIsActive() bool {
|
||||||
|
if o != nil && !IsNil(o.IsActive) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetIsActive gets a reference to the given bool and assigns it to the IsActive field.
|
||||||
|
func (o *BankTemplateDirective) SetIsActive(v bool) {
|
||||||
|
o.IsActive = &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTags returns the Tags field value if set, zero value otherwise.
|
||||||
|
func (o *BankTemplateDirective) GetTags() []string {
|
||||||
|
if o == nil || IsNil(o.Tags) {
|
||||||
|
var ret []string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return o.Tags
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTagsOk returns a tuple with the Tags field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateDirective) GetTagsOk() ([]string, bool) {
|
||||||
|
if o == nil || IsNil(o.Tags) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.Tags, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasTags returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateDirective) HasTags() bool {
|
||||||
|
if o != nil && !IsNil(o.Tags) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTags gets a reference to the given []string and assigns it to the Tags field.
|
||||||
|
func (o *BankTemplateDirective) SetTags(v []string) {
|
||||||
|
o.Tags = v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o BankTemplateDirective) MarshalJSON() ([]byte, error) {
|
||||||
|
toSerialize,err := o.ToMap()
|
||||||
|
if err != nil {
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
return json.Marshal(toSerialize)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o BankTemplateDirective) ToMap() (map[string]interface{}, error) {
|
||||||
|
toSerialize := map[string]interface{}{}
|
||||||
|
toSerialize["name"] = o.Name
|
||||||
|
toSerialize["content"] = o.Content
|
||||||
|
if !IsNil(o.Priority) {
|
||||||
|
toSerialize["priority"] = o.Priority
|
||||||
|
}
|
||||||
|
if !IsNil(o.IsActive) {
|
||||||
|
toSerialize["is_active"] = o.IsActive
|
||||||
|
}
|
||||||
|
if !IsNil(o.Tags) {
|
||||||
|
toSerialize["tags"] = o.Tags
|
||||||
|
}
|
||||||
|
return toSerialize, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *BankTemplateDirective) UnmarshalJSON(data []byte) (err error) {
|
||||||
|
// This validates that all required properties are included in the JSON object
|
||||||
|
// by unmarshalling the object into a generic map with string keys and checking
|
||||||
|
// that every required field exists as a key in the generic map.
|
||||||
|
requiredProperties := []string{
|
||||||
|
"name",
|
||||||
|
"content",
|
||||||
|
}
|
||||||
|
|
||||||
|
allProperties := make(map[string]interface{})
|
||||||
|
|
||||||
|
err = json.Unmarshal(data, &allProperties)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, requiredProperty := range(requiredProperties) {
|
||||||
|
if _, exists := allProperties[requiredProperty]; !exists {
|
||||||
|
return fmt.Errorf("no value given for required property %v", requiredProperty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
varBankTemplateDirective := _BankTemplateDirective{}
|
||||||
|
|
||||||
|
decoder := json.NewDecoder(bytes.NewReader(data))
|
||||||
|
decoder.DisallowUnknownFields()
|
||||||
|
err = decoder.Decode(&varBankTemplateDirective)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*o = BankTemplateDirective(varBankTemplateDirective)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type NullableBankTemplateDirective struct {
|
||||||
|
value *BankTemplateDirective
|
||||||
|
isSet bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v NullableBankTemplateDirective) Get() *BankTemplateDirective {
|
||||||
|
return v.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *NullableBankTemplateDirective) Set(val *BankTemplateDirective) {
|
||||||
|
v.value = val
|
||||||
|
v.isSet = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v NullableBankTemplateDirective) IsSet() bool {
|
||||||
|
return v.isSet
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *NullableBankTemplateDirective) Unset() {
|
||||||
|
v.value = nil
|
||||||
|
v.isSet = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNullableBankTemplateDirective(val *BankTemplateDirective) *NullableBankTemplateDirective {
|
||||||
|
return &NullableBankTemplateDirective{value: val, isSet: true}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v NullableBankTemplateDirective) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(v.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *NullableBankTemplateDirective) UnmarshalJSON(src []byte) error {
|
||||||
|
v.isSet = true
|
||||||
|
return json.Unmarshal(src, &v.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
414
hindsight-clients/go/model_bank_template_import_response.go
Normal file
414
hindsight-clients/go/model_bank_template_import_response.go
Normal file
|
|
@ -0,0 +1,414 @@
|
||||||
|
/*
|
||||||
|
Hindsight HTTP API
|
||||||
|
|
||||||
|
HTTP API for Hindsight
|
||||||
|
|
||||||
|
API version: 0.4.22
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||||
|
|
||||||
|
package hindsight
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// checks if the BankTemplateImportResponse type satisfies the MappedNullable interface at compile time
|
||||||
|
var _ MappedNullable = &BankTemplateImportResponse{}
|
||||||
|
|
||||||
|
// BankTemplateImportResponse Response model for the bank template import endpoint.
|
||||||
|
type BankTemplateImportResponse struct {
|
||||||
|
// Bank that was imported into
|
||||||
|
BankId string `json:"bank_id"`
|
||||||
|
// Whether bank config was updated
|
||||||
|
ConfigApplied bool `json:"config_applied"`
|
||||||
|
// IDs of newly created mental models
|
||||||
|
MentalModelsCreated []string `json:"mental_models_created,omitempty"`
|
||||||
|
// IDs of updated mental models
|
||||||
|
MentalModelsUpdated []string `json:"mental_models_updated,omitempty"`
|
||||||
|
// Names of newly created directives
|
||||||
|
DirectivesCreated []string `json:"directives_created,omitempty"`
|
||||||
|
// Names of updated directives
|
||||||
|
DirectivesUpdated []string `json:"directives_updated,omitempty"`
|
||||||
|
// Operation IDs for mental model content generation (async)
|
||||||
|
OperationIds []string `json:"operation_ids,omitempty"`
|
||||||
|
// True if this was a validation-only run
|
||||||
|
DryRun *bool `json:"dry_run,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type _BankTemplateImportResponse BankTemplateImportResponse
|
||||||
|
|
||||||
|
// NewBankTemplateImportResponse instantiates a new BankTemplateImportResponse object
|
||||||
|
// This constructor will assign default values to properties that have it defined,
|
||||||
|
// and makes sure properties required by API are set, but the set of arguments
|
||||||
|
// will change when the set of required properties is changed
|
||||||
|
func NewBankTemplateImportResponse(bankId string, configApplied bool) *BankTemplateImportResponse {
|
||||||
|
this := BankTemplateImportResponse{}
|
||||||
|
this.BankId = bankId
|
||||||
|
this.ConfigApplied = configApplied
|
||||||
|
var dryRun bool = false
|
||||||
|
this.DryRun = &dryRun
|
||||||
|
return &this
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBankTemplateImportResponseWithDefaults instantiates a new BankTemplateImportResponse object
|
||||||
|
// This constructor will only assign default values to properties that have it defined,
|
||||||
|
// but it doesn't guarantee that properties required by API are set
|
||||||
|
func NewBankTemplateImportResponseWithDefaults() *BankTemplateImportResponse {
|
||||||
|
this := BankTemplateImportResponse{}
|
||||||
|
var dryRun bool = false
|
||||||
|
this.DryRun = &dryRun
|
||||||
|
return &this
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBankId returns the BankId field value
|
||||||
|
func (o *BankTemplateImportResponse) GetBankId() string {
|
||||||
|
if o == nil {
|
||||||
|
var ret string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.BankId
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBankIdOk returns a tuple with the BankId field value
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateImportResponse) GetBankIdOk() (*string, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return &o.BankId, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBankId sets field value
|
||||||
|
func (o *BankTemplateImportResponse) SetBankId(v string) {
|
||||||
|
o.BankId = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetConfigApplied returns the ConfigApplied field value
|
||||||
|
func (o *BankTemplateImportResponse) GetConfigApplied() bool {
|
||||||
|
if o == nil {
|
||||||
|
var ret bool
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.ConfigApplied
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetConfigAppliedOk returns a tuple with the ConfigApplied field value
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateImportResponse) GetConfigAppliedOk() (*bool, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return &o.ConfigApplied, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetConfigApplied sets field value
|
||||||
|
func (o *BankTemplateImportResponse) SetConfigApplied(v bool) {
|
||||||
|
o.ConfigApplied = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMentalModelsCreated returns the MentalModelsCreated field value if set, zero value otherwise.
|
||||||
|
func (o *BankTemplateImportResponse) GetMentalModelsCreated() []string {
|
||||||
|
if o == nil || IsNil(o.MentalModelsCreated) {
|
||||||
|
var ret []string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return o.MentalModelsCreated
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMentalModelsCreatedOk returns a tuple with the MentalModelsCreated field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateImportResponse) GetMentalModelsCreatedOk() ([]string, bool) {
|
||||||
|
if o == nil || IsNil(o.MentalModelsCreated) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.MentalModelsCreated, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasMentalModelsCreated returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateImportResponse) HasMentalModelsCreated() bool {
|
||||||
|
if o != nil && !IsNil(o.MentalModelsCreated) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMentalModelsCreated gets a reference to the given []string and assigns it to the MentalModelsCreated field.
|
||||||
|
func (o *BankTemplateImportResponse) SetMentalModelsCreated(v []string) {
|
||||||
|
o.MentalModelsCreated = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMentalModelsUpdated returns the MentalModelsUpdated field value if set, zero value otherwise.
|
||||||
|
func (o *BankTemplateImportResponse) GetMentalModelsUpdated() []string {
|
||||||
|
if o == nil || IsNil(o.MentalModelsUpdated) {
|
||||||
|
var ret []string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return o.MentalModelsUpdated
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMentalModelsUpdatedOk returns a tuple with the MentalModelsUpdated field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateImportResponse) GetMentalModelsUpdatedOk() ([]string, bool) {
|
||||||
|
if o == nil || IsNil(o.MentalModelsUpdated) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.MentalModelsUpdated, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasMentalModelsUpdated returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateImportResponse) HasMentalModelsUpdated() bool {
|
||||||
|
if o != nil && !IsNil(o.MentalModelsUpdated) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMentalModelsUpdated gets a reference to the given []string and assigns it to the MentalModelsUpdated field.
|
||||||
|
func (o *BankTemplateImportResponse) SetMentalModelsUpdated(v []string) {
|
||||||
|
o.MentalModelsUpdated = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDirectivesCreated returns the DirectivesCreated field value if set, zero value otherwise.
|
||||||
|
func (o *BankTemplateImportResponse) GetDirectivesCreated() []string {
|
||||||
|
if o == nil || IsNil(o.DirectivesCreated) {
|
||||||
|
var ret []string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return o.DirectivesCreated
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDirectivesCreatedOk returns a tuple with the DirectivesCreated field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateImportResponse) GetDirectivesCreatedOk() ([]string, bool) {
|
||||||
|
if o == nil || IsNil(o.DirectivesCreated) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.DirectivesCreated, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasDirectivesCreated returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateImportResponse) HasDirectivesCreated() bool {
|
||||||
|
if o != nil && !IsNil(o.DirectivesCreated) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDirectivesCreated gets a reference to the given []string and assigns it to the DirectivesCreated field.
|
||||||
|
func (o *BankTemplateImportResponse) SetDirectivesCreated(v []string) {
|
||||||
|
o.DirectivesCreated = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDirectivesUpdated returns the DirectivesUpdated field value if set, zero value otherwise.
|
||||||
|
func (o *BankTemplateImportResponse) GetDirectivesUpdated() []string {
|
||||||
|
if o == nil || IsNil(o.DirectivesUpdated) {
|
||||||
|
var ret []string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return o.DirectivesUpdated
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDirectivesUpdatedOk returns a tuple with the DirectivesUpdated field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateImportResponse) GetDirectivesUpdatedOk() ([]string, bool) {
|
||||||
|
if o == nil || IsNil(o.DirectivesUpdated) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.DirectivesUpdated, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasDirectivesUpdated returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateImportResponse) HasDirectivesUpdated() bool {
|
||||||
|
if o != nil && !IsNil(o.DirectivesUpdated) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDirectivesUpdated gets a reference to the given []string and assigns it to the DirectivesUpdated field.
|
||||||
|
func (o *BankTemplateImportResponse) SetDirectivesUpdated(v []string) {
|
||||||
|
o.DirectivesUpdated = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOperationIds returns the OperationIds field value if set, zero value otherwise.
|
||||||
|
func (o *BankTemplateImportResponse) GetOperationIds() []string {
|
||||||
|
if o == nil || IsNil(o.OperationIds) {
|
||||||
|
var ret []string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return o.OperationIds
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOperationIdsOk returns a tuple with the OperationIds field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateImportResponse) GetOperationIdsOk() ([]string, bool) {
|
||||||
|
if o == nil || IsNil(o.OperationIds) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.OperationIds, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasOperationIds returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateImportResponse) HasOperationIds() bool {
|
||||||
|
if o != nil && !IsNil(o.OperationIds) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetOperationIds gets a reference to the given []string and assigns it to the OperationIds field.
|
||||||
|
func (o *BankTemplateImportResponse) SetOperationIds(v []string) {
|
||||||
|
o.OperationIds = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDryRun returns the DryRun field value if set, zero value otherwise.
|
||||||
|
func (o *BankTemplateImportResponse) GetDryRun() bool {
|
||||||
|
if o == nil || IsNil(o.DryRun) {
|
||||||
|
var ret bool
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.DryRun
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDryRunOk returns a tuple with the DryRun field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateImportResponse) GetDryRunOk() (*bool, bool) {
|
||||||
|
if o == nil || IsNil(o.DryRun) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.DryRun, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasDryRun returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateImportResponse) HasDryRun() bool {
|
||||||
|
if o != nil && !IsNil(o.DryRun) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDryRun gets a reference to the given bool and assigns it to the DryRun field.
|
||||||
|
func (o *BankTemplateImportResponse) SetDryRun(v bool) {
|
||||||
|
o.DryRun = &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o BankTemplateImportResponse) MarshalJSON() ([]byte, error) {
|
||||||
|
toSerialize,err := o.ToMap()
|
||||||
|
if err != nil {
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
return json.Marshal(toSerialize)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o BankTemplateImportResponse) ToMap() (map[string]interface{}, error) {
|
||||||
|
toSerialize := map[string]interface{}{}
|
||||||
|
toSerialize["bank_id"] = o.BankId
|
||||||
|
toSerialize["config_applied"] = o.ConfigApplied
|
||||||
|
if !IsNil(o.MentalModelsCreated) {
|
||||||
|
toSerialize["mental_models_created"] = o.MentalModelsCreated
|
||||||
|
}
|
||||||
|
if !IsNil(o.MentalModelsUpdated) {
|
||||||
|
toSerialize["mental_models_updated"] = o.MentalModelsUpdated
|
||||||
|
}
|
||||||
|
if !IsNil(o.DirectivesCreated) {
|
||||||
|
toSerialize["directives_created"] = o.DirectivesCreated
|
||||||
|
}
|
||||||
|
if !IsNil(o.DirectivesUpdated) {
|
||||||
|
toSerialize["directives_updated"] = o.DirectivesUpdated
|
||||||
|
}
|
||||||
|
if !IsNil(o.OperationIds) {
|
||||||
|
toSerialize["operation_ids"] = o.OperationIds
|
||||||
|
}
|
||||||
|
if !IsNil(o.DryRun) {
|
||||||
|
toSerialize["dry_run"] = o.DryRun
|
||||||
|
}
|
||||||
|
return toSerialize, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *BankTemplateImportResponse) UnmarshalJSON(data []byte) (err error) {
|
||||||
|
// This validates that all required properties are included in the JSON object
|
||||||
|
// by unmarshalling the object into a generic map with string keys and checking
|
||||||
|
// that every required field exists as a key in the generic map.
|
||||||
|
requiredProperties := []string{
|
||||||
|
"bank_id",
|
||||||
|
"config_applied",
|
||||||
|
}
|
||||||
|
|
||||||
|
allProperties := make(map[string]interface{})
|
||||||
|
|
||||||
|
err = json.Unmarshal(data, &allProperties)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, requiredProperty := range(requiredProperties) {
|
||||||
|
if _, exists := allProperties[requiredProperty]; !exists {
|
||||||
|
return fmt.Errorf("no value given for required property %v", requiredProperty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
varBankTemplateImportResponse := _BankTemplateImportResponse{}
|
||||||
|
|
||||||
|
decoder := json.NewDecoder(bytes.NewReader(data))
|
||||||
|
decoder.DisallowUnknownFields()
|
||||||
|
err = decoder.Decode(&varBankTemplateImportResponse)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*o = BankTemplateImportResponse(varBankTemplateImportResponse)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type NullableBankTemplateImportResponse struct {
|
||||||
|
value *BankTemplateImportResponse
|
||||||
|
isSet bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v NullableBankTemplateImportResponse) Get() *BankTemplateImportResponse {
|
||||||
|
return v.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *NullableBankTemplateImportResponse) Set(val *BankTemplateImportResponse) {
|
||||||
|
v.value = val
|
||||||
|
v.isSet = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v NullableBankTemplateImportResponse) IsSet() bool {
|
||||||
|
return v.isSet
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *NullableBankTemplateImportResponse) Unset() {
|
||||||
|
v.value = nil
|
||||||
|
v.isSet = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNullableBankTemplateImportResponse(val *BankTemplateImportResponse) *NullableBankTemplateImportResponse {
|
||||||
|
return &NullableBankTemplateImportResponse{value: val, isSet: true}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v NullableBankTemplateImportResponse) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(v.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *NullableBankTemplateImportResponse) UnmarshalJSON(src []byte) error {
|
||||||
|
v.isSet = true
|
||||||
|
return json.Unmarshal(src, &v.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
279
hindsight-clients/go/model_bank_template_manifest.go
Normal file
279
hindsight-clients/go/model_bank_template_manifest.go
Normal file
|
|
@ -0,0 +1,279 @@
|
||||||
|
/*
|
||||||
|
Hindsight HTTP API
|
||||||
|
|
||||||
|
HTTP API for Hindsight
|
||||||
|
|
||||||
|
API version: 0.4.22
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||||
|
|
||||||
|
package hindsight
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// checks if the BankTemplateManifest type satisfies the MappedNullable interface at compile time
|
||||||
|
var _ MappedNullable = &BankTemplateManifest{}
|
||||||
|
|
||||||
|
// BankTemplateManifest A bank template manifest for import/export. Version field enables forward-compatible schema evolution: the API auto-upgrades older manifest versions to the current schema on import.
|
||||||
|
type BankTemplateManifest struct {
|
||||||
|
// Manifest schema version (currently '1')
|
||||||
|
Version string `json:"version"`
|
||||||
|
Bank NullableBankTemplateConfig `json:"bank,omitempty"`
|
||||||
|
MentalModels []BankTemplateMentalModel `json:"mental_models,omitempty"`
|
||||||
|
Directives []BankTemplateDirective `json:"directives,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type _BankTemplateManifest BankTemplateManifest
|
||||||
|
|
||||||
|
// NewBankTemplateManifest instantiates a new BankTemplateManifest object
|
||||||
|
// This constructor will assign default values to properties that have it defined,
|
||||||
|
// and makes sure properties required by API are set, but the set of arguments
|
||||||
|
// will change when the set of required properties is changed
|
||||||
|
func NewBankTemplateManifest(version string) *BankTemplateManifest {
|
||||||
|
this := BankTemplateManifest{}
|
||||||
|
this.Version = version
|
||||||
|
return &this
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBankTemplateManifestWithDefaults instantiates a new BankTemplateManifest object
|
||||||
|
// This constructor will only assign default values to properties that have it defined,
|
||||||
|
// but it doesn't guarantee that properties required by API are set
|
||||||
|
func NewBankTemplateManifestWithDefaults() *BankTemplateManifest {
|
||||||
|
this := BankTemplateManifest{}
|
||||||
|
return &this
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetVersion returns the Version field value
|
||||||
|
func (o *BankTemplateManifest) GetVersion() string {
|
||||||
|
if o == nil {
|
||||||
|
var ret string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.Version
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetVersionOk returns a tuple with the Version field value
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateManifest) GetVersionOk() (*string, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return &o.Version, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetVersion sets field value
|
||||||
|
func (o *BankTemplateManifest) SetVersion(v string) {
|
||||||
|
o.Version = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBank returns the Bank field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
|
func (o *BankTemplateManifest) GetBank() BankTemplateConfig {
|
||||||
|
if o == nil || IsNil(o.Bank.Get()) {
|
||||||
|
var ret BankTemplateConfig
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.Bank.Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBankOk returns a tuple with the Bank field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
|
func (o *BankTemplateManifest) GetBankOk() (*BankTemplateConfig, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.Bank.Get(), o.Bank.IsSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasBank returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateManifest) HasBank() bool {
|
||||||
|
if o != nil && o.Bank.IsSet() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBank gets a reference to the given NullableBankTemplateConfig and assigns it to the Bank field.
|
||||||
|
func (o *BankTemplateManifest) SetBank(v BankTemplateConfig) {
|
||||||
|
o.Bank.Set(&v)
|
||||||
|
}
|
||||||
|
// SetBankNil sets the value for Bank to be an explicit nil
|
||||||
|
func (o *BankTemplateManifest) SetBankNil() {
|
||||||
|
o.Bank.Set(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnsetBank ensures that no value is present for Bank, not even an explicit nil
|
||||||
|
func (o *BankTemplateManifest) UnsetBank() {
|
||||||
|
o.Bank.Unset()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMentalModels returns the MentalModels field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
|
func (o *BankTemplateManifest) GetMentalModels() []BankTemplateMentalModel {
|
||||||
|
if o == nil {
|
||||||
|
var ret []BankTemplateMentalModel
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return o.MentalModels
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMentalModelsOk returns a tuple with the MentalModels field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
|
func (o *BankTemplateManifest) GetMentalModelsOk() ([]BankTemplateMentalModel, bool) {
|
||||||
|
if o == nil || IsNil(o.MentalModels) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.MentalModels, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasMentalModels returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateManifest) HasMentalModels() bool {
|
||||||
|
if o != nil && !IsNil(o.MentalModels) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMentalModels gets a reference to the given []BankTemplateMentalModel and assigns it to the MentalModels field.
|
||||||
|
func (o *BankTemplateManifest) SetMentalModels(v []BankTemplateMentalModel) {
|
||||||
|
o.MentalModels = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDirectives returns the Directives field value if set, zero value otherwise (both if not set or set to explicit null).
|
||||||
|
func (o *BankTemplateManifest) GetDirectives() []BankTemplateDirective {
|
||||||
|
if o == nil {
|
||||||
|
var ret []BankTemplateDirective
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return o.Directives
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDirectivesOk returns a tuple with the Directives field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
// NOTE: If the value is an explicit nil, `nil, true` will be returned
|
||||||
|
func (o *BankTemplateManifest) GetDirectivesOk() ([]BankTemplateDirective, bool) {
|
||||||
|
if o == nil || IsNil(o.Directives) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.Directives, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasDirectives returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateManifest) HasDirectives() bool {
|
||||||
|
if o != nil && !IsNil(o.Directives) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDirectives gets a reference to the given []BankTemplateDirective and assigns it to the Directives field.
|
||||||
|
func (o *BankTemplateManifest) SetDirectives(v []BankTemplateDirective) {
|
||||||
|
o.Directives = v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o BankTemplateManifest) MarshalJSON() ([]byte, error) {
|
||||||
|
toSerialize,err := o.ToMap()
|
||||||
|
if err != nil {
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
return json.Marshal(toSerialize)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o BankTemplateManifest) ToMap() (map[string]interface{}, error) {
|
||||||
|
toSerialize := map[string]interface{}{}
|
||||||
|
toSerialize["version"] = o.Version
|
||||||
|
if o.Bank.IsSet() {
|
||||||
|
toSerialize["bank"] = o.Bank.Get()
|
||||||
|
}
|
||||||
|
if o.MentalModels != nil {
|
||||||
|
toSerialize["mental_models"] = o.MentalModels
|
||||||
|
}
|
||||||
|
if o.Directives != nil {
|
||||||
|
toSerialize["directives"] = o.Directives
|
||||||
|
}
|
||||||
|
return toSerialize, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *BankTemplateManifest) UnmarshalJSON(data []byte) (err error) {
|
||||||
|
// This validates that all required properties are included in the JSON object
|
||||||
|
// by unmarshalling the object into a generic map with string keys and checking
|
||||||
|
// that every required field exists as a key in the generic map.
|
||||||
|
requiredProperties := []string{
|
||||||
|
"version",
|
||||||
|
}
|
||||||
|
|
||||||
|
allProperties := make(map[string]interface{})
|
||||||
|
|
||||||
|
err = json.Unmarshal(data, &allProperties)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, requiredProperty := range(requiredProperties) {
|
||||||
|
if _, exists := allProperties[requiredProperty]; !exists {
|
||||||
|
return fmt.Errorf("no value given for required property %v", requiredProperty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
varBankTemplateManifest := _BankTemplateManifest{}
|
||||||
|
|
||||||
|
decoder := json.NewDecoder(bytes.NewReader(data))
|
||||||
|
decoder.DisallowUnknownFields()
|
||||||
|
err = decoder.Decode(&varBankTemplateManifest)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*o = BankTemplateManifest(varBankTemplateManifest)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type NullableBankTemplateManifest struct {
|
||||||
|
value *BankTemplateManifest
|
||||||
|
isSet bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v NullableBankTemplateManifest) Get() *BankTemplateManifest {
|
||||||
|
return v.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *NullableBankTemplateManifest) Set(val *BankTemplateManifest) {
|
||||||
|
v.value = val
|
||||||
|
v.isSet = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v NullableBankTemplateManifest) IsSet() bool {
|
||||||
|
return v.isSet
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *NullableBankTemplateManifest) Unset() {
|
||||||
|
v.value = nil
|
||||||
|
v.isSet = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNullableBankTemplateManifest(val *BankTemplateManifest) *NullableBankTemplateManifest {
|
||||||
|
return &NullableBankTemplateManifest{value: val, isSet: true}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v NullableBankTemplateManifest) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(v.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *NullableBankTemplateManifest) UnmarshalJSON(src []byte) error {
|
||||||
|
v.isSet = true
|
||||||
|
return json.Unmarshal(src, &v.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
332
hindsight-clients/go/model_bank_template_mental_model.go
Normal file
332
hindsight-clients/go/model_bank_template_mental_model.go
Normal file
|
|
@ -0,0 +1,332 @@
|
||||||
|
/*
|
||||||
|
Hindsight HTTP API
|
||||||
|
|
||||||
|
HTTP API for Hindsight
|
||||||
|
|
||||||
|
API version: 0.4.22
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
||||||
|
|
||||||
|
package hindsight
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// checks if the BankTemplateMentalModel type satisfies the MappedNullable interface at compile time
|
||||||
|
var _ MappedNullable = &BankTemplateMentalModel{}
|
||||||
|
|
||||||
|
// BankTemplateMentalModel A mental model definition within a bank template manifest.
|
||||||
|
type BankTemplateMentalModel struct {
|
||||||
|
// Unique ID for the mental model (alphanumeric lowercase with hyphens)
|
||||||
|
Id string `json:"id"`
|
||||||
|
// Human-readable name for the mental model
|
||||||
|
Name string `json:"name"`
|
||||||
|
// The query to run to generate content
|
||||||
|
SourceQuery string `json:"source_query"`
|
||||||
|
// Tags for scoped visibility
|
||||||
|
Tags []string `json:"tags,omitempty"`
|
||||||
|
// Maximum tokens for generated content
|
||||||
|
MaxTokens *int32 `json:"max_tokens,omitempty"`
|
||||||
|
// Trigger settings
|
||||||
|
Trigger *MentalModelTriggerOutput `json:"trigger,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type _BankTemplateMentalModel BankTemplateMentalModel
|
||||||
|
|
||||||
|
// NewBankTemplateMentalModel instantiates a new BankTemplateMentalModel object
|
||||||
|
// This constructor will assign default values to properties that have it defined,
|
||||||
|
// and makes sure properties required by API are set, but the set of arguments
|
||||||
|
// will change when the set of required properties is changed
|
||||||
|
func NewBankTemplateMentalModel(id string, name string, sourceQuery string) *BankTemplateMentalModel {
|
||||||
|
this := BankTemplateMentalModel{}
|
||||||
|
this.Id = id
|
||||||
|
this.Name = name
|
||||||
|
this.SourceQuery = sourceQuery
|
||||||
|
var maxTokens int32 = 2048
|
||||||
|
this.MaxTokens = &maxTokens
|
||||||
|
return &this
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBankTemplateMentalModelWithDefaults instantiates a new BankTemplateMentalModel object
|
||||||
|
// This constructor will only assign default values to properties that have it defined,
|
||||||
|
// but it doesn't guarantee that properties required by API are set
|
||||||
|
func NewBankTemplateMentalModelWithDefaults() *BankTemplateMentalModel {
|
||||||
|
this := BankTemplateMentalModel{}
|
||||||
|
var maxTokens int32 = 2048
|
||||||
|
this.MaxTokens = &maxTokens
|
||||||
|
return &this
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetId returns the Id field value
|
||||||
|
func (o *BankTemplateMentalModel) GetId() string {
|
||||||
|
if o == nil {
|
||||||
|
var ret string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.Id
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetIdOk returns a tuple with the Id field value
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateMentalModel) GetIdOk() (*string, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return &o.Id, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetId sets field value
|
||||||
|
func (o *BankTemplateMentalModel) SetId(v string) {
|
||||||
|
o.Id = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetName returns the Name field value
|
||||||
|
func (o *BankTemplateMentalModel) GetName() string {
|
||||||
|
if o == nil {
|
||||||
|
var ret string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetNameOk returns a tuple with the Name field value
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateMentalModel) GetNameOk() (*string, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return &o.Name, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetName sets field value
|
||||||
|
func (o *BankTemplateMentalModel) SetName(v string) {
|
||||||
|
o.Name = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSourceQuery returns the SourceQuery field value
|
||||||
|
func (o *BankTemplateMentalModel) GetSourceQuery() string {
|
||||||
|
if o == nil {
|
||||||
|
var ret string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
return o.SourceQuery
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSourceQueryOk returns a tuple with the SourceQuery field value
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateMentalModel) GetSourceQueryOk() (*string, bool) {
|
||||||
|
if o == nil {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return &o.SourceQuery, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSourceQuery sets field value
|
||||||
|
func (o *BankTemplateMentalModel) SetSourceQuery(v string) {
|
||||||
|
o.SourceQuery = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTags returns the Tags field value if set, zero value otherwise.
|
||||||
|
func (o *BankTemplateMentalModel) GetTags() []string {
|
||||||
|
if o == nil || IsNil(o.Tags) {
|
||||||
|
var ret []string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return o.Tags
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTagsOk returns a tuple with the Tags field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateMentalModel) GetTagsOk() ([]string, bool) {
|
||||||
|
if o == nil || IsNil(o.Tags) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.Tags, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasTags returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateMentalModel) HasTags() bool {
|
||||||
|
if o != nil && !IsNil(o.Tags) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTags gets a reference to the given []string and assigns it to the Tags field.
|
||||||
|
func (o *BankTemplateMentalModel) SetTags(v []string) {
|
||||||
|
o.Tags = v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMaxTokens returns the MaxTokens field value if set, zero value otherwise.
|
||||||
|
func (o *BankTemplateMentalModel) GetMaxTokens() int32 {
|
||||||
|
if o == nil || IsNil(o.MaxTokens) {
|
||||||
|
var ret int32
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.MaxTokens
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMaxTokensOk returns a tuple with the MaxTokens field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateMentalModel) GetMaxTokensOk() (*int32, bool) {
|
||||||
|
if o == nil || IsNil(o.MaxTokens) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.MaxTokens, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasMaxTokens returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateMentalModel) HasMaxTokens() bool {
|
||||||
|
if o != nil && !IsNil(o.MaxTokens) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetMaxTokens gets a reference to the given int32 and assigns it to the MaxTokens field.
|
||||||
|
func (o *BankTemplateMentalModel) SetMaxTokens(v int32) {
|
||||||
|
o.MaxTokens = &v
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTrigger returns the Trigger field value if set, zero value otherwise.
|
||||||
|
func (o *BankTemplateMentalModel) GetTrigger() MentalModelTriggerOutput {
|
||||||
|
if o == nil || IsNil(o.Trigger) {
|
||||||
|
var ret MentalModelTriggerOutput
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.Trigger
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTriggerOk returns a tuple with the Trigger field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *BankTemplateMentalModel) GetTriggerOk() (*MentalModelTriggerOutput, bool) {
|
||||||
|
if o == nil || IsNil(o.Trigger) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.Trigger, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasTrigger returns a boolean if a field has been set.
|
||||||
|
func (o *BankTemplateMentalModel) HasTrigger() bool {
|
||||||
|
if o != nil && !IsNil(o.Trigger) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTrigger gets a reference to the given MentalModelTriggerOutput and assigns it to the Trigger field.
|
||||||
|
func (o *BankTemplateMentalModel) SetTrigger(v MentalModelTriggerOutput) {
|
||||||
|
o.Trigger = &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o BankTemplateMentalModel) MarshalJSON() ([]byte, error) {
|
||||||
|
toSerialize,err := o.ToMap()
|
||||||
|
if err != nil {
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
return json.Marshal(toSerialize)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o BankTemplateMentalModel) ToMap() (map[string]interface{}, error) {
|
||||||
|
toSerialize := map[string]interface{}{}
|
||||||
|
toSerialize["id"] = o.Id
|
||||||
|
toSerialize["name"] = o.Name
|
||||||
|
toSerialize["source_query"] = o.SourceQuery
|
||||||
|
if !IsNil(o.Tags) {
|
||||||
|
toSerialize["tags"] = o.Tags
|
||||||
|
}
|
||||||
|
if !IsNil(o.MaxTokens) {
|
||||||
|
toSerialize["max_tokens"] = o.MaxTokens
|
||||||
|
}
|
||||||
|
if !IsNil(o.Trigger) {
|
||||||
|
toSerialize["trigger"] = o.Trigger
|
||||||
|
}
|
||||||
|
return toSerialize, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *BankTemplateMentalModel) UnmarshalJSON(data []byte) (err error) {
|
||||||
|
// This validates that all required properties are included in the JSON object
|
||||||
|
// by unmarshalling the object into a generic map with string keys and checking
|
||||||
|
// that every required field exists as a key in the generic map.
|
||||||
|
requiredProperties := []string{
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"source_query",
|
||||||
|
}
|
||||||
|
|
||||||
|
allProperties := make(map[string]interface{})
|
||||||
|
|
||||||
|
err = json.Unmarshal(data, &allProperties)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, requiredProperty := range(requiredProperties) {
|
||||||
|
if _, exists := allProperties[requiredProperty]; !exists {
|
||||||
|
return fmt.Errorf("no value given for required property %v", requiredProperty)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
varBankTemplateMentalModel := _BankTemplateMentalModel{}
|
||||||
|
|
||||||
|
decoder := json.NewDecoder(bytes.NewReader(data))
|
||||||
|
decoder.DisallowUnknownFields()
|
||||||
|
err = decoder.Decode(&varBankTemplateMentalModel)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*o = BankTemplateMentalModel(varBankTemplateMentalModel)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type NullableBankTemplateMentalModel struct {
|
||||||
|
value *BankTemplateMentalModel
|
||||||
|
isSet bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v NullableBankTemplateMentalModel) Get() *BankTemplateMentalModel {
|
||||||
|
return v.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *NullableBankTemplateMentalModel) Set(val *BankTemplateMentalModel) {
|
||||||
|
v.value = val
|
||||||
|
v.isSet = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v NullableBankTemplateMentalModel) IsSet() bool {
|
||||||
|
return v.isSet
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *NullableBankTemplateMentalModel) Unset() {
|
||||||
|
v.value = nil
|
||||||
|
v.isSet = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNullableBankTemplateMentalModel(val *BankTemplateMentalModel) *NullableBankTemplateMentalModel {
|
||||||
|
return &NullableBankTemplateMentalModel{value: val, isSet: true}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v NullableBankTemplateMentalModel) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(v.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *NullableBankTemplateMentalModel) UnmarshalJSON(src []byte) error {
|
||||||
|
v.isSet = true
|
||||||
|
return json.Unmarshal(src, &v.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
hindsight_client_api/__init__.py
|
hindsight_client_api/__init__.py
|
||||||
hindsight_client_api/api/__init__.py
|
hindsight_client_api/api/__init__.py
|
||||||
hindsight_client_api/api/audit_api.py
|
hindsight_client_api/api/audit_api.py
|
||||||
|
hindsight_client_api/api/bank_templates_api.py
|
||||||
hindsight_client_api/api/banks_api.py
|
hindsight_client_api/api/banks_api.py
|
||||||
hindsight_client_api/api/directives_api.py
|
hindsight_client_api/api/directives_api.py
|
||||||
hindsight_client_api/api/documents_api.py
|
hindsight_client_api/api/documents_api.py
|
||||||
|
|
@ -29,6 +30,11 @@ hindsight_client_api/models/bank_list_item.py
|
||||||
hindsight_client_api/models/bank_list_response.py
|
hindsight_client_api/models/bank_list_response.py
|
||||||
hindsight_client_api/models/bank_profile_response.py
|
hindsight_client_api/models/bank_profile_response.py
|
||||||
hindsight_client_api/models/bank_stats_response.py
|
hindsight_client_api/models/bank_stats_response.py
|
||||||
|
hindsight_client_api/models/bank_template_config.py
|
||||||
|
hindsight_client_api/models/bank_template_directive.py
|
||||||
|
hindsight_client_api/models/bank_template_import_response.py
|
||||||
|
hindsight_client_api/models/bank_template_manifest.py
|
||||||
|
hindsight_client_api/models/bank_template_mental_model.py
|
||||||
hindsight_client_api/models/budget.py
|
hindsight_client_api/models/budget.py
|
||||||
hindsight_client_api/models/cancel_operation_response.py
|
hindsight_client_api/models/cancel_operation_response.py
|
||||||
hindsight_client_api/models/child_operation_status.py
|
hindsight_client_api/models/child_operation_status.py
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ __version__ = "0.0.7"
|
||||||
|
|
||||||
# import apis into sdk package
|
# import apis into sdk package
|
||||||
from hindsight_client_api.api.audit_api import AuditApi
|
from hindsight_client_api.api.audit_api import AuditApi
|
||||||
|
from hindsight_client_api.api.bank_templates_api import BankTemplatesApi
|
||||||
from hindsight_client_api.api.banks_api import BanksApi
|
from hindsight_client_api.api.banks_api import BanksApi
|
||||||
from hindsight_client_api.api.directives_api import DirectivesApi
|
from hindsight_client_api.api.directives_api import DirectivesApi
|
||||||
from hindsight_client_api.api.documents_api import DocumentsApi
|
from hindsight_client_api.api.documents_api import DocumentsApi
|
||||||
|
|
@ -54,6 +55,11 @@ from hindsight_client_api.models.bank_list_item import BankListItem
|
||||||
from hindsight_client_api.models.bank_list_response import BankListResponse
|
from hindsight_client_api.models.bank_list_response import BankListResponse
|
||||||
from hindsight_client_api.models.bank_profile_response import BankProfileResponse
|
from hindsight_client_api.models.bank_profile_response import BankProfileResponse
|
||||||
from hindsight_client_api.models.bank_stats_response import BankStatsResponse
|
from hindsight_client_api.models.bank_stats_response import BankStatsResponse
|
||||||
|
from hindsight_client_api.models.bank_template_config import BankTemplateConfig
|
||||||
|
from hindsight_client_api.models.bank_template_directive import BankTemplateDirective
|
||||||
|
from hindsight_client_api.models.bank_template_import_response import BankTemplateImportResponse
|
||||||
|
from hindsight_client_api.models.bank_template_manifest import BankTemplateManifest
|
||||||
|
from hindsight_client_api.models.bank_template_mental_model import BankTemplateMentalModel
|
||||||
from hindsight_client_api.models.budget import Budget
|
from hindsight_client_api.models.budget import Budget
|
||||||
from hindsight_client_api.models.cancel_operation_response import CancelOperationResponse
|
from hindsight_client_api.models.cancel_operation_response import CancelOperationResponse
|
||||||
from hindsight_client_api.models.child_operation_status import ChildOperationStatus
|
from hindsight_client_api.models.child_operation_status import ChildOperationStatus
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
# import apis into api package
|
# import apis into api package
|
||||||
from hindsight_client_api.api.audit_api import AuditApi
|
from hindsight_client_api.api.audit_api import AuditApi
|
||||||
|
from hindsight_client_api.api.bank_templates_api import BankTemplatesApi
|
||||||
from hindsight_client_api.api.banks_api import BanksApi
|
from hindsight_client_api.api.banks_api import BanksApi
|
||||||
from hindsight_client_api.api.directives_api import DirectivesApi
|
from hindsight_client_api.api.directives_api import DirectivesApi
|
||||||
from hindsight_client_api.api.documents_api import DocumentsApi
|
from hindsight_client_api.api.documents_api import DocumentsApi
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,858 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
"""
|
||||||
|
Hindsight HTTP API
|
||||||
|
|
||||||
|
HTTP API for Hindsight
|
||||||
|
|
||||||
|
The version of the OpenAPI document: 0.4.22
|
||||||
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||||
|
|
||||||
|
Do not edit the class manually.
|
||||||
|
""" # noqa: E501
|
||||||
|
|
||||||
|
import warnings
|
||||||
|
from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt
|
||||||
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
||||||
|
from typing_extensions import Annotated
|
||||||
|
|
||||||
|
from pydantic import Field, StrictBool, StrictStr
|
||||||
|
from typing import Any, Optional
|
||||||
|
from typing_extensions import Annotated
|
||||||
|
from hindsight_client_api.models.bank_template_import_response import BankTemplateImportResponse
|
||||||
|
from hindsight_client_api.models.bank_template_manifest import BankTemplateManifest
|
||||||
|
|
||||||
|
from hindsight_client_api.api_client import ApiClient, RequestSerialized
|
||||||
|
from hindsight_client_api.api_response import ApiResponse
|
||||||
|
from hindsight_client_api.rest import RESTResponseType
|
||||||
|
|
||||||
|
|
||||||
|
class BankTemplatesApi:
|
||||||
|
"""NOTE: This class is auto generated by OpenAPI Generator
|
||||||
|
Ref: https://openapi-generator.tech
|
||||||
|
|
||||||
|
Do not edit the class manually.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, api_client=None) -> None:
|
||||||
|
if api_client is None:
|
||||||
|
api_client = ApiClient.get_default()
|
||||||
|
self.api_client = api_client
|
||||||
|
|
||||||
|
|
||||||
|
@validate_call
|
||||||
|
async def export_bank_template(
|
||||||
|
self,
|
||||||
|
bank_id: StrictStr,
|
||||||
|
authorization: Optional[StrictStr] = None,
|
||||||
|
_request_timeout: Union[
|
||||||
|
None,
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Tuple[
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Annotated[StrictFloat, Field(gt=0)]
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_content_type: Optional[StrictStr] = None,
|
||||||
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
||||||
|
) -> BankTemplateManifest:
|
||||||
|
"""Export bank template
|
||||||
|
|
||||||
|
Export a bank's current configuration, mental models, and directives as a template manifest. The exported manifest can be imported into another bank to replicate the setup.
|
||||||
|
|
||||||
|
:param bank_id: (required)
|
||||||
|
:type bank_id: str
|
||||||
|
:param authorization:
|
||||||
|
:type authorization: str
|
||||||
|
:param _request_timeout: timeout setting for this request. If one
|
||||||
|
number provided, it will be total request
|
||||||
|
timeout. It can also be a pair (tuple) of
|
||||||
|
(connection, read) timeouts.
|
||||||
|
:type _request_timeout: int, tuple(int, int), optional
|
||||||
|
:param _request_auth: set to override the auth_settings for an a single
|
||||||
|
request; this effectively ignores the
|
||||||
|
authentication in the spec for a single request.
|
||||||
|
:type _request_auth: dict, optional
|
||||||
|
:param _content_type: force content-type for the request.
|
||||||
|
:type _content_type: str, Optional
|
||||||
|
:param _headers: set to override the headers for a single
|
||||||
|
request; this effectively ignores the headers
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _headers: dict, optional
|
||||||
|
:param _host_index: set to override the host_index for a single
|
||||||
|
request; this effectively ignores the host_index
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _host_index: int, optional
|
||||||
|
:return: Returns the result object.
|
||||||
|
""" # noqa: E501
|
||||||
|
|
||||||
|
_param = self._export_bank_template_serialize(
|
||||||
|
bank_id=bank_id,
|
||||||
|
authorization=authorization,
|
||||||
|
_request_auth=_request_auth,
|
||||||
|
_content_type=_content_type,
|
||||||
|
_headers=_headers,
|
||||||
|
_host_index=_host_index
|
||||||
|
)
|
||||||
|
|
||||||
|
_response_types_map: Dict[str, Optional[str]] = {
|
||||||
|
'200': "BankTemplateManifest",
|
||||||
|
'422': "HTTPValidationError",
|
||||||
|
}
|
||||||
|
response_data = await self.api_client.call_api(
|
||||||
|
*_param,
|
||||||
|
_request_timeout=_request_timeout
|
||||||
|
)
|
||||||
|
await response_data.read()
|
||||||
|
return self.api_client.response_deserialize(
|
||||||
|
response_data=response_data,
|
||||||
|
response_types_map=_response_types_map,
|
||||||
|
).data
|
||||||
|
|
||||||
|
|
||||||
|
@validate_call
|
||||||
|
async def export_bank_template_with_http_info(
|
||||||
|
self,
|
||||||
|
bank_id: StrictStr,
|
||||||
|
authorization: Optional[StrictStr] = None,
|
||||||
|
_request_timeout: Union[
|
||||||
|
None,
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Tuple[
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Annotated[StrictFloat, Field(gt=0)]
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_content_type: Optional[StrictStr] = None,
|
||||||
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
||||||
|
) -> ApiResponse[BankTemplateManifest]:
|
||||||
|
"""Export bank template
|
||||||
|
|
||||||
|
Export a bank's current configuration, mental models, and directives as a template manifest. The exported manifest can be imported into another bank to replicate the setup.
|
||||||
|
|
||||||
|
:param bank_id: (required)
|
||||||
|
:type bank_id: str
|
||||||
|
:param authorization:
|
||||||
|
:type authorization: str
|
||||||
|
:param _request_timeout: timeout setting for this request. If one
|
||||||
|
number provided, it will be total request
|
||||||
|
timeout. It can also be a pair (tuple) of
|
||||||
|
(connection, read) timeouts.
|
||||||
|
:type _request_timeout: int, tuple(int, int), optional
|
||||||
|
:param _request_auth: set to override the auth_settings for an a single
|
||||||
|
request; this effectively ignores the
|
||||||
|
authentication in the spec for a single request.
|
||||||
|
:type _request_auth: dict, optional
|
||||||
|
:param _content_type: force content-type for the request.
|
||||||
|
:type _content_type: str, Optional
|
||||||
|
:param _headers: set to override the headers for a single
|
||||||
|
request; this effectively ignores the headers
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _headers: dict, optional
|
||||||
|
:param _host_index: set to override the host_index for a single
|
||||||
|
request; this effectively ignores the host_index
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _host_index: int, optional
|
||||||
|
:return: Returns the result object.
|
||||||
|
""" # noqa: E501
|
||||||
|
|
||||||
|
_param = self._export_bank_template_serialize(
|
||||||
|
bank_id=bank_id,
|
||||||
|
authorization=authorization,
|
||||||
|
_request_auth=_request_auth,
|
||||||
|
_content_type=_content_type,
|
||||||
|
_headers=_headers,
|
||||||
|
_host_index=_host_index
|
||||||
|
)
|
||||||
|
|
||||||
|
_response_types_map: Dict[str, Optional[str]] = {
|
||||||
|
'200': "BankTemplateManifest",
|
||||||
|
'422': "HTTPValidationError",
|
||||||
|
}
|
||||||
|
response_data = await self.api_client.call_api(
|
||||||
|
*_param,
|
||||||
|
_request_timeout=_request_timeout
|
||||||
|
)
|
||||||
|
await response_data.read()
|
||||||
|
return self.api_client.response_deserialize(
|
||||||
|
response_data=response_data,
|
||||||
|
response_types_map=_response_types_map,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@validate_call
|
||||||
|
async def export_bank_template_without_preload_content(
|
||||||
|
self,
|
||||||
|
bank_id: StrictStr,
|
||||||
|
authorization: Optional[StrictStr] = None,
|
||||||
|
_request_timeout: Union[
|
||||||
|
None,
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Tuple[
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Annotated[StrictFloat, Field(gt=0)]
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_content_type: Optional[StrictStr] = None,
|
||||||
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
||||||
|
) -> RESTResponseType:
|
||||||
|
"""Export bank template
|
||||||
|
|
||||||
|
Export a bank's current configuration, mental models, and directives as a template manifest. The exported manifest can be imported into another bank to replicate the setup.
|
||||||
|
|
||||||
|
:param bank_id: (required)
|
||||||
|
:type bank_id: str
|
||||||
|
:param authorization:
|
||||||
|
:type authorization: str
|
||||||
|
:param _request_timeout: timeout setting for this request. If one
|
||||||
|
number provided, it will be total request
|
||||||
|
timeout. It can also be a pair (tuple) of
|
||||||
|
(connection, read) timeouts.
|
||||||
|
:type _request_timeout: int, tuple(int, int), optional
|
||||||
|
:param _request_auth: set to override the auth_settings for an a single
|
||||||
|
request; this effectively ignores the
|
||||||
|
authentication in the spec for a single request.
|
||||||
|
:type _request_auth: dict, optional
|
||||||
|
:param _content_type: force content-type for the request.
|
||||||
|
:type _content_type: str, Optional
|
||||||
|
:param _headers: set to override the headers for a single
|
||||||
|
request; this effectively ignores the headers
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _headers: dict, optional
|
||||||
|
:param _host_index: set to override the host_index for a single
|
||||||
|
request; this effectively ignores the host_index
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _host_index: int, optional
|
||||||
|
:return: Returns the result object.
|
||||||
|
""" # noqa: E501
|
||||||
|
|
||||||
|
_param = self._export_bank_template_serialize(
|
||||||
|
bank_id=bank_id,
|
||||||
|
authorization=authorization,
|
||||||
|
_request_auth=_request_auth,
|
||||||
|
_content_type=_content_type,
|
||||||
|
_headers=_headers,
|
||||||
|
_host_index=_host_index
|
||||||
|
)
|
||||||
|
|
||||||
|
_response_types_map: Dict[str, Optional[str]] = {
|
||||||
|
'200': "BankTemplateManifest",
|
||||||
|
'422': "HTTPValidationError",
|
||||||
|
}
|
||||||
|
response_data = await self.api_client.call_api(
|
||||||
|
*_param,
|
||||||
|
_request_timeout=_request_timeout
|
||||||
|
)
|
||||||
|
return response_data.response
|
||||||
|
|
||||||
|
|
||||||
|
def _export_bank_template_serialize(
|
||||||
|
self,
|
||||||
|
bank_id,
|
||||||
|
authorization,
|
||||||
|
_request_auth,
|
||||||
|
_content_type,
|
||||||
|
_headers,
|
||||||
|
_host_index,
|
||||||
|
) -> RequestSerialized:
|
||||||
|
|
||||||
|
_host = None
|
||||||
|
|
||||||
|
_collection_formats: Dict[str, str] = {
|
||||||
|
}
|
||||||
|
|
||||||
|
_path_params: Dict[str, str] = {}
|
||||||
|
_query_params: List[Tuple[str, str]] = []
|
||||||
|
_header_params: Dict[str, Optional[str]] = _headers or {}
|
||||||
|
_form_params: List[Tuple[str, str]] = []
|
||||||
|
_files: Dict[
|
||||||
|
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
|
||||||
|
] = {}
|
||||||
|
_body_params: Optional[bytes] = None
|
||||||
|
|
||||||
|
# process the path parameters
|
||||||
|
if bank_id is not None:
|
||||||
|
_path_params['bank_id'] = bank_id
|
||||||
|
# process the query parameters
|
||||||
|
# process the header parameters
|
||||||
|
if authorization is not None:
|
||||||
|
_header_params['authorization'] = authorization
|
||||||
|
# process the form parameters
|
||||||
|
# process the body parameter
|
||||||
|
|
||||||
|
|
||||||
|
# set the HTTP header `Accept`
|
||||||
|
if 'Accept' not in _header_params:
|
||||||
|
_header_params['Accept'] = self.api_client.select_header_accept(
|
||||||
|
[
|
||||||
|
'application/json'
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# authentication setting
|
||||||
|
_auth_settings: List[str] = [
|
||||||
|
]
|
||||||
|
|
||||||
|
return self.api_client.param_serialize(
|
||||||
|
method='GET',
|
||||||
|
resource_path='/v1/default/banks/{bank_id}/export',
|
||||||
|
path_params=_path_params,
|
||||||
|
query_params=_query_params,
|
||||||
|
header_params=_header_params,
|
||||||
|
body=_body_params,
|
||||||
|
post_params=_form_params,
|
||||||
|
files=_files,
|
||||||
|
auth_settings=_auth_settings,
|
||||||
|
collection_formats=_collection_formats,
|
||||||
|
_host=_host,
|
||||||
|
_request_auth=_request_auth
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@validate_call
|
||||||
|
async def get_bank_template_schema(
|
||||||
|
self,
|
||||||
|
_request_timeout: Union[
|
||||||
|
None,
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Tuple[
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Annotated[StrictFloat, Field(gt=0)]
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_content_type: Optional[StrictStr] = None,
|
||||||
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
||||||
|
) -> object:
|
||||||
|
"""Get bank template JSON Schema
|
||||||
|
|
||||||
|
Returns the JSON Schema for the bank template manifest format. Use this to validate template manifests before importing.
|
||||||
|
|
||||||
|
:param _request_timeout: timeout setting for this request. If one
|
||||||
|
number provided, it will be total request
|
||||||
|
timeout. It can also be a pair (tuple) of
|
||||||
|
(connection, read) timeouts.
|
||||||
|
:type _request_timeout: int, tuple(int, int), optional
|
||||||
|
:param _request_auth: set to override the auth_settings for an a single
|
||||||
|
request; this effectively ignores the
|
||||||
|
authentication in the spec for a single request.
|
||||||
|
:type _request_auth: dict, optional
|
||||||
|
:param _content_type: force content-type for the request.
|
||||||
|
:type _content_type: str, Optional
|
||||||
|
:param _headers: set to override the headers for a single
|
||||||
|
request; this effectively ignores the headers
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _headers: dict, optional
|
||||||
|
:param _host_index: set to override the host_index for a single
|
||||||
|
request; this effectively ignores the host_index
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _host_index: int, optional
|
||||||
|
:return: Returns the result object.
|
||||||
|
""" # noqa: E501
|
||||||
|
|
||||||
|
_param = self._get_bank_template_schema_serialize(
|
||||||
|
_request_auth=_request_auth,
|
||||||
|
_content_type=_content_type,
|
||||||
|
_headers=_headers,
|
||||||
|
_host_index=_host_index
|
||||||
|
)
|
||||||
|
|
||||||
|
_response_types_map: Dict[str, Optional[str]] = {
|
||||||
|
'200': "object",
|
||||||
|
}
|
||||||
|
response_data = await self.api_client.call_api(
|
||||||
|
*_param,
|
||||||
|
_request_timeout=_request_timeout
|
||||||
|
)
|
||||||
|
await response_data.read()
|
||||||
|
return self.api_client.response_deserialize(
|
||||||
|
response_data=response_data,
|
||||||
|
response_types_map=_response_types_map,
|
||||||
|
).data
|
||||||
|
|
||||||
|
|
||||||
|
@validate_call
|
||||||
|
async def get_bank_template_schema_with_http_info(
|
||||||
|
self,
|
||||||
|
_request_timeout: Union[
|
||||||
|
None,
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Tuple[
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Annotated[StrictFloat, Field(gt=0)]
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_content_type: Optional[StrictStr] = None,
|
||||||
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
||||||
|
) -> ApiResponse[object]:
|
||||||
|
"""Get bank template JSON Schema
|
||||||
|
|
||||||
|
Returns the JSON Schema for the bank template manifest format. Use this to validate template manifests before importing.
|
||||||
|
|
||||||
|
:param _request_timeout: timeout setting for this request. If one
|
||||||
|
number provided, it will be total request
|
||||||
|
timeout. It can also be a pair (tuple) of
|
||||||
|
(connection, read) timeouts.
|
||||||
|
:type _request_timeout: int, tuple(int, int), optional
|
||||||
|
:param _request_auth: set to override the auth_settings for an a single
|
||||||
|
request; this effectively ignores the
|
||||||
|
authentication in the spec for a single request.
|
||||||
|
:type _request_auth: dict, optional
|
||||||
|
:param _content_type: force content-type for the request.
|
||||||
|
:type _content_type: str, Optional
|
||||||
|
:param _headers: set to override the headers for a single
|
||||||
|
request; this effectively ignores the headers
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _headers: dict, optional
|
||||||
|
:param _host_index: set to override the host_index for a single
|
||||||
|
request; this effectively ignores the host_index
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _host_index: int, optional
|
||||||
|
:return: Returns the result object.
|
||||||
|
""" # noqa: E501
|
||||||
|
|
||||||
|
_param = self._get_bank_template_schema_serialize(
|
||||||
|
_request_auth=_request_auth,
|
||||||
|
_content_type=_content_type,
|
||||||
|
_headers=_headers,
|
||||||
|
_host_index=_host_index
|
||||||
|
)
|
||||||
|
|
||||||
|
_response_types_map: Dict[str, Optional[str]] = {
|
||||||
|
'200': "object",
|
||||||
|
}
|
||||||
|
response_data = await self.api_client.call_api(
|
||||||
|
*_param,
|
||||||
|
_request_timeout=_request_timeout
|
||||||
|
)
|
||||||
|
await response_data.read()
|
||||||
|
return self.api_client.response_deserialize(
|
||||||
|
response_data=response_data,
|
||||||
|
response_types_map=_response_types_map,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@validate_call
|
||||||
|
async def get_bank_template_schema_without_preload_content(
|
||||||
|
self,
|
||||||
|
_request_timeout: Union[
|
||||||
|
None,
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Tuple[
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Annotated[StrictFloat, Field(gt=0)]
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_content_type: Optional[StrictStr] = None,
|
||||||
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
||||||
|
) -> RESTResponseType:
|
||||||
|
"""Get bank template JSON Schema
|
||||||
|
|
||||||
|
Returns the JSON Schema for the bank template manifest format. Use this to validate template manifests before importing.
|
||||||
|
|
||||||
|
:param _request_timeout: timeout setting for this request. If one
|
||||||
|
number provided, it will be total request
|
||||||
|
timeout. It can also be a pair (tuple) of
|
||||||
|
(connection, read) timeouts.
|
||||||
|
:type _request_timeout: int, tuple(int, int), optional
|
||||||
|
:param _request_auth: set to override the auth_settings for an a single
|
||||||
|
request; this effectively ignores the
|
||||||
|
authentication in the spec for a single request.
|
||||||
|
:type _request_auth: dict, optional
|
||||||
|
:param _content_type: force content-type for the request.
|
||||||
|
:type _content_type: str, Optional
|
||||||
|
:param _headers: set to override the headers for a single
|
||||||
|
request; this effectively ignores the headers
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _headers: dict, optional
|
||||||
|
:param _host_index: set to override the host_index for a single
|
||||||
|
request; this effectively ignores the host_index
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _host_index: int, optional
|
||||||
|
:return: Returns the result object.
|
||||||
|
""" # noqa: E501
|
||||||
|
|
||||||
|
_param = self._get_bank_template_schema_serialize(
|
||||||
|
_request_auth=_request_auth,
|
||||||
|
_content_type=_content_type,
|
||||||
|
_headers=_headers,
|
||||||
|
_host_index=_host_index
|
||||||
|
)
|
||||||
|
|
||||||
|
_response_types_map: Dict[str, Optional[str]] = {
|
||||||
|
'200': "object",
|
||||||
|
}
|
||||||
|
response_data = await self.api_client.call_api(
|
||||||
|
*_param,
|
||||||
|
_request_timeout=_request_timeout
|
||||||
|
)
|
||||||
|
return response_data.response
|
||||||
|
|
||||||
|
|
||||||
|
def _get_bank_template_schema_serialize(
|
||||||
|
self,
|
||||||
|
_request_auth,
|
||||||
|
_content_type,
|
||||||
|
_headers,
|
||||||
|
_host_index,
|
||||||
|
) -> RequestSerialized:
|
||||||
|
|
||||||
|
_host = None
|
||||||
|
|
||||||
|
_collection_formats: Dict[str, str] = {
|
||||||
|
}
|
||||||
|
|
||||||
|
_path_params: Dict[str, str] = {}
|
||||||
|
_query_params: List[Tuple[str, str]] = []
|
||||||
|
_header_params: Dict[str, Optional[str]] = _headers or {}
|
||||||
|
_form_params: List[Tuple[str, str]] = []
|
||||||
|
_files: Dict[
|
||||||
|
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
|
||||||
|
] = {}
|
||||||
|
_body_params: Optional[bytes] = None
|
||||||
|
|
||||||
|
# process the path parameters
|
||||||
|
# process the query parameters
|
||||||
|
# process the header parameters
|
||||||
|
# process the form parameters
|
||||||
|
# process the body parameter
|
||||||
|
|
||||||
|
|
||||||
|
# set the HTTP header `Accept`
|
||||||
|
if 'Accept' not in _header_params:
|
||||||
|
_header_params['Accept'] = self.api_client.select_header_accept(
|
||||||
|
[
|
||||||
|
'application/json'
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# authentication setting
|
||||||
|
_auth_settings: List[str] = [
|
||||||
|
]
|
||||||
|
|
||||||
|
return self.api_client.param_serialize(
|
||||||
|
method='GET',
|
||||||
|
resource_path='/v1/bank-template-schema',
|
||||||
|
path_params=_path_params,
|
||||||
|
query_params=_query_params,
|
||||||
|
header_params=_header_params,
|
||||||
|
body=_body_params,
|
||||||
|
post_params=_form_params,
|
||||||
|
files=_files,
|
||||||
|
auth_settings=_auth_settings,
|
||||||
|
collection_formats=_collection_formats,
|
||||||
|
_host=_host,
|
||||||
|
_request_auth=_request_auth
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@validate_call
|
||||||
|
async def import_bank_template(
|
||||||
|
self,
|
||||||
|
bank_id: StrictStr,
|
||||||
|
dry_run: Annotated[Optional[StrictBool], Field(description="Validate only, do not apply changes")] = None,
|
||||||
|
authorization: Optional[StrictStr] = None,
|
||||||
|
_request_timeout: Union[
|
||||||
|
None,
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Tuple[
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Annotated[StrictFloat, Field(gt=0)]
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_content_type: Optional[StrictStr] = None,
|
||||||
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
||||||
|
) -> BankTemplateImportResponse:
|
||||||
|
"""Import bank template
|
||||||
|
|
||||||
|
Import a bank template manifest to create or update a bank's configuration, mental models, and directives. If the bank does not exist it is created. Config fields are applied as per-bank overrides. Mental models are matched by id, directives by name — existing ones are updated, new ones are created. Use dry_run=true to validate the manifest without applying changes.
|
||||||
|
|
||||||
|
:param bank_id: (required)
|
||||||
|
:type bank_id: str
|
||||||
|
:param dry_run: Validate only, do not apply changes
|
||||||
|
:type dry_run: bool
|
||||||
|
:param authorization:
|
||||||
|
:type authorization: str
|
||||||
|
:param _request_timeout: timeout setting for this request. If one
|
||||||
|
number provided, it will be total request
|
||||||
|
timeout. It can also be a pair (tuple) of
|
||||||
|
(connection, read) timeouts.
|
||||||
|
:type _request_timeout: int, tuple(int, int), optional
|
||||||
|
:param _request_auth: set to override the auth_settings for an a single
|
||||||
|
request; this effectively ignores the
|
||||||
|
authentication in the spec for a single request.
|
||||||
|
:type _request_auth: dict, optional
|
||||||
|
:param _content_type: force content-type for the request.
|
||||||
|
:type _content_type: str, Optional
|
||||||
|
:param _headers: set to override the headers for a single
|
||||||
|
request; this effectively ignores the headers
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _headers: dict, optional
|
||||||
|
:param _host_index: set to override the host_index for a single
|
||||||
|
request; this effectively ignores the host_index
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _host_index: int, optional
|
||||||
|
:return: Returns the result object.
|
||||||
|
""" # noqa: E501
|
||||||
|
|
||||||
|
_param = self._import_bank_template_serialize(
|
||||||
|
bank_id=bank_id,
|
||||||
|
dry_run=dry_run,
|
||||||
|
authorization=authorization,
|
||||||
|
_request_auth=_request_auth,
|
||||||
|
_content_type=_content_type,
|
||||||
|
_headers=_headers,
|
||||||
|
_host_index=_host_index
|
||||||
|
)
|
||||||
|
|
||||||
|
_response_types_map: Dict[str, Optional[str]] = {
|
||||||
|
'200': "BankTemplateImportResponse",
|
||||||
|
'422': "HTTPValidationError",
|
||||||
|
}
|
||||||
|
response_data = await self.api_client.call_api(
|
||||||
|
*_param,
|
||||||
|
_request_timeout=_request_timeout
|
||||||
|
)
|
||||||
|
await response_data.read()
|
||||||
|
return self.api_client.response_deserialize(
|
||||||
|
response_data=response_data,
|
||||||
|
response_types_map=_response_types_map,
|
||||||
|
).data
|
||||||
|
|
||||||
|
|
||||||
|
@validate_call
|
||||||
|
async def import_bank_template_with_http_info(
|
||||||
|
self,
|
||||||
|
bank_id: StrictStr,
|
||||||
|
dry_run: Annotated[Optional[StrictBool], Field(description="Validate only, do not apply changes")] = None,
|
||||||
|
authorization: Optional[StrictStr] = None,
|
||||||
|
_request_timeout: Union[
|
||||||
|
None,
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Tuple[
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Annotated[StrictFloat, Field(gt=0)]
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_content_type: Optional[StrictStr] = None,
|
||||||
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
||||||
|
) -> ApiResponse[BankTemplateImportResponse]:
|
||||||
|
"""Import bank template
|
||||||
|
|
||||||
|
Import a bank template manifest to create or update a bank's configuration, mental models, and directives. If the bank does not exist it is created. Config fields are applied as per-bank overrides. Mental models are matched by id, directives by name — existing ones are updated, new ones are created. Use dry_run=true to validate the manifest without applying changes.
|
||||||
|
|
||||||
|
:param bank_id: (required)
|
||||||
|
:type bank_id: str
|
||||||
|
:param dry_run: Validate only, do not apply changes
|
||||||
|
:type dry_run: bool
|
||||||
|
:param authorization:
|
||||||
|
:type authorization: str
|
||||||
|
:param _request_timeout: timeout setting for this request. If one
|
||||||
|
number provided, it will be total request
|
||||||
|
timeout. It can also be a pair (tuple) of
|
||||||
|
(connection, read) timeouts.
|
||||||
|
:type _request_timeout: int, tuple(int, int), optional
|
||||||
|
:param _request_auth: set to override the auth_settings for an a single
|
||||||
|
request; this effectively ignores the
|
||||||
|
authentication in the spec for a single request.
|
||||||
|
:type _request_auth: dict, optional
|
||||||
|
:param _content_type: force content-type for the request.
|
||||||
|
:type _content_type: str, Optional
|
||||||
|
:param _headers: set to override the headers for a single
|
||||||
|
request; this effectively ignores the headers
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _headers: dict, optional
|
||||||
|
:param _host_index: set to override the host_index for a single
|
||||||
|
request; this effectively ignores the host_index
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _host_index: int, optional
|
||||||
|
:return: Returns the result object.
|
||||||
|
""" # noqa: E501
|
||||||
|
|
||||||
|
_param = self._import_bank_template_serialize(
|
||||||
|
bank_id=bank_id,
|
||||||
|
dry_run=dry_run,
|
||||||
|
authorization=authorization,
|
||||||
|
_request_auth=_request_auth,
|
||||||
|
_content_type=_content_type,
|
||||||
|
_headers=_headers,
|
||||||
|
_host_index=_host_index
|
||||||
|
)
|
||||||
|
|
||||||
|
_response_types_map: Dict[str, Optional[str]] = {
|
||||||
|
'200': "BankTemplateImportResponse",
|
||||||
|
'422': "HTTPValidationError",
|
||||||
|
}
|
||||||
|
response_data = await self.api_client.call_api(
|
||||||
|
*_param,
|
||||||
|
_request_timeout=_request_timeout
|
||||||
|
)
|
||||||
|
await response_data.read()
|
||||||
|
return self.api_client.response_deserialize(
|
||||||
|
response_data=response_data,
|
||||||
|
response_types_map=_response_types_map,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@validate_call
|
||||||
|
async def import_bank_template_without_preload_content(
|
||||||
|
self,
|
||||||
|
bank_id: StrictStr,
|
||||||
|
dry_run: Annotated[Optional[StrictBool], Field(description="Validate only, do not apply changes")] = None,
|
||||||
|
authorization: Optional[StrictStr] = None,
|
||||||
|
_request_timeout: Union[
|
||||||
|
None,
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Tuple[
|
||||||
|
Annotated[StrictFloat, Field(gt=0)],
|
||||||
|
Annotated[StrictFloat, Field(gt=0)]
|
||||||
|
]
|
||||||
|
] = None,
|
||||||
|
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_content_type: Optional[StrictStr] = None,
|
||||||
|
_headers: Optional[Dict[StrictStr, Any]] = None,
|
||||||
|
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
||||||
|
) -> RESTResponseType:
|
||||||
|
"""Import bank template
|
||||||
|
|
||||||
|
Import a bank template manifest to create or update a bank's configuration, mental models, and directives. If the bank does not exist it is created. Config fields are applied as per-bank overrides. Mental models are matched by id, directives by name — existing ones are updated, new ones are created. Use dry_run=true to validate the manifest without applying changes.
|
||||||
|
|
||||||
|
:param bank_id: (required)
|
||||||
|
:type bank_id: str
|
||||||
|
:param dry_run: Validate only, do not apply changes
|
||||||
|
:type dry_run: bool
|
||||||
|
:param authorization:
|
||||||
|
:type authorization: str
|
||||||
|
:param _request_timeout: timeout setting for this request. If one
|
||||||
|
number provided, it will be total request
|
||||||
|
timeout. It can also be a pair (tuple) of
|
||||||
|
(connection, read) timeouts.
|
||||||
|
:type _request_timeout: int, tuple(int, int), optional
|
||||||
|
:param _request_auth: set to override the auth_settings for an a single
|
||||||
|
request; this effectively ignores the
|
||||||
|
authentication in the spec for a single request.
|
||||||
|
:type _request_auth: dict, optional
|
||||||
|
:param _content_type: force content-type for the request.
|
||||||
|
:type _content_type: str, Optional
|
||||||
|
:param _headers: set to override the headers for a single
|
||||||
|
request; this effectively ignores the headers
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _headers: dict, optional
|
||||||
|
:param _host_index: set to override the host_index for a single
|
||||||
|
request; this effectively ignores the host_index
|
||||||
|
in the spec for a single request.
|
||||||
|
:type _host_index: int, optional
|
||||||
|
:return: Returns the result object.
|
||||||
|
""" # noqa: E501
|
||||||
|
|
||||||
|
_param = self._import_bank_template_serialize(
|
||||||
|
bank_id=bank_id,
|
||||||
|
dry_run=dry_run,
|
||||||
|
authorization=authorization,
|
||||||
|
_request_auth=_request_auth,
|
||||||
|
_content_type=_content_type,
|
||||||
|
_headers=_headers,
|
||||||
|
_host_index=_host_index
|
||||||
|
)
|
||||||
|
|
||||||
|
_response_types_map: Dict[str, Optional[str]] = {
|
||||||
|
'200': "BankTemplateImportResponse",
|
||||||
|
'422': "HTTPValidationError",
|
||||||
|
}
|
||||||
|
response_data = await self.api_client.call_api(
|
||||||
|
*_param,
|
||||||
|
_request_timeout=_request_timeout
|
||||||
|
)
|
||||||
|
return response_data.response
|
||||||
|
|
||||||
|
|
||||||
|
def _import_bank_template_serialize(
|
||||||
|
self,
|
||||||
|
bank_id,
|
||||||
|
dry_run,
|
||||||
|
authorization,
|
||||||
|
_request_auth,
|
||||||
|
_content_type,
|
||||||
|
_headers,
|
||||||
|
_host_index,
|
||||||
|
) -> RequestSerialized:
|
||||||
|
|
||||||
|
_host = None
|
||||||
|
|
||||||
|
_collection_formats: Dict[str, str] = {
|
||||||
|
}
|
||||||
|
|
||||||
|
_path_params: Dict[str, str] = {}
|
||||||
|
_query_params: List[Tuple[str, str]] = []
|
||||||
|
_header_params: Dict[str, Optional[str]] = _headers or {}
|
||||||
|
_form_params: List[Tuple[str, str]] = []
|
||||||
|
_files: Dict[
|
||||||
|
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
|
||||||
|
] = {}
|
||||||
|
_body_params: Optional[bytes] = None
|
||||||
|
|
||||||
|
# process the path parameters
|
||||||
|
if bank_id is not None:
|
||||||
|
_path_params['bank_id'] = bank_id
|
||||||
|
# process the query parameters
|
||||||
|
if dry_run is not None:
|
||||||
|
|
||||||
|
_query_params.append(('dry_run', dry_run))
|
||||||
|
|
||||||
|
# process the header parameters
|
||||||
|
if authorization is not None:
|
||||||
|
_header_params['authorization'] = authorization
|
||||||
|
# process the form parameters
|
||||||
|
# process the body parameter
|
||||||
|
|
||||||
|
|
||||||
|
# set the HTTP header `Accept`
|
||||||
|
if 'Accept' not in _header_params:
|
||||||
|
_header_params['Accept'] = self.api_client.select_header_accept(
|
||||||
|
[
|
||||||
|
'application/json'
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# authentication setting
|
||||||
|
_auth_settings: List[str] = [
|
||||||
|
]
|
||||||
|
|
||||||
|
return self.api_client.param_serialize(
|
||||||
|
method='POST',
|
||||||
|
resource_path='/v1/default/banks/{bank_id}/import',
|
||||||
|
path_params=_path_params,
|
||||||
|
query_params=_query_params,
|
||||||
|
header_params=_header_params,
|
||||||
|
body=_body_params,
|
||||||
|
post_params=_form_params,
|
||||||
|
files=_files,
|
||||||
|
auth_settings=_auth_settings,
|
||||||
|
collection_formats=_collection_formats,
|
||||||
|
_host=_host,
|
||||||
|
_request_auth=_request_auth
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -27,6 +27,11 @@ from hindsight_client_api.models.bank_list_item import BankListItem
|
||||||
from hindsight_client_api.models.bank_list_response import BankListResponse
|
from hindsight_client_api.models.bank_list_response import BankListResponse
|
||||||
from hindsight_client_api.models.bank_profile_response import BankProfileResponse
|
from hindsight_client_api.models.bank_profile_response import BankProfileResponse
|
||||||
from hindsight_client_api.models.bank_stats_response import BankStatsResponse
|
from hindsight_client_api.models.bank_stats_response import BankStatsResponse
|
||||||
|
from hindsight_client_api.models.bank_template_config import BankTemplateConfig
|
||||||
|
from hindsight_client_api.models.bank_template_directive import BankTemplateDirective
|
||||||
|
from hindsight_client_api.models.bank_template_import_response import BankTemplateImportResponse
|
||||||
|
from hindsight_client_api.models.bank_template_manifest import BankTemplateManifest
|
||||||
|
from hindsight_client_api.models.bank_template_mental_model import BankTemplateMentalModel
|
||||||
from hindsight_client_api.models.budget import Budget
|
from hindsight_client_api.models.budget import Budget
|
||||||
from hindsight_client_api.models.cancel_operation_response import CancelOperationResponse
|
from hindsight_client_api.models.cancel_operation_response import CancelOperationResponse
|
||||||
from hindsight_client_api.models.child_operation_status import ChildOperationStatus
|
from hindsight_client_api.models.child_operation_status import ChildOperationStatus
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,170 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
"""
|
||||||
|
Hindsight HTTP API
|
||||||
|
|
||||||
|
HTTP API for Hindsight
|
||||||
|
|
||||||
|
The version of the OpenAPI document: 0.4.22
|
||||||
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||||
|
|
||||||
|
Do not edit the class manually.
|
||||||
|
""" # noqa: E501
|
||||||
|
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
import pprint
|
||||||
|
import re # noqa: F401
|
||||||
|
import json
|
||||||
|
|
||||||
|
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr
|
||||||
|
from typing import Any, ClassVar, Dict, List, Optional
|
||||||
|
from typing_extensions import Annotated
|
||||||
|
from typing import Optional, Set
|
||||||
|
from typing_extensions import Self
|
||||||
|
|
||||||
|
class BankTemplateConfig(BaseModel):
|
||||||
|
"""
|
||||||
|
Bank configuration fields within a template manifest. Only includes configurable (per-bank) fields. Credential fields (API keys, base URLs) are intentionally excluded for security.
|
||||||
|
""" # noqa: E501
|
||||||
|
reflect_mission: Optional[StrictStr] = None
|
||||||
|
retain_mission: Optional[StrictStr] = None
|
||||||
|
retain_extraction_mode: Optional[StrictStr] = None
|
||||||
|
retain_custom_instructions: Optional[StrictStr] = None
|
||||||
|
retain_chunk_size: Optional[StrictInt] = None
|
||||||
|
enable_observations: Optional[StrictBool] = None
|
||||||
|
observations_mission: Optional[StrictStr] = None
|
||||||
|
disposition_skepticism: Optional[Annotated[int, Field(le=5, strict=True, ge=1)]] = None
|
||||||
|
disposition_literalism: Optional[Annotated[int, Field(le=5, strict=True, ge=1)]] = None
|
||||||
|
disposition_empathy: Optional[Annotated[int, Field(le=5, strict=True, ge=1)]] = None
|
||||||
|
entity_labels: Optional[List[StrictStr]] = None
|
||||||
|
entities_allow_free_form: Optional[StrictBool] = None
|
||||||
|
__properties: ClassVar[List[str]] = ["reflect_mission", "retain_mission", "retain_extraction_mode", "retain_custom_instructions", "retain_chunk_size", "enable_observations", "observations_mission", "disposition_skepticism", "disposition_literalism", "disposition_empathy", "entity_labels", "entities_allow_free_form"]
|
||||||
|
|
||||||
|
model_config = ConfigDict(
|
||||||
|
populate_by_name=True,
|
||||||
|
validate_assignment=True,
|
||||||
|
protected_namespaces=(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def to_str(self) -> str:
|
||||||
|
"""Returns the string representation of the model using alias"""
|
||||||
|
return pprint.pformat(self.model_dump(by_alias=True))
|
||||||
|
|
||||||
|
def to_json(self) -> str:
|
||||||
|
"""Returns the JSON representation of the model using alias"""
|
||||||
|
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
||||||
|
return json.dumps(self.to_dict())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls, json_str: str) -> Optional[Self]:
|
||||||
|
"""Create an instance of BankTemplateConfig from a JSON string"""
|
||||||
|
return cls.from_dict(json.loads(json_str))
|
||||||
|
|
||||||
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
|
"""Return the dictionary representation of the model using alias.
|
||||||
|
|
||||||
|
This has the following differences from calling pydantic's
|
||||||
|
`self.model_dump(by_alias=True)`:
|
||||||
|
|
||||||
|
* `None` is only added to the output dict for nullable fields that
|
||||||
|
were set at model initialization. Other fields with value `None`
|
||||||
|
are ignored.
|
||||||
|
"""
|
||||||
|
excluded_fields: Set[str] = set([
|
||||||
|
])
|
||||||
|
|
||||||
|
_dict = self.model_dump(
|
||||||
|
by_alias=True,
|
||||||
|
exclude=excluded_fields,
|
||||||
|
exclude_none=True,
|
||||||
|
)
|
||||||
|
# set to None if reflect_mission (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.reflect_mission is None and "reflect_mission" in self.model_fields_set:
|
||||||
|
_dict['reflect_mission'] = None
|
||||||
|
|
||||||
|
# set to None if retain_mission (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.retain_mission is None and "retain_mission" in self.model_fields_set:
|
||||||
|
_dict['retain_mission'] = None
|
||||||
|
|
||||||
|
# set to None if retain_extraction_mode (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.retain_extraction_mode is None and "retain_extraction_mode" in self.model_fields_set:
|
||||||
|
_dict['retain_extraction_mode'] = None
|
||||||
|
|
||||||
|
# set to None if retain_custom_instructions (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.retain_custom_instructions is None and "retain_custom_instructions" in self.model_fields_set:
|
||||||
|
_dict['retain_custom_instructions'] = None
|
||||||
|
|
||||||
|
# set to None if retain_chunk_size (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.retain_chunk_size is None and "retain_chunk_size" in self.model_fields_set:
|
||||||
|
_dict['retain_chunk_size'] = None
|
||||||
|
|
||||||
|
# set to None if enable_observations (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.enable_observations is None and "enable_observations" in self.model_fields_set:
|
||||||
|
_dict['enable_observations'] = None
|
||||||
|
|
||||||
|
# set to None if observations_mission (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.observations_mission is None and "observations_mission" in self.model_fields_set:
|
||||||
|
_dict['observations_mission'] = None
|
||||||
|
|
||||||
|
# set to None if disposition_skepticism (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.disposition_skepticism is None and "disposition_skepticism" in self.model_fields_set:
|
||||||
|
_dict['disposition_skepticism'] = None
|
||||||
|
|
||||||
|
# set to None if disposition_literalism (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.disposition_literalism is None and "disposition_literalism" in self.model_fields_set:
|
||||||
|
_dict['disposition_literalism'] = None
|
||||||
|
|
||||||
|
# set to None if disposition_empathy (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.disposition_empathy is None and "disposition_empathy" in self.model_fields_set:
|
||||||
|
_dict['disposition_empathy'] = None
|
||||||
|
|
||||||
|
# set to None if entity_labels (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.entity_labels is None and "entity_labels" in self.model_fields_set:
|
||||||
|
_dict['entity_labels'] = None
|
||||||
|
|
||||||
|
# set to None if entities_allow_free_form (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.entities_allow_free_form is None and "entities_allow_free_form" in self.model_fields_set:
|
||||||
|
_dict['entities_allow_free_form'] = None
|
||||||
|
|
||||||
|
return _dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
||||||
|
"""Create an instance of BankTemplateConfig from a dict"""
|
||||||
|
if obj is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if not isinstance(obj, dict):
|
||||||
|
return cls.model_validate(obj)
|
||||||
|
|
||||||
|
_obj = cls.model_validate({
|
||||||
|
"reflect_mission": obj.get("reflect_mission"),
|
||||||
|
"retain_mission": obj.get("retain_mission"),
|
||||||
|
"retain_extraction_mode": obj.get("retain_extraction_mode"),
|
||||||
|
"retain_custom_instructions": obj.get("retain_custom_instructions"),
|
||||||
|
"retain_chunk_size": obj.get("retain_chunk_size"),
|
||||||
|
"enable_observations": obj.get("enable_observations"),
|
||||||
|
"observations_mission": obj.get("observations_mission"),
|
||||||
|
"disposition_skepticism": obj.get("disposition_skepticism"),
|
||||||
|
"disposition_literalism": obj.get("disposition_literalism"),
|
||||||
|
"disposition_empathy": obj.get("disposition_empathy"),
|
||||||
|
"entity_labels": obj.get("entity_labels"),
|
||||||
|
"entities_allow_free_form": obj.get("entities_allow_free_form")
|
||||||
|
})
|
||||||
|
return _obj
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
"""
|
||||||
|
Hindsight HTTP API
|
||||||
|
|
||||||
|
HTTP API for Hindsight
|
||||||
|
|
||||||
|
The version of the OpenAPI document: 0.4.22
|
||||||
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||||
|
|
||||||
|
Do not edit the class manually.
|
||||||
|
""" # noqa: E501
|
||||||
|
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
import pprint
|
||||||
|
import re # noqa: F401
|
||||||
|
import json
|
||||||
|
|
||||||
|
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr
|
||||||
|
from typing import Any, ClassVar, Dict, List, Optional
|
||||||
|
from typing import Optional, Set
|
||||||
|
from typing_extensions import Self
|
||||||
|
|
||||||
|
class BankTemplateDirective(BaseModel):
|
||||||
|
"""
|
||||||
|
A directive definition within a bank template manifest. Directives are matched by name on re-import: existing directives with the same name are updated, new ones are created.
|
||||||
|
""" # noqa: E501
|
||||||
|
name: StrictStr = Field(description="Human-readable name for the directive (used as match key on re-import)")
|
||||||
|
content: StrictStr = Field(description="The directive text to inject into prompts")
|
||||||
|
priority: Optional[StrictInt] = Field(default=0, description="Higher priority directives are injected first")
|
||||||
|
is_active: Optional[StrictBool] = Field(default=True, description="Whether this directive is active")
|
||||||
|
tags: Optional[List[StrictStr]] = Field(default=None, description="Tags for filtering")
|
||||||
|
__properties: ClassVar[List[str]] = ["name", "content", "priority", "is_active", "tags"]
|
||||||
|
|
||||||
|
model_config = ConfigDict(
|
||||||
|
populate_by_name=True,
|
||||||
|
validate_assignment=True,
|
||||||
|
protected_namespaces=(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def to_str(self) -> str:
|
||||||
|
"""Returns the string representation of the model using alias"""
|
||||||
|
return pprint.pformat(self.model_dump(by_alias=True))
|
||||||
|
|
||||||
|
def to_json(self) -> str:
|
||||||
|
"""Returns the JSON representation of the model using alias"""
|
||||||
|
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
||||||
|
return json.dumps(self.to_dict())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls, json_str: str) -> Optional[Self]:
|
||||||
|
"""Create an instance of BankTemplateDirective from a JSON string"""
|
||||||
|
return cls.from_dict(json.loads(json_str))
|
||||||
|
|
||||||
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
|
"""Return the dictionary representation of the model using alias.
|
||||||
|
|
||||||
|
This has the following differences from calling pydantic's
|
||||||
|
`self.model_dump(by_alias=True)`:
|
||||||
|
|
||||||
|
* `None` is only added to the output dict for nullable fields that
|
||||||
|
were set at model initialization. Other fields with value `None`
|
||||||
|
are ignored.
|
||||||
|
"""
|
||||||
|
excluded_fields: Set[str] = set([
|
||||||
|
])
|
||||||
|
|
||||||
|
_dict = self.model_dump(
|
||||||
|
by_alias=True,
|
||||||
|
exclude=excluded_fields,
|
||||||
|
exclude_none=True,
|
||||||
|
)
|
||||||
|
return _dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
||||||
|
"""Create an instance of BankTemplateDirective from a dict"""
|
||||||
|
if obj is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if not isinstance(obj, dict):
|
||||||
|
return cls.model_validate(obj)
|
||||||
|
|
||||||
|
_obj = cls.model_validate({
|
||||||
|
"name": obj.get("name"),
|
||||||
|
"content": obj.get("content"),
|
||||||
|
"priority": obj.get("priority") if obj.get("priority") is not None else 0,
|
||||||
|
"is_active": obj.get("is_active") if obj.get("is_active") is not None else True,
|
||||||
|
"tags": obj.get("tags")
|
||||||
|
})
|
||||||
|
return _obj
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
"""
|
||||||
|
Hindsight HTTP API
|
||||||
|
|
||||||
|
HTTP API for Hindsight
|
||||||
|
|
||||||
|
The version of the OpenAPI document: 0.4.22
|
||||||
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||||
|
|
||||||
|
Do not edit the class manually.
|
||||||
|
""" # noqa: E501
|
||||||
|
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
import pprint
|
||||||
|
import re # noqa: F401
|
||||||
|
import json
|
||||||
|
|
||||||
|
from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictStr
|
||||||
|
from typing import Any, ClassVar, Dict, List, Optional
|
||||||
|
from typing import Optional, Set
|
||||||
|
from typing_extensions import Self
|
||||||
|
|
||||||
|
class BankTemplateImportResponse(BaseModel):
|
||||||
|
"""
|
||||||
|
Response model for the bank template import endpoint.
|
||||||
|
""" # noqa: E501
|
||||||
|
bank_id: StrictStr = Field(description="Bank that was imported into")
|
||||||
|
config_applied: StrictBool = Field(description="Whether bank config was updated")
|
||||||
|
mental_models_created: Optional[List[StrictStr]] = Field(default=None, description="IDs of newly created mental models")
|
||||||
|
mental_models_updated: Optional[List[StrictStr]] = Field(default=None, description="IDs of updated mental models")
|
||||||
|
directives_created: Optional[List[StrictStr]] = Field(default=None, description="Names of newly created directives")
|
||||||
|
directives_updated: Optional[List[StrictStr]] = Field(default=None, description="Names of updated directives")
|
||||||
|
operation_ids: Optional[List[StrictStr]] = Field(default=None, description="Operation IDs for mental model content generation (async)")
|
||||||
|
dry_run: Optional[StrictBool] = Field(default=False, description="True if this was a validation-only run")
|
||||||
|
__properties: ClassVar[List[str]] = ["bank_id", "config_applied", "mental_models_created", "mental_models_updated", "directives_created", "directives_updated", "operation_ids", "dry_run"]
|
||||||
|
|
||||||
|
model_config = ConfigDict(
|
||||||
|
populate_by_name=True,
|
||||||
|
validate_assignment=True,
|
||||||
|
protected_namespaces=(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def to_str(self) -> str:
|
||||||
|
"""Returns the string representation of the model using alias"""
|
||||||
|
return pprint.pformat(self.model_dump(by_alias=True))
|
||||||
|
|
||||||
|
def to_json(self) -> str:
|
||||||
|
"""Returns the JSON representation of the model using alias"""
|
||||||
|
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
||||||
|
return json.dumps(self.to_dict())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls, json_str: str) -> Optional[Self]:
|
||||||
|
"""Create an instance of BankTemplateImportResponse from a JSON string"""
|
||||||
|
return cls.from_dict(json.loads(json_str))
|
||||||
|
|
||||||
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
|
"""Return the dictionary representation of the model using alias.
|
||||||
|
|
||||||
|
This has the following differences from calling pydantic's
|
||||||
|
`self.model_dump(by_alias=True)`:
|
||||||
|
|
||||||
|
* `None` is only added to the output dict for nullable fields that
|
||||||
|
were set at model initialization. Other fields with value `None`
|
||||||
|
are ignored.
|
||||||
|
"""
|
||||||
|
excluded_fields: Set[str] = set([
|
||||||
|
])
|
||||||
|
|
||||||
|
_dict = self.model_dump(
|
||||||
|
by_alias=True,
|
||||||
|
exclude=excluded_fields,
|
||||||
|
exclude_none=True,
|
||||||
|
)
|
||||||
|
return _dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
||||||
|
"""Create an instance of BankTemplateImportResponse from a dict"""
|
||||||
|
if obj is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if not isinstance(obj, dict):
|
||||||
|
return cls.model_validate(obj)
|
||||||
|
|
||||||
|
_obj = cls.model_validate({
|
||||||
|
"bank_id": obj.get("bank_id"),
|
||||||
|
"config_applied": obj.get("config_applied"),
|
||||||
|
"mental_models_created": obj.get("mental_models_created"),
|
||||||
|
"mental_models_updated": obj.get("mental_models_updated"),
|
||||||
|
"directives_created": obj.get("directives_created"),
|
||||||
|
"directives_updated": obj.get("directives_updated"),
|
||||||
|
"operation_ids": obj.get("operation_ids"),
|
||||||
|
"dry_run": obj.get("dry_run") if obj.get("dry_run") is not None else False
|
||||||
|
})
|
||||||
|
return _obj
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,128 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
"""
|
||||||
|
Hindsight HTTP API
|
||||||
|
|
||||||
|
HTTP API for Hindsight
|
||||||
|
|
||||||
|
The version of the OpenAPI document: 0.4.22
|
||||||
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||||
|
|
||||||
|
Do not edit the class manually.
|
||||||
|
""" # noqa: E501
|
||||||
|
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
import pprint
|
||||||
|
import re # noqa: F401
|
||||||
|
import json
|
||||||
|
|
||||||
|
from pydantic import BaseModel, ConfigDict, Field, StrictStr
|
||||||
|
from typing import Any, ClassVar, Dict, List, Optional
|
||||||
|
from hindsight_client_api.models.bank_template_config import BankTemplateConfig
|
||||||
|
from hindsight_client_api.models.bank_template_directive import BankTemplateDirective
|
||||||
|
from hindsight_client_api.models.bank_template_mental_model import BankTemplateMentalModel
|
||||||
|
from typing import Optional, Set
|
||||||
|
from typing_extensions import Self
|
||||||
|
|
||||||
|
class BankTemplateManifest(BaseModel):
|
||||||
|
"""
|
||||||
|
A bank template manifest for import/export. Version field enables forward-compatible schema evolution: the API auto-upgrades older manifest versions to the current schema on import.
|
||||||
|
""" # noqa: E501
|
||||||
|
version: StrictStr = Field(description="Manifest schema version (currently '1')")
|
||||||
|
bank: Optional[BankTemplateConfig] = None
|
||||||
|
mental_models: Optional[List[BankTemplateMentalModel]] = None
|
||||||
|
directives: Optional[List[BankTemplateDirective]] = None
|
||||||
|
__properties: ClassVar[List[str]] = ["version", "bank", "mental_models", "directives"]
|
||||||
|
|
||||||
|
model_config = ConfigDict(
|
||||||
|
populate_by_name=True,
|
||||||
|
validate_assignment=True,
|
||||||
|
protected_namespaces=(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def to_str(self) -> str:
|
||||||
|
"""Returns the string representation of the model using alias"""
|
||||||
|
return pprint.pformat(self.model_dump(by_alias=True))
|
||||||
|
|
||||||
|
def to_json(self) -> str:
|
||||||
|
"""Returns the JSON representation of the model using alias"""
|
||||||
|
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
||||||
|
return json.dumps(self.to_dict())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls, json_str: str) -> Optional[Self]:
|
||||||
|
"""Create an instance of BankTemplateManifest from a JSON string"""
|
||||||
|
return cls.from_dict(json.loads(json_str))
|
||||||
|
|
||||||
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
|
"""Return the dictionary representation of the model using alias.
|
||||||
|
|
||||||
|
This has the following differences from calling pydantic's
|
||||||
|
`self.model_dump(by_alias=True)`:
|
||||||
|
|
||||||
|
* `None` is only added to the output dict for nullable fields that
|
||||||
|
were set at model initialization. Other fields with value `None`
|
||||||
|
are ignored.
|
||||||
|
"""
|
||||||
|
excluded_fields: Set[str] = set([
|
||||||
|
])
|
||||||
|
|
||||||
|
_dict = self.model_dump(
|
||||||
|
by_alias=True,
|
||||||
|
exclude=excluded_fields,
|
||||||
|
exclude_none=True,
|
||||||
|
)
|
||||||
|
# override the default output from pydantic by calling `to_dict()` of bank
|
||||||
|
if self.bank:
|
||||||
|
_dict['bank'] = self.bank.to_dict()
|
||||||
|
# override the default output from pydantic by calling `to_dict()` of each item in mental_models (list)
|
||||||
|
_items = []
|
||||||
|
if self.mental_models:
|
||||||
|
for _item_mental_models in self.mental_models:
|
||||||
|
if _item_mental_models:
|
||||||
|
_items.append(_item_mental_models.to_dict())
|
||||||
|
_dict['mental_models'] = _items
|
||||||
|
# override the default output from pydantic by calling `to_dict()` of each item in directives (list)
|
||||||
|
_items = []
|
||||||
|
if self.directives:
|
||||||
|
for _item_directives in self.directives:
|
||||||
|
if _item_directives:
|
||||||
|
_items.append(_item_directives.to_dict())
|
||||||
|
_dict['directives'] = _items
|
||||||
|
# set to None if bank (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.bank is None and "bank" in self.model_fields_set:
|
||||||
|
_dict['bank'] = None
|
||||||
|
|
||||||
|
# set to None if mental_models (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.mental_models is None and "mental_models" in self.model_fields_set:
|
||||||
|
_dict['mental_models'] = None
|
||||||
|
|
||||||
|
# set to None if directives (nullable) is None
|
||||||
|
# and model_fields_set contains the field
|
||||||
|
if self.directives is None and "directives" in self.model_fields_set:
|
||||||
|
_dict['directives'] = None
|
||||||
|
|
||||||
|
return _dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
||||||
|
"""Create an instance of BankTemplateManifest from a dict"""
|
||||||
|
if obj is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if not isinstance(obj, dict):
|
||||||
|
return cls.model_validate(obj)
|
||||||
|
|
||||||
|
_obj = cls.model_validate({
|
||||||
|
"version": obj.get("version"),
|
||||||
|
"bank": BankTemplateConfig.from_dict(obj["bank"]) if obj.get("bank") is not None else None,
|
||||||
|
"mental_models": [BankTemplateMentalModel.from_dict(_item) for _item in obj["mental_models"]] if obj.get("mental_models") is not None else None,
|
||||||
|
"directives": [BankTemplateDirective.from_dict(_item) for _item in obj["directives"]] if obj.get("directives") is not None else None
|
||||||
|
})
|
||||||
|
return _obj
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
|
"""
|
||||||
|
Hindsight HTTP API
|
||||||
|
|
||||||
|
HTTP API for Hindsight
|
||||||
|
|
||||||
|
The version of the OpenAPI document: 0.4.22
|
||||||
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||||
|
|
||||||
|
Do not edit the class manually.
|
||||||
|
""" # noqa: E501
|
||||||
|
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
import pprint
|
||||||
|
import re # noqa: F401
|
||||||
|
import json
|
||||||
|
|
||||||
|
from pydantic import BaseModel, ConfigDict, Field, StrictStr
|
||||||
|
from typing import Any, ClassVar, Dict, List, Optional
|
||||||
|
from typing_extensions import Annotated
|
||||||
|
from hindsight_client_api.models.mental_model_trigger_output import MentalModelTriggerOutput
|
||||||
|
from typing import Optional, Set
|
||||||
|
from typing_extensions import Self
|
||||||
|
|
||||||
|
class BankTemplateMentalModel(BaseModel):
|
||||||
|
"""
|
||||||
|
A mental model definition within a bank template manifest.
|
||||||
|
""" # noqa: E501
|
||||||
|
id: StrictStr = Field(description="Unique ID for the mental model (alphanumeric lowercase with hyphens)")
|
||||||
|
name: StrictStr = Field(description="Human-readable name for the mental model")
|
||||||
|
source_query: StrictStr = Field(description="The query to run to generate content")
|
||||||
|
tags: Optional[List[StrictStr]] = Field(default=None, description="Tags for scoped visibility")
|
||||||
|
max_tokens: Optional[Annotated[int, Field(le=8192, strict=True, ge=256)]] = Field(default=2048, description="Maximum tokens for generated content")
|
||||||
|
trigger: Optional[MentalModelTriggerOutput] = Field(default=None, description="Trigger settings")
|
||||||
|
__properties: ClassVar[List[str]] = ["id", "name", "source_query", "tags", "max_tokens", "trigger"]
|
||||||
|
|
||||||
|
model_config = ConfigDict(
|
||||||
|
populate_by_name=True,
|
||||||
|
validate_assignment=True,
|
||||||
|
protected_namespaces=(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def to_str(self) -> str:
|
||||||
|
"""Returns the string representation of the model using alias"""
|
||||||
|
return pprint.pformat(self.model_dump(by_alias=True))
|
||||||
|
|
||||||
|
def to_json(self) -> str:
|
||||||
|
"""Returns the JSON representation of the model using alias"""
|
||||||
|
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
|
||||||
|
return json.dumps(self.to_dict())
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls, json_str: str) -> Optional[Self]:
|
||||||
|
"""Create an instance of BankTemplateMentalModel from a JSON string"""
|
||||||
|
return cls.from_dict(json.loads(json_str))
|
||||||
|
|
||||||
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
|
"""Return the dictionary representation of the model using alias.
|
||||||
|
|
||||||
|
This has the following differences from calling pydantic's
|
||||||
|
`self.model_dump(by_alias=True)`:
|
||||||
|
|
||||||
|
* `None` is only added to the output dict for nullable fields that
|
||||||
|
were set at model initialization. Other fields with value `None`
|
||||||
|
are ignored.
|
||||||
|
"""
|
||||||
|
excluded_fields: Set[str] = set([
|
||||||
|
])
|
||||||
|
|
||||||
|
_dict = self.model_dump(
|
||||||
|
by_alias=True,
|
||||||
|
exclude=excluded_fields,
|
||||||
|
exclude_none=True,
|
||||||
|
)
|
||||||
|
# override the default output from pydantic by calling `to_dict()` of trigger
|
||||||
|
if self.trigger:
|
||||||
|
_dict['trigger'] = self.trigger.to_dict()
|
||||||
|
return _dict
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
|
||||||
|
"""Create an instance of BankTemplateMentalModel from a dict"""
|
||||||
|
if obj is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if not isinstance(obj, dict):
|
||||||
|
return cls.model_validate(obj)
|
||||||
|
|
||||||
|
_obj = cls.model_validate({
|
||||||
|
"id": obj.get("id"),
|
||||||
|
"name": obj.get("name"),
|
||||||
|
"source_query": obj.get("source_query"),
|
||||||
|
"tags": obj.get("tags"),
|
||||||
|
"max_tokens": obj.get("max_tokens") if obj.get("max_tokens") is not None else 2048,
|
||||||
|
"trigger": MentalModelTriggerOutput.from_dict(obj["trigger"]) if obj.get("trigger") is not None else None
|
||||||
|
})
|
||||||
|
return _obj
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -53,6 +53,9 @@ import type {
|
||||||
DeleteWebhookData,
|
DeleteWebhookData,
|
||||||
DeleteWebhookErrors,
|
DeleteWebhookErrors,
|
||||||
DeleteWebhookResponses,
|
DeleteWebhookResponses,
|
||||||
|
ExportBankTemplateData,
|
||||||
|
ExportBankTemplateErrors,
|
||||||
|
ExportBankTemplateResponses,
|
||||||
FileRetainData,
|
FileRetainData,
|
||||||
FileRetainErrors,
|
FileRetainErrors,
|
||||||
FileRetainResponses,
|
FileRetainResponses,
|
||||||
|
|
@ -65,6 +68,8 @@ import type {
|
||||||
GetBankProfileData,
|
GetBankProfileData,
|
||||||
GetBankProfileErrors,
|
GetBankProfileErrors,
|
||||||
GetBankProfileResponses,
|
GetBankProfileResponses,
|
||||||
|
GetBankTemplateSchemaData,
|
||||||
|
GetBankTemplateSchemaResponses,
|
||||||
GetChunkData,
|
GetChunkData,
|
||||||
GetChunkErrors,
|
GetChunkErrors,
|
||||||
GetChunkResponses,
|
GetChunkResponses,
|
||||||
|
|
@ -99,6 +104,9 @@ import type {
|
||||||
GetVersionResponses,
|
GetVersionResponses,
|
||||||
HealthEndpointHealthGetData,
|
HealthEndpointHealthGetData,
|
||||||
HealthEndpointHealthGetResponses,
|
HealthEndpointHealthGetResponses,
|
||||||
|
ImportBankTemplateData,
|
||||||
|
ImportBankTemplateErrors,
|
||||||
|
ImportBankTemplateResponses,
|
||||||
ListAuditLogsData,
|
ListAuditLogsData,
|
||||||
ListAuditLogsErrors,
|
ListAuditLogsErrors,
|
||||||
ListAuditLogsResponses,
|
ListAuditLogsResponses,
|
||||||
|
|
@ -930,6 +938,48 @@ export const createOrUpdateBank = <ThrowOnError extends boolean = false>(
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import bank template
|
||||||
|
*
|
||||||
|
* Import a bank template manifest to create or update a bank's configuration, mental models, and directives. If the bank does not exist it is created. Config fields are applied as per-bank overrides. Mental models are matched by id, directives by name — existing ones are updated, new ones are created. Use dry_run=true to validate the manifest without applying changes.
|
||||||
|
*/
|
||||||
|
export const importBankTemplate = <ThrowOnError extends boolean = false>(
|
||||||
|
options: Options<ImportBankTemplateData, ThrowOnError>,
|
||||||
|
) =>
|
||||||
|
(options.client ?? client).post<
|
||||||
|
ImportBankTemplateResponses,
|
||||||
|
ImportBankTemplateErrors,
|
||||||
|
ThrowOnError
|
||||||
|
>({ url: "/v1/default/banks/{bank_id}/import", ...options });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export bank template
|
||||||
|
*
|
||||||
|
* Export a bank's current configuration, mental models, and directives as a template manifest. The exported manifest can be imported into another bank to replicate the setup.
|
||||||
|
*/
|
||||||
|
export const exportBankTemplate = <ThrowOnError extends boolean = false>(
|
||||||
|
options: Options<ExportBankTemplateData, ThrowOnError>,
|
||||||
|
) =>
|
||||||
|
(options.client ?? client).get<
|
||||||
|
ExportBankTemplateResponses,
|
||||||
|
ExportBankTemplateErrors,
|
||||||
|
ThrowOnError
|
||||||
|
>({ url: "/v1/default/banks/{bank_id}/export", ...options });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get bank template JSON Schema
|
||||||
|
*
|
||||||
|
* Returns the JSON Schema for the bank template manifest format. Use this to validate template manifests before importing.
|
||||||
|
*/
|
||||||
|
export const getBankTemplateSchema = <ThrowOnError extends boolean = false>(
|
||||||
|
options?: Options<GetBankTemplateSchemaData, ThrowOnError>,
|
||||||
|
) =>
|
||||||
|
(options?.client ?? client).get<
|
||||||
|
GetBankTemplateSchemaResponses,
|
||||||
|
unknown,
|
||||||
|
ThrowOnError
|
||||||
|
>({ url: "/v1/bank-template-schema", ...options });
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear all observations
|
* Clear all observations
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -385,6 +385,261 @@ export type BankStatsResponse = {
|
||||||
total_observations?: number;
|
total_observations?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BankTemplateConfig
|
||||||
|
*
|
||||||
|
* Bank configuration fields within a template manifest.
|
||||||
|
*
|
||||||
|
* Only includes configurable (per-bank) fields. Credential fields
|
||||||
|
* (API keys, base URLs) are intentionally excluded for security.
|
||||||
|
*/
|
||||||
|
export type BankTemplateConfig = {
|
||||||
|
/**
|
||||||
|
* Reflect Mission
|
||||||
|
*
|
||||||
|
* Mission/context for Reflect operations
|
||||||
|
*/
|
||||||
|
reflect_mission?: string | null;
|
||||||
|
/**
|
||||||
|
* Retain Mission
|
||||||
|
*
|
||||||
|
* Steers what gets extracted during retain
|
||||||
|
*/
|
||||||
|
retain_mission?: string | null;
|
||||||
|
/**
|
||||||
|
* Retain Extraction Mode
|
||||||
|
*
|
||||||
|
* Fact extraction mode: 'concise' (default), 'verbose', or 'custom'
|
||||||
|
*/
|
||||||
|
retain_extraction_mode?: string | null;
|
||||||
|
/**
|
||||||
|
* Retain Custom Instructions
|
||||||
|
*
|
||||||
|
* Custom extraction prompt (when mode='custom')
|
||||||
|
*/
|
||||||
|
retain_custom_instructions?: string | null;
|
||||||
|
/**
|
||||||
|
* Retain Chunk Size
|
||||||
|
*
|
||||||
|
* Max token size for each content chunk
|
||||||
|
*/
|
||||||
|
retain_chunk_size?: number | null;
|
||||||
|
/**
|
||||||
|
* Enable Observations
|
||||||
|
*
|
||||||
|
* Toggle observation consolidation
|
||||||
|
*/
|
||||||
|
enable_observations?: boolean | null;
|
||||||
|
/**
|
||||||
|
* Observations Mission
|
||||||
|
*
|
||||||
|
* Controls what gets synthesised
|
||||||
|
*/
|
||||||
|
observations_mission?: string | null;
|
||||||
|
/**
|
||||||
|
* Disposition Skepticism
|
||||||
|
*
|
||||||
|
* Skepticism trait (1-5)
|
||||||
|
*/
|
||||||
|
disposition_skepticism?: number | null;
|
||||||
|
/**
|
||||||
|
* Disposition Literalism
|
||||||
|
*
|
||||||
|
* Literalism trait (1-5)
|
||||||
|
*/
|
||||||
|
disposition_literalism?: number | null;
|
||||||
|
/**
|
||||||
|
* Disposition Empathy
|
||||||
|
*
|
||||||
|
* Empathy trait (1-5)
|
||||||
|
*/
|
||||||
|
disposition_empathy?: number | null;
|
||||||
|
/**
|
||||||
|
* Entity Labels
|
||||||
|
*
|
||||||
|
* Controlled vocabulary for entity labels
|
||||||
|
*/
|
||||||
|
entity_labels?: Array<string> | null;
|
||||||
|
/**
|
||||||
|
* Entities Allow Free Form
|
||||||
|
*
|
||||||
|
* Allow entities outside the label vocabulary
|
||||||
|
*/
|
||||||
|
entities_allow_free_form?: boolean | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BankTemplateDirective
|
||||||
|
*
|
||||||
|
* A directive definition within a bank template manifest.
|
||||||
|
*
|
||||||
|
* Directives are matched by name on re-import: existing directives
|
||||||
|
* with the same name are updated, new ones are created.
|
||||||
|
*/
|
||||||
|
export type BankTemplateDirective = {
|
||||||
|
/**
|
||||||
|
* Name
|
||||||
|
*
|
||||||
|
* Human-readable name for the directive (used as match key on re-import)
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
/**
|
||||||
|
* Content
|
||||||
|
*
|
||||||
|
* The directive text to inject into prompts
|
||||||
|
*/
|
||||||
|
content: string;
|
||||||
|
/**
|
||||||
|
* Priority
|
||||||
|
*
|
||||||
|
* Higher priority directives are injected first
|
||||||
|
*/
|
||||||
|
priority?: number;
|
||||||
|
/**
|
||||||
|
* Is Active
|
||||||
|
*
|
||||||
|
* Whether this directive is active
|
||||||
|
*/
|
||||||
|
is_active?: boolean;
|
||||||
|
/**
|
||||||
|
* Tags
|
||||||
|
*
|
||||||
|
* Tags for filtering
|
||||||
|
*/
|
||||||
|
tags?: Array<string>;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BankTemplateImportResponse
|
||||||
|
*
|
||||||
|
* Response model for the bank template import endpoint.
|
||||||
|
*/
|
||||||
|
export type BankTemplateImportResponse = {
|
||||||
|
/**
|
||||||
|
* Bank Id
|
||||||
|
*
|
||||||
|
* Bank that was imported into
|
||||||
|
*/
|
||||||
|
bank_id: string;
|
||||||
|
/**
|
||||||
|
* Config Applied
|
||||||
|
*
|
||||||
|
* Whether bank config was updated
|
||||||
|
*/
|
||||||
|
config_applied: boolean;
|
||||||
|
/**
|
||||||
|
* Mental Models Created
|
||||||
|
*
|
||||||
|
* IDs of newly created mental models
|
||||||
|
*/
|
||||||
|
mental_models_created?: Array<string>;
|
||||||
|
/**
|
||||||
|
* Mental Models Updated
|
||||||
|
*
|
||||||
|
* IDs of updated mental models
|
||||||
|
*/
|
||||||
|
mental_models_updated?: Array<string>;
|
||||||
|
/**
|
||||||
|
* Directives Created
|
||||||
|
*
|
||||||
|
* Names of newly created directives
|
||||||
|
*/
|
||||||
|
directives_created?: Array<string>;
|
||||||
|
/**
|
||||||
|
* Directives Updated
|
||||||
|
*
|
||||||
|
* Names of updated directives
|
||||||
|
*/
|
||||||
|
directives_updated?: Array<string>;
|
||||||
|
/**
|
||||||
|
* Operation Ids
|
||||||
|
*
|
||||||
|
* Operation IDs for mental model content generation (async)
|
||||||
|
*/
|
||||||
|
operation_ids?: Array<string>;
|
||||||
|
/**
|
||||||
|
* Dry Run
|
||||||
|
*
|
||||||
|
* True if this was a validation-only run
|
||||||
|
*/
|
||||||
|
dry_run?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BankTemplateManifest
|
||||||
|
*
|
||||||
|
* A bank template manifest for import/export.
|
||||||
|
*
|
||||||
|
* Version field enables forward-compatible schema evolution: the API
|
||||||
|
* auto-upgrades older manifest versions to the current schema on import.
|
||||||
|
*/
|
||||||
|
export type BankTemplateManifest = {
|
||||||
|
/**
|
||||||
|
* Version
|
||||||
|
*
|
||||||
|
* Manifest schema version (currently '1')
|
||||||
|
*/
|
||||||
|
version: string;
|
||||||
|
/**
|
||||||
|
* Bank configuration to apply. Omit to leave config unchanged.
|
||||||
|
*/
|
||||||
|
bank?: BankTemplateConfig | null;
|
||||||
|
/**
|
||||||
|
* Mental Models
|
||||||
|
*
|
||||||
|
* Mental models to create or update (matched by id). Omit to leave unchanged.
|
||||||
|
*/
|
||||||
|
mental_models?: Array<BankTemplateMentalModel> | null;
|
||||||
|
/**
|
||||||
|
* Directives
|
||||||
|
*
|
||||||
|
* Directives to create or update (matched by name). Omit to leave unchanged.
|
||||||
|
*/
|
||||||
|
directives?: Array<BankTemplateDirective> | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BankTemplateMentalModel
|
||||||
|
*
|
||||||
|
* A mental model definition within a bank template manifest.
|
||||||
|
*/
|
||||||
|
export type BankTemplateMentalModel = {
|
||||||
|
/**
|
||||||
|
* Id
|
||||||
|
*
|
||||||
|
* Unique ID for the mental model (alphanumeric lowercase with hyphens)
|
||||||
|
*/
|
||||||
|
id: string;
|
||||||
|
/**
|
||||||
|
* Name
|
||||||
|
*
|
||||||
|
* Human-readable name for the mental model
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
/**
|
||||||
|
* Source Query
|
||||||
|
*
|
||||||
|
* The query to run to generate content
|
||||||
|
*/
|
||||||
|
source_query: string;
|
||||||
|
/**
|
||||||
|
* Tags
|
||||||
|
*
|
||||||
|
* Tags for scoped visibility
|
||||||
|
*/
|
||||||
|
tags?: Array<string>;
|
||||||
|
/**
|
||||||
|
* Max Tokens
|
||||||
|
*
|
||||||
|
* Maximum tokens for generated content
|
||||||
|
*/
|
||||||
|
max_tokens?: number;
|
||||||
|
/**
|
||||||
|
* Trigger settings
|
||||||
|
*/
|
||||||
|
trigger?: MentalModelTriggerOutput;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Body_file_retain
|
* Body_file_retain
|
||||||
*/
|
*/
|
||||||
|
|
@ -4536,6 +4791,103 @@ export type CreateOrUpdateBankResponses = {
|
||||||
export type CreateOrUpdateBankResponse =
|
export type CreateOrUpdateBankResponse =
|
||||||
CreateOrUpdateBankResponses[keyof CreateOrUpdateBankResponses];
|
CreateOrUpdateBankResponses[keyof CreateOrUpdateBankResponses];
|
||||||
|
|
||||||
|
export type ImportBankTemplateData = {
|
||||||
|
body?: never;
|
||||||
|
headers?: {
|
||||||
|
/**
|
||||||
|
* Authorization
|
||||||
|
*/
|
||||||
|
authorization?: string | null;
|
||||||
|
};
|
||||||
|
path: {
|
||||||
|
/**
|
||||||
|
* Bank Id
|
||||||
|
*/
|
||||||
|
bank_id: string;
|
||||||
|
};
|
||||||
|
query?: {
|
||||||
|
/**
|
||||||
|
* Dry Run
|
||||||
|
*
|
||||||
|
* Validate only, do not apply changes
|
||||||
|
*/
|
||||||
|
dry_run?: boolean;
|
||||||
|
};
|
||||||
|
url: "/v1/default/banks/{bank_id}/import";
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ImportBankTemplateErrors = {
|
||||||
|
/**
|
||||||
|
* Validation Error
|
||||||
|
*/
|
||||||
|
422: HttpValidationError;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ImportBankTemplateError =
|
||||||
|
ImportBankTemplateErrors[keyof ImportBankTemplateErrors];
|
||||||
|
|
||||||
|
export type ImportBankTemplateResponses = {
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
200: BankTemplateImportResponse;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ImportBankTemplateResponse =
|
||||||
|
ImportBankTemplateResponses[keyof ImportBankTemplateResponses];
|
||||||
|
|
||||||
|
export type ExportBankTemplateData = {
|
||||||
|
body?: never;
|
||||||
|
headers?: {
|
||||||
|
/**
|
||||||
|
* Authorization
|
||||||
|
*/
|
||||||
|
authorization?: string | null;
|
||||||
|
};
|
||||||
|
path: {
|
||||||
|
/**
|
||||||
|
* Bank Id
|
||||||
|
*/
|
||||||
|
bank_id: string;
|
||||||
|
};
|
||||||
|
query?: never;
|
||||||
|
url: "/v1/default/banks/{bank_id}/export";
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ExportBankTemplateErrors = {
|
||||||
|
/**
|
||||||
|
* Validation Error
|
||||||
|
*/
|
||||||
|
422: HttpValidationError;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ExportBankTemplateError =
|
||||||
|
ExportBankTemplateErrors[keyof ExportBankTemplateErrors];
|
||||||
|
|
||||||
|
export type ExportBankTemplateResponses = {
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
200: BankTemplateManifest;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ExportBankTemplateResponse =
|
||||||
|
ExportBankTemplateResponses[keyof ExportBankTemplateResponses];
|
||||||
|
|
||||||
|
export type GetBankTemplateSchemaData = {
|
||||||
|
body?: never;
|
||||||
|
path?: never;
|
||||||
|
query?: never;
|
||||||
|
url: "/v1/bank-template-schema";
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GetBankTemplateSchemaResponses = {
|
||||||
|
/**
|
||||||
|
* Successful Response
|
||||||
|
*/
|
||||||
|
200: unknown;
|
||||||
|
};
|
||||||
|
|
||||||
export type ClearObservationsData = {
|
export type ClearObservationsData = {
|
||||||
body?: never;
|
body?: never;
|
||||||
headers?: {
|
headers?: {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
import { DATAPLANE_URL, getDataplaneHeaders } from "@/lib/hindsight-client";
|
||||||
|
|
||||||
|
export async function GET(
|
||||||
|
request: NextRequest,
|
||||||
|
{ params }: { params: Promise<{ bankId: string }> }
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const { bankId } = await params;
|
||||||
|
|
||||||
|
const url = `${DATAPLANE_URL}/v1/default/banks/${encodeURIComponent(bankId)}/export`;
|
||||||
|
const response = await fetch(url, {
|
||||||
|
headers: getDataplaneHeaders(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
if (!response.ok) {
|
||||||
|
return NextResponse.json(data, { status: response.status });
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(data, { status: 200 });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error exporting bank template:", error);
|
||||||
|
return NextResponse.json({ error: "Failed to export bank template" }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import { NextRequest, NextResponse } from "next/server";
|
||||||
|
import { DATAPLANE_URL, getDataplaneHeaders } from "@/lib/hindsight-client";
|
||||||
|
|
||||||
|
export async function POST(
|
||||||
|
request: NextRequest,
|
||||||
|
{ params }: { params: Promise<{ bankId: string }> }
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const { bankId } = await params;
|
||||||
|
const body = await request.json();
|
||||||
|
const dryRun = request.nextUrl.searchParams.get("dry_run") === "true";
|
||||||
|
|
||||||
|
// Direct fetch since the SDK doesn't have this operation yet
|
||||||
|
const url = `${DATAPLANE_URL}/v1/default/banks/${encodeURIComponent(bankId)}/import${dryRun ? "?dry_run=true" : ""}`;
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: "POST",
|
||||||
|
headers: getDataplaneHeaders({ "Content-Type": "application/json" }),
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
if (!response.ok) {
|
||||||
|
return NextResponse.json(data, { status: response.status });
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json(data, { status: 200 });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error importing bank template:", error);
|
||||||
|
return NextResponse.json({ error: "Failed to import bank template" }, { status: 500 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -38,7 +38,7 @@ import {
|
||||||
AlertDialogHeader,
|
AlertDialogHeader,
|
||||||
AlertDialogTitle,
|
AlertDialogTitle,
|
||||||
} from "@/components/ui/alert-dialog";
|
} from "@/components/ui/alert-dialog";
|
||||||
import { Brain, Trash2, Loader2, MoreVertical, Pencil, RotateCcw } from "lucide-react";
|
import { Brain, Download, Trash2, Loader2, MoreVertical, Pencil, RotateCcw } from "lucide-react";
|
||||||
|
|
||||||
type NavItem = "recall" | "reflect" | "data" | "documents" | "entities" | "profile";
|
type NavItem = "recall" | "reflect" | "data" | "documents" | "entities" | "profile";
|
||||||
type DataSubTab = "world" | "experience" | "observations" | "mental-models";
|
type DataSubTab = "world" | "experience" | "observations" | "mental-models";
|
||||||
|
|
@ -182,6 +182,23 @@ export default function BankPage() {
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent align="end" className="w-48">
|
<DropdownMenuContent align="end" className="w-48">
|
||||||
|
<DropdownMenuItem
|
||||||
|
onClick={async () => {
|
||||||
|
if (!bankId) return;
|
||||||
|
try {
|
||||||
|
const manifest = await client.exportBankTemplate(bankId);
|
||||||
|
const json = JSON.stringify(manifest, null, 2);
|
||||||
|
await navigator.clipboard.writeText(json);
|
||||||
|
toast.success("Template copied to clipboard");
|
||||||
|
} catch {
|
||||||
|
toast.error("Failed to export template");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Download className="w-4 h-4 mr-2" />
|
||||||
|
Export Template
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
onClick={handleTriggerConsolidation}
|
onClick={handleTriggerConsolidation}
|
||||||
disabled={isConsolidating || !observationsEnabled}
|
disabled={isConsolidating || !observationsEnabled}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ import {
|
||||||
SelectTrigger,
|
SelectTrigger,
|
||||||
SelectValue,
|
SelectValue,
|
||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
|
import { Switch } from "@/components/ui/switch";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
function BankSelectorInner() {
|
function BankSelectorInner() {
|
||||||
|
|
@ -61,6 +62,9 @@ function BankSelectorInner() {
|
||||||
const [newBankId, setNewBankId] = React.useState("");
|
const [newBankId, setNewBankId] = React.useState("");
|
||||||
const [isCreating, setIsCreating] = React.useState(false);
|
const [isCreating, setIsCreating] = React.useState(false);
|
||||||
const [createError, setCreateError] = React.useState<string | null>(null);
|
const [createError, setCreateError] = React.useState<string | null>(null);
|
||||||
|
const [useTemplate, setUseTemplate] = React.useState(false);
|
||||||
|
const [templateJson, setTemplateJson] = React.useState("");
|
||||||
|
const [templateError, setTemplateError] = React.useState<string | null>(null);
|
||||||
|
|
||||||
// Document creation state
|
// Document creation state
|
||||||
const [docDialogOpen, setDocDialogOpen] = React.useState(false);
|
const [docDialogOpen, setDocDialogOpen] = React.useState(false);
|
||||||
|
|
@ -137,12 +141,39 @@ function BankSelectorInner() {
|
||||||
|
|
||||||
setIsCreating(true);
|
setIsCreating(true);
|
||||||
setCreateError(null);
|
setCreateError(null);
|
||||||
|
setTemplateError(null);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Create the bank first
|
||||||
await client.createBank(newBankId.trim());
|
await client.createBank(newBankId.trim());
|
||||||
|
|
||||||
|
// If template JSON is provided, import it
|
||||||
|
if (templateJson.trim()) {
|
||||||
|
let manifest: Record<string, unknown>;
|
||||||
|
try {
|
||||||
|
manifest = JSON.parse(templateJson.trim());
|
||||||
|
} catch {
|
||||||
|
setTemplateError("Invalid JSON. Please check the template syntax.");
|
||||||
|
setIsCreating(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await client.importBankTemplate(newBankId.trim(), manifest);
|
||||||
|
} catch (importError) {
|
||||||
|
setTemplateError(
|
||||||
|
importError instanceof Error ? importError.message : "Failed to import template"
|
||||||
|
);
|
||||||
|
setIsCreating(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await loadBanks();
|
await loadBanks();
|
||||||
setCreateDialogOpen(false);
|
setCreateDialogOpen(false);
|
||||||
setNewBankId("");
|
setNewBankId("");
|
||||||
|
setTemplateJson("");
|
||||||
|
setTemplateError(null);
|
||||||
// Navigate to the new bank
|
// Navigate to the new bank
|
||||||
setCurrentBank(newBankId.trim());
|
setCurrentBank(newBankId.trim());
|
||||||
router.push(`/banks/${newBankId.trim()}?view=data`);
|
router.push(`/banks/${newBankId.trim()}?view=data`);
|
||||||
|
|
@ -475,6 +506,7 @@ function BankSelectorInner() {
|
||||||
className="h-9 gap-1.5"
|
className="h-9 gap-1.5"
|
||||||
onClick={() => setDocDialogOpen(true)}
|
onClick={() => setDocDialogOpen(true)}
|
||||||
title="Add document to current bank"
|
title="Add document to current bank"
|
||||||
|
data-add-document
|
||||||
>
|
>
|
||||||
<Plus className="h-4 w-4" />
|
<Plus className="h-4 w-4" />
|
||||||
<span>Add Document</span>
|
<span>Add Document</span>
|
||||||
|
|
@ -511,23 +543,68 @@ function BankSelectorInner() {
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Dialog open={createDialogOpen} onOpenChange={setCreateDialogOpen}>
|
<Dialog open={createDialogOpen} onOpenChange={setCreateDialogOpen}>
|
||||||
<DialogContent className="sm:max-w-[425px]">
|
<DialogContent className="sm:max-w-[550px]">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Create New Memory Bank</DialogTitle>
|
<DialogTitle>Create New Memory Bank</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="py-4">
|
<div className="py-4 space-y-4">
|
||||||
<Input
|
<Input
|
||||||
placeholder="Enter bank ID..."
|
placeholder="Enter bank ID..."
|
||||||
value={newBankId}
|
value={newBankId}
|
||||||
onChange={(e) => setNewBankId(e.target.value)}
|
onChange={(e) => setNewBankId(e.target.value)}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === "Enter" && !isCreating) {
|
if (e.key === "Enter" && !isCreating && !useTemplate) {
|
||||||
handleCreateBank();
|
handleCreateBank();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
autoFocus
|
autoFocus
|
||||||
/>
|
/>
|
||||||
{createError && <p className="text-sm text-destructive mt-2">{createError}</p>}
|
<div className="flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<Switch
|
||||||
|
checked={useTemplate}
|
||||||
|
onCheckedChange={(checked) => {
|
||||||
|
setUseTemplate(checked);
|
||||||
|
if (!checked) {
|
||||||
|
setTemplateJson("");
|
||||||
|
setTemplateError(null);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<label className="text-sm font-medium">Import from template</label>
|
||||||
|
</div>
|
||||||
|
{useTemplate && (
|
||||||
|
<a
|
||||||
|
href="https://hindsight.vectorize.io/templates"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-xs text-muted-foreground hover:text-foreground transition-colors"
|
||||||
|
>
|
||||||
|
Browse templates →
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{useTemplate && (
|
||||||
|
<div>
|
||||||
|
<p className="text-xs text-muted-foreground mb-2">
|
||||||
|
Paste a template manifest JSON to pre-configure the bank with settings, mental
|
||||||
|
models, and directives.
|
||||||
|
</p>
|
||||||
|
<Textarea
|
||||||
|
placeholder='{"version": "1", "bank": {...}, "mental_models": [...]}'
|
||||||
|
value={templateJson}
|
||||||
|
onChange={(e) => {
|
||||||
|
setTemplateJson(e.target.value);
|
||||||
|
setTemplateError(null);
|
||||||
|
}}
|
||||||
|
className="font-mono text-xs min-h-[120px]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{templateError && (
|
||||||
|
<p className="text-sm text-destructive whitespace-pre-wrap">{templateError}</p>
|
||||||
|
)}
|
||||||
|
{createError && <p className="text-sm text-destructive">{createError}</p>}
|
||||||
</div>
|
</div>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
<Button
|
<Button
|
||||||
|
|
@ -535,7 +612,10 @@ function BankSelectorInner() {
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setCreateDialogOpen(false);
|
setCreateDialogOpen(false);
|
||||||
setNewBankId("");
|
setNewBankId("");
|
||||||
|
setUseTemplate(false);
|
||||||
|
setTemplateJson("");
|
||||||
setCreateError(null);
|
setCreateError(null);
|
||||||
|
setTemplateError(null);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ import { MemoryDetailPanel } from "./memory-detail-panel";
|
||||||
import { MemoryDetailModal } from "./memory-detail-modal";
|
import { MemoryDetailModal } from "./memory-detail-modal";
|
||||||
import { Graph2D, convertHindsightGraphData, GraphNode } from "./graph-2d";
|
import { Graph2D, convertHindsightGraphData, GraphNode } from "./graph-2d";
|
||||||
import { Constellation } from "./constellation";
|
import { Constellation } from "./constellation";
|
||||||
import { ScatterChart } from "lucide-react";
|
import { ScatterChart, Plus, FileText } from "lucide-react";
|
||||||
|
|
||||||
type FactType = "world" | "experience" | "observation";
|
type FactType = "world" | "experience" | "observation";
|
||||||
type ViewMode = "graph" | "table" | "timeline" | "constellation";
|
type ViewMode = "graph" | "table" | "timeline" | "constellation";
|
||||||
|
|
@ -273,6 +273,26 @@ export function DataView({ factType }: DataViewProps) {
|
||||||
<RefreshCw className="w-8 h-8 mx-auto mb-3 text-muted-foreground animate-spin" />
|
<RefreshCw className="w-8 h-8 mx-auto mb-3 text-muted-foreground animate-spin" />
|
||||||
<p className="text-muted-foreground">Loading memories...</p>
|
<p className="text-muted-foreground">Loading memories...</p>
|
||||||
</div>
|
</div>
|
||||||
|
) : data && data.total_units === 0 ? (
|
||||||
|
<div className="text-center py-20">
|
||||||
|
<FileText className="w-10 h-10 mx-auto mb-4 text-muted-foreground/50" />
|
||||||
|
<h3 className="text-base font-medium text-foreground mb-1">No memories yet</h3>
|
||||||
|
<p className="text-sm text-muted-foreground mb-6">
|
||||||
|
Add a document to start building this memory bank.
|
||||||
|
</p>
|
||||||
|
<Button
|
||||||
|
variant="default"
|
||||||
|
size="sm"
|
||||||
|
className="gap-1.5"
|
||||||
|
onClick={() => {
|
||||||
|
const btn = document.querySelector<HTMLButtonElement>("[data-add-document]");
|
||||||
|
btn?.click();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Plus className="w-4 h-4" />
|
||||||
|
Add Document
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
) : data ? (
|
) : data ? (
|
||||||
<>
|
<>
|
||||||
{/* Always visible filters */}
|
{/* Always visible filters */}
|
||||||
|
|
|
||||||
|
|
@ -102,6 +102,15 @@ export interface MentalModel {
|
||||||
reflect_response?: any;
|
reflect_response?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface BankTemplateImportResponse {
|
||||||
|
bank_id: string;
|
||||||
|
config_applied: boolean;
|
||||||
|
mental_models_created: string[];
|
||||||
|
mental_models_updated: string[];
|
||||||
|
operation_ids: string[];
|
||||||
|
dry_run: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export class ControlPlaneClient {
|
export class ControlPlaneClient {
|
||||||
private async fetchApi<T>(path: string, options?: RequestInit): Promise<T> {
|
private async fetchApi<T>(path: string, options?: RequestInit): Promise<T> {
|
||||||
try {
|
try {
|
||||||
|
|
@ -195,6 +204,24 @@ export class ControlPlaneClient {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import a bank template manifest
|
||||||
|
*/
|
||||||
|
async importBankTemplate(bankId: string, manifest: Record<string, unknown>, dryRun = false) {
|
||||||
|
const params = dryRun ? "?dry_run=true" : "";
|
||||||
|
return this.fetchApi<BankTemplateImportResponse>(`/api/banks/${bankId}/import${params}`, {
|
||||||
|
method: "POST",
|
||||||
|
body: JSON.stringify(manifest),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export a bank as a template manifest
|
||||||
|
*/
|
||||||
|
async exportBankTemplate(bankId: string) {
|
||||||
|
return this.fetchApi<Record<string, unknown>>(`/api/banks/${bankId}/export`);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recall memories
|
* Recall memories
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -393,6 +393,7 @@ class BenchmarkRunner:
|
||||||
self.dataset = dataset
|
self.dataset = dataset
|
||||||
self.answer_generator = answer_generator
|
self.answer_generator = answer_generator
|
||||||
self.answer_evaluator = answer_evaluator
|
self.answer_evaluator = answer_evaluator
|
||||||
|
self.template_path: Optional[str] = None
|
||||||
self.memory = memory or MemoryEngine(
|
self.memory = memory or MemoryEngine(
|
||||||
db_url=os.getenv("HINDSIGHT_API_DATABASE_URL", "pg0"),
|
db_url=os.getenv("HINDSIGHT_API_DATABASE_URL", "pg0"),
|
||||||
memory_llm_provider=os.getenv("HINDSIGHT_API_LLM_PROVIDER", "groq"),
|
memory_llm_provider=os.getenv("HINDSIGHT_API_LLM_PROVIDER", "groq"),
|
||||||
|
|
@ -432,6 +433,58 @@ class BenchmarkRunner:
|
||||||
"max_session_length": max(session_lengths) if session_lengths else 0,
|
"max_session_length": max(session_lengths) if session_lengths else 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async def apply_template(self, bank_id: str, manifest_path: str) -> None:
|
||||||
|
"""Apply a bank template manifest to a bank before ingestion.
|
||||||
|
|
||||||
|
Reads the manifest JSON file and applies config overrides, creates
|
||||||
|
mental models and directives — same logic as the /import API endpoint.
|
||||||
|
"""
|
||||||
|
from hindsight_api.api.http import BankTemplateManifest
|
||||||
|
from hindsight_api.models import RequestContext
|
||||||
|
|
||||||
|
raw = json.loads(Path(manifest_path).read_text())
|
||||||
|
manifest = BankTemplateManifest.model_validate(raw)
|
||||||
|
|
||||||
|
request_context = RequestContext()
|
||||||
|
await self.memory.get_bank_profile(bank_id, request_context=request_context)
|
||||||
|
|
||||||
|
# Apply bank config overrides
|
||||||
|
if manifest.bank:
|
||||||
|
config_updates = manifest.bank.get_config_updates()
|
||||||
|
if config_updates:
|
||||||
|
await self.memory._config_resolver.update_bank_config(bank_id, config_updates, request_context)
|
||||||
|
|
||||||
|
# Create directives
|
||||||
|
for directive in manifest.directives or []:
|
||||||
|
await self.memory.create_directive(
|
||||||
|
bank_id=bank_id,
|
||||||
|
name=directive.name,
|
||||||
|
content=directive.content,
|
||||||
|
priority=directive.priority,
|
||||||
|
is_active=directive.is_active,
|
||||||
|
tags=directive.tags if directive.tags else None,
|
||||||
|
request_context=request_context,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create mental models (async content generation)
|
||||||
|
for mm in manifest.mental_models or []:
|
||||||
|
mental_model = await self.memory.create_mental_model(
|
||||||
|
bank_id=bank_id,
|
||||||
|
name=mm.name,
|
||||||
|
source_query=mm.source_query,
|
||||||
|
content="Generating content...",
|
||||||
|
mental_model_id=mm.id,
|
||||||
|
tags=mm.tags if mm.tags else None,
|
||||||
|
max_tokens=mm.max_tokens,
|
||||||
|
trigger=mm.trigger.model_dump() if mm.trigger else None,
|
||||||
|
request_context=request_context,
|
||||||
|
)
|
||||||
|
await self.memory.submit_async_refresh_mental_model(
|
||||||
|
bank_id=bank_id,
|
||||||
|
mental_model_id=mental_model["id"],
|
||||||
|
request_context=request_context,
|
||||||
|
)
|
||||||
|
|
||||||
async def ingest_conversation(
|
async def ingest_conversation(
|
||||||
self, item: Dict[str, Any], agent_id: str, wait_for_consolidation: bool = False
|
self, item: Dict[str, Any], agent_id: str, wait_for_consolidation: bool = False
|
||||||
) -> int:
|
) -> int:
|
||||||
|
|
@ -872,6 +925,13 @@ class BenchmarkRunner:
|
||||||
await self.memory.delete_bank(agent_id, request_context=RequestContext())
|
await self.memory.delete_bank(agent_id, request_context=RequestContext())
|
||||||
console.print(f" [green]✓[/green] Cleared '{agent_id}' agent data")
|
console.print(f" [green]✓[/green] Cleared '{agent_id}' agent data")
|
||||||
|
|
||||||
|
# Apply template if configured
|
||||||
|
if self.template_path:
|
||||||
|
step += 1
|
||||||
|
console.print(f" [{step}] Applying bank template...")
|
||||||
|
await self.apply_template(agent_id, self.template_path)
|
||||||
|
console.print(" [green]✓[/green] Template applied")
|
||||||
|
|
||||||
# Ingest conversation
|
# Ingest conversation
|
||||||
step += 1
|
step += 1
|
||||||
console.print(f" [{step}] Ingesting conversation (batch mode)...")
|
console.print(f" [{step}] Ingesting conversation (batch mode)...")
|
||||||
|
|
@ -930,6 +990,7 @@ class BenchmarkRunner:
|
||||||
output_path: Optional[Path] = None, # Path to save results incrementally
|
output_path: Optional[Path] = None, # Path to save results incrementally
|
||||||
merge_with_existing: bool = False, # Whether to merge with existing results
|
merge_with_existing: bool = False, # Whether to merge with existing results
|
||||||
wait_consolidation: bool = False, # Wait for consolidation to complete before evaluating QA
|
wait_consolidation: bool = False, # Wait for consolidation to complete before evaluating QA
|
||||||
|
template_path: Optional[str] = None, # Path to a bank template manifest to apply before ingestion
|
||||||
) -> Dict[str, Any]:
|
) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
Run the full benchmark evaluation.
|
Run the full benchmark evaluation.
|
||||||
|
|
@ -975,6 +1036,9 @@ class BenchmarkRunner:
|
||||||
|
|
||||||
# Initialize memory system
|
# Initialize memory system
|
||||||
console.print("\n[2] Initializing memory system...")
|
console.print("\n[2] Initializing memory system...")
|
||||||
|
if template_path:
|
||||||
|
self.template_path = template_path
|
||||||
|
console.print(f" Bank template: {template_path}")
|
||||||
console.print(" [green]✓[/green] Memory system initialized")
|
console.print(" [green]✓[/green] Memory system initialized")
|
||||||
|
|
||||||
if separate_ingestion_phase:
|
if separate_ingestion_phase:
|
||||||
|
|
@ -1288,6 +1352,12 @@ class BenchmarkRunner:
|
||||||
await self.memory.delete_bank(agent_id, request_context=RequestContext())
|
await self.memory.delete_bank(agent_id, request_context=RequestContext())
|
||||||
console.print(" [green]✓[/green] Cleared agent data")
|
console.print(" [green]✓[/green] Cleared agent data")
|
||||||
|
|
||||||
|
# Apply template if configured
|
||||||
|
if self.template_path:
|
||||||
|
console.print(" [yellow]Applying bank template...[/yellow]")
|
||||||
|
await self.apply_template(agent_id, self.template_path)
|
||||||
|
console.print(" [green]✓[/green] Template applied")
|
||||||
|
|
||||||
# Collect all sessions and send in one batch (with auto-chunking)
|
# Collect all sessions and send in one batch (with auto-chunking)
|
||||||
console.print(" [yellow]Collecting sessions from all items...[/yellow]")
|
console.print(" [yellow]Collecting sessions from all items...[/yellow]")
|
||||||
all_sessions = []
|
all_sessions = []
|
||||||
|
|
|
||||||
|
|
@ -306,6 +306,7 @@ async def run_benchmark(
|
||||||
only_invalid: bool = False,
|
only_invalid: bool = False,
|
||||||
question_index: int = None,
|
question_index: int = None,
|
||||||
wait_consolidation: bool = False,
|
wait_consolidation: bool = False,
|
||||||
|
template_path: str = None,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Run the LoComo benchmark.
|
Run the LoComo benchmark.
|
||||||
|
|
@ -473,6 +474,7 @@ async def run_benchmark(
|
||||||
output_path=output_path, # Save results incrementally
|
output_path=output_path, # Save results incrementally
|
||||||
merge_with_existing=merge_with_existing,
|
merge_with_existing=merge_with_existing,
|
||||||
wait_consolidation=wait_consolidation,
|
wait_consolidation=wait_consolidation,
|
||||||
|
template_path=template_path,
|
||||||
)
|
)
|
||||||
|
|
||||||
# Display results (final save already happened incrementally)
|
# Display results (final save already happened incrementally)
|
||||||
|
|
@ -608,6 +610,12 @@ if __name__ == "__main__":
|
||||||
action="store_true",
|
action="store_true",
|
||||||
help="Wait for consolidation to complete after ingestion (or immediately when using --skip-ingestion) before evaluating QA.",
|
help="Wait for consolidation to complete after ingestion (or immediately when using --skip-ingestion) before evaluating QA.",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--template",
|
||||||
|
type=str,
|
||||||
|
default=None,
|
||||||
|
help="Path to a bank template manifest JSON to apply before ingestion (sets config, mental models, directives)",
|
||||||
|
)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
|
@ -628,5 +636,6 @@ if __name__ == "__main__":
|
||||||
only_invalid=args.only_invalid,
|
only_invalid=args.only_invalid,
|
||||||
question_index=args.question_index,
|
question_index=args.question_index,
|
||||||
wait_consolidation=args.wait_consolidation,
|
wait_consolidation=args.wait_consolidation,
|
||||||
|
template_path=args.template,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
251
hindsight-docs/docs/developer/api/bank-templates.mdx
Normal file
251
hindsight-docs/docs/developer/api/bank-templates.mdx
Normal file
|
|
@ -0,0 +1,251 @@
|
||||||
|
---
|
||||||
|
sidebar_position: 9
|
||||||
|
---
|
||||||
|
|
||||||
|
# Bank Templates
|
||||||
|
|
||||||
|
Declarative JSON manifests for creating pre-configured memory banks with a single API call.
|
||||||
|
|
||||||
|
import Tabs from '@theme/Tabs';
|
||||||
|
import TabItem from '@theme/TabItem';
|
||||||
|
import CodeSnippet from '@site/src/components/CodeSnippet';
|
||||||
|
|
||||||
|
{/* Import raw source files */}
|
||||||
|
import templatesPy from '!!raw-loader!@site/examples/api/bank-templates.py';
|
||||||
|
import templatesMjs from '!!raw-loader!@site/examples/api/bank-templates.mjs';
|
||||||
|
import templatesSh from '!!raw-loader!@site/examples/api/bank-templates.sh';
|
||||||
|
import templatesGo from '!!raw-loader!@site/examples/api/bank-templates.go';
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
A bank template is a JSON manifest that describes a bank's full setup: configuration overrides, mental models, directives, and more. Instead of making multiple API calls to configure a bank, you submit one manifest and the API provisions everything.
|
||||||
|
|
||||||
|
Templates are useful for:
|
||||||
|
- **Replication** — stamp out identically-configured banks for multiple users or agents
|
||||||
|
- **Onboarding** — new users start with a known-good configuration instead of configuring from scratch
|
||||||
|
- **Sharing** — distribute recommended setups as portable JSON files
|
||||||
|
- **Framework integrations** — ship a recommended template alongside your integration
|
||||||
|
|
||||||
|
Browse the [Bank Templates Hub](/templates) for ready-to-use templates.
|
||||||
|
|
||||||
|
## Manifest Schema
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"version": "1",
|
||||||
|
"bank": {
|
||||||
|
"reflect_mission": "...",
|
||||||
|
"retain_mission": "...",
|
||||||
|
"retain_extraction_mode": "concise | verbose | custom | chunks",
|
||||||
|
"retain_custom_instructions": "...",
|
||||||
|
"retain_chunk_size": 2048,
|
||||||
|
"disposition_skepticism": 3,
|
||||||
|
"disposition_literalism": 3,
|
||||||
|
"disposition_empathy": 3,
|
||||||
|
"enable_observations": true,
|
||||||
|
"observations_mission": "...",
|
||||||
|
"entity_labels": ["PERSON", "ORGANIZATION"],
|
||||||
|
"entities_allow_free_form": true
|
||||||
|
},
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "unique-lowercase-id",
|
||||||
|
"name": "Human-Readable Name",
|
||||||
|
"source_query": "The query that generates this mental model's content",
|
||||||
|
"tags": ["optional", "tags"],
|
||||||
|
"max_tokens": 2048,
|
||||||
|
"trigger": {
|
||||||
|
"refresh_after_consolidation": false,
|
||||||
|
"fact_types": ["world", "experience", "observation"],
|
||||||
|
"exclude_mental_models": false,
|
||||||
|
"exclude_mental_model_ids": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"directives": [
|
||||||
|
{
|
||||||
|
"name": "directive-name",
|
||||||
|
"content": "The directive instruction text",
|
||||||
|
"priority": 0,
|
||||||
|
"is_active": true,
|
||||||
|
"tags": ["optional", "tags"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fields
|
||||||
|
|
||||||
|
| Field | Required | Description |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| `version` | Yes | Schema version. Currently `"1"`. |
|
||||||
|
| `bank` | No | Bank configuration overrides. Omit to leave config unchanged. |
|
||||||
|
| `mental_models` | No | Mental models to create or update. Omit to leave unchanged. |
|
||||||
|
| `directives` | No | Directives to create or update. Omit to leave unchanged. |
|
||||||
|
|
||||||
|
All of `bank`, `mental_models`, and `directives` are optional. Omit any section to leave that part of the bank unchanged.
|
||||||
|
|
||||||
|
### Bank Config Fields
|
||||||
|
|
||||||
|
All fields in `bank` are optional. Only the fields you include will be set as per-bank overrides — everything else inherits from the server/tenant defaults.
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-------|------|-------------|
|
||||||
|
| `reflect_mission` | string | Mission/context for reflect operations |
|
||||||
|
| `retain_mission` | string | Steers what gets extracted during retain |
|
||||||
|
| `retain_extraction_mode` | string | `concise`, `verbose`, `custom`, or `chunks` |
|
||||||
|
| `retain_custom_instructions` | string | Custom extraction prompt (requires `mode=custom`) |
|
||||||
|
| `retain_chunk_size` | integer | Max token size per content chunk |
|
||||||
|
| `disposition_skepticism` | integer (1-5) | How skeptical the disposition is |
|
||||||
|
| `disposition_literalism` | integer (1-5) | How literal the disposition is |
|
||||||
|
| `disposition_empathy` | integer (1-5) | How empathetic the disposition is |
|
||||||
|
| `enable_observations` | boolean | Toggle observation consolidation |
|
||||||
|
| `observations_mission` | string | Controls what gets synthesised into observations |
|
||||||
|
| `entity_labels` | string[] | Controlled vocabulary for entity labels |
|
||||||
|
| `entities_allow_free_form` | boolean | Allow entities outside the label vocabulary |
|
||||||
|
|
||||||
|
### Mental Model Fields
|
||||||
|
|
||||||
|
| Field | Required | Description |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| `id` | Yes | Unique ID (lowercase alphanumeric with hyphens). Used to match on re-import. |
|
||||||
|
| `name` | Yes | Human-readable name |
|
||||||
|
| `source_query` | Yes | The query that generates this model's content via reflect |
|
||||||
|
| `tags` | No | Tags for scoped visibility. Default: `[]` |
|
||||||
|
| `max_tokens` | No | Max tokens for generated content (256-8192). Default: `2048` |
|
||||||
|
| `trigger` | No | Trigger settings for auto-refresh |
|
||||||
|
|
||||||
|
### Directive Fields
|
||||||
|
|
||||||
|
| Field | Required | Description |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| `name` | Yes | Directive name. Used as the match key on re-import. |
|
||||||
|
| `content` | Yes | The directive instruction text. |
|
||||||
|
| `priority` | No | Priority value (higher = more important). Default: `0` |
|
||||||
|
| `is_active` | No | Whether the directive is active. Default: `true` |
|
||||||
|
| `tags` | No | Tags for categorization. Default: `[]` |
|
||||||
|
|
||||||
|
## Import
|
||||||
|
|
||||||
|
Import a manifest into a bank. If the bank doesn't exist, it's created automatically.
|
||||||
|
|
||||||
|
<Tabs>
|
||||||
|
<TabItem value="python" label="Python">
|
||||||
|
<CodeSnippet code={templatesPy} section="import-template" language="python" />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="node" label="Node.js">
|
||||||
|
<CodeSnippet code={templatesMjs} section="import-template" language="javascript" />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="cli" label="CLI">
|
||||||
|
<CodeSnippet code={templatesSh} section="import-template" language="bash" />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="go" label="Go">
|
||||||
|
<CodeSnippet code={templatesGo} section="import-template" language="go" />
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
### Behavior
|
||||||
|
|
||||||
|
- **Config**: all `bank` fields are applied as per-bank config overrides
|
||||||
|
- **Mental models**: matched by `id` — existing models are updated, new ones are created
|
||||||
|
- **Directives**: matched by `name` — existing directives are updated, new ones are created
|
||||||
|
- **Async**: mental model content is generated asynchronously. The response includes `operation_ids` to track progress.
|
||||||
|
|
||||||
|
### Dry Run
|
||||||
|
|
||||||
|
Validate a manifest without applying changes:
|
||||||
|
|
||||||
|
<Tabs>
|
||||||
|
<TabItem value="python" label="Python">
|
||||||
|
<CodeSnippet code={templatesPy} section="import-dry-run" language="python" />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="node" label="Node.js">
|
||||||
|
<CodeSnippet code={templatesMjs} section="import-dry-run" language="javascript" />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="cli" label="CLI">
|
||||||
|
<CodeSnippet code={templatesSh} section="import-dry-run" language="bash" />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="go" label="Go">
|
||||||
|
<CodeSnippet code={templatesGo} section="import-dry-run" language="go" />
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
Returns what *would* happen (which config would be applied, which mental models would be created) without making any changes. Returns HTTP 400 with a detailed error message if the manifest is invalid.
|
||||||
|
|
||||||
|
## Export
|
||||||
|
|
||||||
|
Export a bank's current config overrides, mental models, and directives as a manifest:
|
||||||
|
|
||||||
|
<Tabs>
|
||||||
|
<TabItem value="python" label="Python">
|
||||||
|
<CodeSnippet code={templatesPy} section="export-template" language="python" />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="node" label="Node.js">
|
||||||
|
<CodeSnippet code={templatesMjs} section="export-template" language="javascript" />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="cli" label="CLI">
|
||||||
|
<CodeSnippet code={templatesSh} section="export-template" language="bash" />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="go" label="Go">
|
||||||
|
<CodeSnippet code={templatesGo} section="export-template" language="go" />
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
The exported manifest only includes config fields that were explicitly set as per-bank overrides — not the fully resolved config (which includes server/tenant defaults). This means the exported manifest is portable: importing it into a new bank only overrides the fields that were intentionally customized.
|
||||||
|
|
||||||
|
### Round-trip
|
||||||
|
|
||||||
|
Export from one bank and import into another to replicate the setup:
|
||||||
|
|
||||||
|
<Tabs>
|
||||||
|
<TabItem value="python" label="Python">
|
||||||
|
<CodeSnippet code={templatesPy} section="export-reimport" language="python" />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="node" label="Node.js">
|
||||||
|
<CodeSnippet code={templatesMjs} section="export-reimport" language="javascript" />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="cli" label="CLI">
|
||||||
|
<CodeSnippet code={templatesSh} section="export-reimport" language="bash" />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="go" label="Go">
|
||||||
|
<CodeSnippet code={templatesGo} section="export-reimport" language="go" />
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
## JSON Schema
|
||||||
|
|
||||||
|
The manifest format is defined by a JSON Schema. Fetch the live schema from your server:
|
||||||
|
|
||||||
|
<Tabs>
|
||||||
|
<TabItem value="python" label="Python">
|
||||||
|
<CodeSnippet code={templatesPy} section="get-schema" language="python" />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="node" label="Node.js">
|
||||||
|
<CodeSnippet code={templatesMjs} section="get-schema" language="javascript" />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="cli" label="CLI">
|
||||||
|
<CodeSnippet code={templatesSh} section="get-schema" language="bash" />
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="go" label="Go">
|
||||||
|
<CodeSnippet code={templatesGo} section="get-schema" language="go" />
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|
||||||
|
The static schema is also available at [bank-template-schema.json](/bank-template-schema.json).
|
||||||
|
|
||||||
|
## Control Plane
|
||||||
|
|
||||||
|
The control plane bank creation dialog includes an optional "Import from template" toggle. Enable it to paste a manifest JSON and pre-configure the bank on creation.
|
||||||
|
|
||||||
|
You can also export any bank's template from the bank Settings page via **Actions → Export Template**, which copies the manifest JSON to your clipboard.
|
||||||
|
|
||||||
|
## Versioning
|
||||||
|
|
||||||
|
The `version` field enables forward-compatible schema evolution. The current version is `"1"`.
|
||||||
|
|
||||||
|
When future versions are released:
|
||||||
|
- Older manifests are automatically upgraded to the current schema on import
|
||||||
|
- Export always produces the latest version
|
||||||
|
- The API rejects manifests with a version newer than what the server supports (with a clear error message suggesting an upgrade)
|
||||||
|
|
||||||
|
This means old templates keep working indefinitely — no need to manually update them.
|
||||||
|
|
@ -226,6 +226,11 @@ const config: Config = {
|
||||||
position: 'left',
|
position: 'left',
|
||||||
className: 'navbar-item-resources',
|
className: 'navbar-item-resources',
|
||||||
items: [
|
items: [
|
||||||
|
{
|
||||||
|
to: '/templates',
|
||||||
|
label: 'Bank Templates Hub',
|
||||||
|
customProps: { icon: 'lu-layout-template' },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
to: '/best-practices',
|
to: '/best-practices',
|
||||||
label: 'Best Practices',
|
label: 'Best Practices',
|
||||||
|
|
|
||||||
97
hindsight-docs/examples/api/bank-templates.go
Normal file
97
hindsight-docs/examples/api/bank-templates.go
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
apiURL := os.Getenv("HINDSIGHT_API_URL")
|
||||||
|
if apiURL == "" {
|
||||||
|
apiURL = "http://localhost:8888"
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Doc Examples
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
// [docs:import-template]
|
||||||
|
template := map[string]interface{}{
|
||||||
|
"version": "1",
|
||||||
|
"bank": map[string]interface{}{
|
||||||
|
"retain_mission": "Extract customer issues, resolutions, and sentiment.",
|
||||||
|
"enable_observations": true,
|
||||||
|
"observations_mission": "Track recurring customer pain points.",
|
||||||
|
},
|
||||||
|
"mental_models": []map[string]interface{}{
|
||||||
|
{
|
||||||
|
"id": "sentiment-overview",
|
||||||
|
"name": "Customer Sentiment Overview",
|
||||||
|
"source_query": "What is the overall sentiment trend?",
|
||||||
|
"trigger": map[string]interface{}{"refresh_after_consolidation": true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"directives": []map[string]interface{}{
|
||||||
|
{
|
||||||
|
"name": "Acknowledge frustration",
|
||||||
|
"content": "Always acknowledge frustration before offering solutions.",
|
||||||
|
"priority": 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
body, _ := json.Marshal(template)
|
||||||
|
resp, _ := http.Post(
|
||||||
|
apiURL+"/v1/default/banks/my-bank/import",
|
||||||
|
"application/json",
|
||||||
|
bytes.NewReader(body),
|
||||||
|
)
|
||||||
|
defer resp.Body.Close()
|
||||||
|
respBody, _ := io.ReadAll(resp.Body)
|
||||||
|
fmt.Println(string(respBody))
|
||||||
|
// [/docs:import-template]
|
||||||
|
|
||||||
|
// [docs:import-dry-run]
|
||||||
|
resp, _ = http.Post(
|
||||||
|
apiURL+"/v1/default/banks/my-bank/import?dry_run=true",
|
||||||
|
"application/json",
|
||||||
|
bytes.NewReader(body),
|
||||||
|
)
|
||||||
|
defer resp.Body.Close()
|
||||||
|
dryRunBody, _ := io.ReadAll(resp.Body)
|
||||||
|
fmt.Println(string(dryRunBody))
|
||||||
|
// [/docs:import-dry-run]
|
||||||
|
|
||||||
|
// [docs:export-template]
|
||||||
|
resp, _ = http.Get(apiURL + "/v1/default/banks/my-bank/export")
|
||||||
|
defer resp.Body.Close()
|
||||||
|
exported, _ := io.ReadAll(resp.Body)
|
||||||
|
fmt.Println(string(exported))
|
||||||
|
// [/docs:export-template]
|
||||||
|
|
||||||
|
// [docs:export-reimport]
|
||||||
|
// Export from source bank
|
||||||
|
resp, _ = http.Get(apiURL + "/v1/default/banks/source-bank/export")
|
||||||
|
defer resp.Body.Close()
|
||||||
|
srcExported, _ := io.ReadAll(resp.Body)
|
||||||
|
|
||||||
|
// Import into a new bank
|
||||||
|
resp, _ = http.Post(
|
||||||
|
apiURL+"/v1/default/banks/new-bank/import",
|
||||||
|
"application/json",
|
||||||
|
bytes.NewReader(srcExported),
|
||||||
|
)
|
||||||
|
defer resp.Body.Close()
|
||||||
|
// [/docs:export-reimport]
|
||||||
|
|
||||||
|
// [docs:get-schema]
|
||||||
|
resp, _ = http.Get(apiURL + "/v1/bank-template-schema")
|
||||||
|
defer resp.Body.Close()
|
||||||
|
schema, _ := io.ReadAll(resp.Body)
|
||||||
|
fmt.Println(string(schema))
|
||||||
|
// [/docs:get-schema]
|
||||||
|
}
|
||||||
99
hindsight-docs/examples/api/bank-templates.mjs
Normal file
99
hindsight-docs/examples/api/bank-templates.mjs
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* Bank Templates API examples for Hindsight (Node.js)
|
||||||
|
* Run: node examples/api/bank-templates.mjs
|
||||||
|
*/
|
||||||
|
|
||||||
|
const HINDSIGHT_URL = process.env.HINDSIGHT_API_URL || 'http://localhost:8888';
|
||||||
|
|
||||||
|
// =============================================================================
|
||||||
|
// Doc Examples
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
// [docs:import-template]
|
||||||
|
const template = {
|
||||||
|
version: '1',
|
||||||
|
bank: {
|
||||||
|
retain_mission: 'Extract customer issues, resolutions, and sentiment.',
|
||||||
|
enable_observations: true,
|
||||||
|
observations_mission: 'Track recurring customer pain points.',
|
||||||
|
},
|
||||||
|
mental_models: [
|
||||||
|
{
|
||||||
|
id: 'sentiment-overview',
|
||||||
|
name: 'Customer Sentiment Overview',
|
||||||
|
source_query: 'What is the overall sentiment trend?',
|
||||||
|
trigger: { refresh_after_consolidation: true },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
directives: [
|
||||||
|
{
|
||||||
|
name: 'Acknowledge frustration',
|
||||||
|
content: 'Always acknowledge frustration before offering solutions.',
|
||||||
|
priority: 10,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const importResponse = await fetch(
|
||||||
|
`${HINDSIGHT_URL}/v1/default/banks/my-bank/import`,
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(template),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const result = await importResponse.json();
|
||||||
|
console.log('Config applied:', result.config_applied);
|
||||||
|
console.log('Mental models created:', result.mental_models_created);
|
||||||
|
console.log('Directives created:', result.directives_created);
|
||||||
|
// [/docs:import-template]
|
||||||
|
|
||||||
|
|
||||||
|
// [docs:import-dry-run]
|
||||||
|
const dryRunResponse = await fetch(
|
||||||
|
`${HINDSIGHT_URL}/v1/default/banks/my-bank/import?dry_run=true`,
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(template),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const dryRunResult = await dryRunResponse.json();
|
||||||
|
console.log('Dry run:', dryRunResult.dry_run);
|
||||||
|
console.log('Would apply config:', dryRunResult.config_applied);
|
||||||
|
// [/docs:import-dry-run]
|
||||||
|
|
||||||
|
|
||||||
|
// [docs:export-template]
|
||||||
|
const exportResponse = await fetch(
|
||||||
|
`${HINDSIGHT_URL}/v1/default/banks/my-bank/export`,
|
||||||
|
);
|
||||||
|
const exported = await exportResponse.json();
|
||||||
|
console.log(JSON.stringify(exported, null, 2));
|
||||||
|
// [/docs:export-template]
|
||||||
|
|
||||||
|
|
||||||
|
// [docs:export-reimport]
|
||||||
|
// Export from source bank
|
||||||
|
const srcResponse = await fetch(
|
||||||
|
`${HINDSIGHT_URL}/v1/default/banks/source-bank/export`,
|
||||||
|
);
|
||||||
|
const srcExported = await srcResponse.json();
|
||||||
|
|
||||||
|
// Import into a new bank
|
||||||
|
await fetch(`${HINDSIGHT_URL}/v1/default/banks/new-bank/import`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(srcExported),
|
||||||
|
});
|
||||||
|
// [/docs:export-reimport]
|
||||||
|
|
||||||
|
|
||||||
|
// [docs:get-schema]
|
||||||
|
const schemaResponse = await fetch(
|
||||||
|
`${HINDSIGHT_URL}/v1/bank-template-schema`,
|
||||||
|
);
|
||||||
|
const schema = await schemaResponse.json();
|
||||||
|
console.log(JSON.stringify(schema, null, 2));
|
||||||
|
// [/docs:get-schema]
|
||||||
95
hindsight-docs/examples/api/bank-templates.py
Normal file
95
hindsight-docs/examples/api/bank-templates.py
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Bank Templates API examples for Hindsight.
|
||||||
|
Run: python examples/api/bank-templates.py
|
||||||
|
"""
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
import requests
|
||||||
|
|
||||||
|
HINDSIGHT_URL = os.getenv("HINDSIGHT_API_URL", "http://localhost:8888")
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Doc Examples
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# [docs:import-template]
|
||||||
|
template = {
|
||||||
|
"version": "1",
|
||||||
|
"bank": {
|
||||||
|
"retain_mission": "Extract customer issues, resolutions, and sentiment.",
|
||||||
|
"enable_observations": True,
|
||||||
|
"observations_mission": "Track recurring customer pain points.",
|
||||||
|
},
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "sentiment-overview",
|
||||||
|
"name": "Customer Sentiment Overview",
|
||||||
|
"source_query": "What is the overall sentiment trend?",
|
||||||
|
"trigger": {"refresh_after_consolidation": True},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"directives": [
|
||||||
|
{
|
||||||
|
"name": "Acknowledge frustration",
|
||||||
|
"content": "Always acknowledge frustration before offering solutions.",
|
||||||
|
"priority": 10,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.post(
|
||||||
|
f"{HINDSIGHT_URL}/v1/default/banks/my-bank/import",
|
||||||
|
json=template,
|
||||||
|
)
|
||||||
|
result = response.json()
|
||||||
|
print(f"Config applied: {result['config_applied']}")
|
||||||
|
print(f"Mental models created: {result['mental_models_created']}")
|
||||||
|
print(f"Directives created: {result['directives_created']}")
|
||||||
|
# [/docs:import-template]
|
||||||
|
|
||||||
|
|
||||||
|
# [docs:import-dry-run]
|
||||||
|
response = requests.post(
|
||||||
|
f"{HINDSIGHT_URL}/v1/default/banks/my-bank/import",
|
||||||
|
params={"dry_run": "true"},
|
||||||
|
json=template,
|
||||||
|
)
|
||||||
|
result = response.json()
|
||||||
|
print(f"Dry run: {result['dry_run']}")
|
||||||
|
print(f"Would apply config: {result['config_applied']}")
|
||||||
|
# [/docs:import-dry-run]
|
||||||
|
|
||||||
|
|
||||||
|
# [docs:export-template]
|
||||||
|
response = requests.get(
|
||||||
|
f"{HINDSIGHT_URL}/v1/default/banks/my-bank/export"
|
||||||
|
)
|
||||||
|
exported = response.json()
|
||||||
|
print(json.dumps(exported, indent=2))
|
||||||
|
# [/docs:export-template]
|
||||||
|
|
||||||
|
|
||||||
|
# [docs:export-reimport]
|
||||||
|
# Export from source bank
|
||||||
|
response = requests.get(
|
||||||
|
f"{HINDSIGHT_URL}/v1/default/banks/source-bank/export"
|
||||||
|
)
|
||||||
|
exported = response.json()
|
||||||
|
|
||||||
|
# Import into a new bank
|
||||||
|
response = requests.post(
|
||||||
|
f"{HINDSIGHT_URL}/v1/default/banks/new-bank/import",
|
||||||
|
json=exported,
|
||||||
|
)
|
||||||
|
# [/docs:export-reimport]
|
||||||
|
|
||||||
|
|
||||||
|
# [docs:get-schema]
|
||||||
|
response = requests.get(
|
||||||
|
f"{HINDSIGHT_URL}/v1/bank-template-schema"
|
||||||
|
)
|
||||||
|
schema = response.json()
|
||||||
|
print(json.dumps(schema, indent=2))
|
||||||
|
# [/docs:get-schema]
|
||||||
63
hindsight-docs/examples/api/bank-templates.sh
Normal file
63
hindsight-docs/examples/api/bank-templates.sh
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Bank Templates API examples for Hindsight CLI
|
||||||
|
# Run: bash examples/api/bank-templates.sh
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
HINDSIGHT_URL="${HINDSIGHT_API_URL:-http://localhost:8888}"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# Doc Examples
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# [docs:import-template]
|
||||||
|
curl -X POST "$HINDSIGHT_URL/v1/default/banks/my-bank/import" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"version": "1",
|
||||||
|
"bank": {
|
||||||
|
"retain_mission": "Extract customer issues, resolutions, and sentiment.",
|
||||||
|
"enable_observations": true,
|
||||||
|
"observations_mission": "Track recurring customer pain points."
|
||||||
|
},
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "sentiment-overview",
|
||||||
|
"name": "Customer Sentiment Overview",
|
||||||
|
"source_query": "What is the overall sentiment trend?",
|
||||||
|
"trigger": { "refresh_after_consolidation": true }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"directives": [
|
||||||
|
{
|
||||||
|
"name": "Acknowledge frustration",
|
||||||
|
"content": "Always acknowledge frustration before offering solutions.",
|
||||||
|
"priority": 10
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}'
|
||||||
|
# [/docs:import-template]
|
||||||
|
|
||||||
|
# [docs:import-dry-run]
|
||||||
|
curl -X POST "$HINDSIGHT_URL/v1/default/banks/my-bank/import?dry_run=true" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d @template.json
|
||||||
|
# [/docs:import-dry-run]
|
||||||
|
|
||||||
|
# [docs:export-template]
|
||||||
|
curl "$HINDSIGHT_URL/v1/default/banks/my-bank/export"
|
||||||
|
# [/docs:export-template]
|
||||||
|
|
||||||
|
# [docs:export-reimport]
|
||||||
|
# Export from source bank
|
||||||
|
curl "$HINDSIGHT_URL/v1/default/banks/source-bank/export" > template.json
|
||||||
|
|
||||||
|
# Import into a new bank
|
||||||
|
curl -X POST "$HINDSIGHT_URL/v1/default/banks/new-bank/import" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d @template.json
|
||||||
|
# [/docs:export-reimport]
|
||||||
|
|
||||||
|
# [docs:get-schema]
|
||||||
|
curl "$HINDSIGHT_URL/v1/bank-template-schema"
|
||||||
|
# [/docs:get-schema]
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"docusaurus": "docusaurus",
|
"docusaurus": "docusaurus",
|
||||||
"start": "docusaurus start",
|
"start": "docusaurus start",
|
||||||
"build": "node scripts/check-code-parity.mjs && node scripts/check-integration-seo.mjs && docusaurus build",
|
"build": "node scripts/check-code-parity.mjs && node scripts/check-integration-seo.mjs && node scripts/check-templates.mjs && docusaurus build",
|
||||||
"swizzle": "docusaurus swizzle",
|
"swizzle": "docusaurus swizzle",
|
||||||
"deploy": "docusaurus deploy",
|
"deploy": "docusaurus deploy",
|
||||||
"clear": "docusaurus clear",
|
"clear": "docusaurus clear",
|
||||||
|
|
|
||||||
53
hindsight-docs/scripts/check-templates.mjs
Normal file
53
hindsight-docs/scripts/check-templates.mjs
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
/**
|
||||||
|
* Validates that every manifest in templates.json conforms to the
|
||||||
|
* bank template JSON Schema (static/bank-template-schema.json).
|
||||||
|
*
|
||||||
|
* Run: node scripts/check-templates.mjs
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { readFileSync } from 'node:fs';
|
||||||
|
import { join, dirname } from 'node:path';
|
||||||
|
import { fileURLToPath } from 'node:url';
|
||||||
|
import Ajv from 'ajv';
|
||||||
|
|
||||||
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||||
|
const docsRoot = join(__dirname, '..');
|
||||||
|
|
||||||
|
const templates = JSON.parse(
|
||||||
|
readFileSync(join(docsRoot, 'src/data/templates.json'), 'utf-8'),
|
||||||
|
);
|
||||||
|
const schema = JSON.parse(
|
||||||
|
readFileSync(join(docsRoot, 'static/bank-template-schema.json'), 'utf-8'),
|
||||||
|
);
|
||||||
|
|
||||||
|
const ajv = new Ajv({ allErrors: true, strict: false });
|
||||||
|
const validate = ajv.compile(schema);
|
||||||
|
|
||||||
|
let failed = 0;
|
||||||
|
|
||||||
|
for (const template of templates.templates) {
|
||||||
|
const valid = validate(template.manifest);
|
||||||
|
if (!valid) {
|
||||||
|
failed++;
|
||||||
|
console.error(`\x1b[31m✗\x1b[0m Template "${template.id}" has invalid manifest:`);
|
||||||
|
// Filter out noisy anyOf wrapper errors, keep only leaf errors with paths
|
||||||
|
const meaningful = validate.errors.filter(
|
||||||
|
(e) => e.keyword !== 'anyOf' && e.keyword !== 'if' && e.keyword !== 'then',
|
||||||
|
);
|
||||||
|
const shown = meaningful.length > 0 ? meaningful : validate.errors;
|
||||||
|
for (const err of shown) {
|
||||||
|
const path = err.instancePath || err.schemaPath || '(root)';
|
||||||
|
console.error(` ${path}: ${err.message} ${err.params ? JSON.stringify(err.params) : ''}`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(`\x1b[32m✓\x1b[0m Template "${template.id}" — valid`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failed > 0) {
|
||||||
|
console.error(`\n\x1b[31m${failed} template(s) failed schema validation.\x1b[0m`);
|
||||||
|
process.exit(1);
|
||||||
|
} else {
|
||||||
|
console.log(`\n\x1b[32mAll ${templates.templates.length} templates are valid.\x1b[0m`);
|
||||||
|
}
|
||||||
|
|
@ -122,6 +122,12 @@ const sidebars: SidebarsConfig = {
|
||||||
label: 'Webhooks',
|
label: 'Webhooks',
|
||||||
customProps: { icon: 'lu-webhook' },
|
customProps: { icon: 'lu-webhook' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'doc',
|
||||||
|
id: 'developer/api/bank-templates',
|
||||||
|
label: 'Bank Templates',
|
||||||
|
customProps: { icon: 'lu-file-json' },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'link',
|
type: 'link',
|
||||||
href: '/api-reference',
|
href: '/api-reference',
|
||||||
|
|
@ -342,6 +348,12 @@ const sidebars: SidebarsConfig = {
|
||||||
label: 'Resources',
|
label: 'Resources',
|
||||||
collapsible: false,
|
collapsible: false,
|
||||||
items: [
|
items: [
|
||||||
|
{
|
||||||
|
type: 'link',
|
||||||
|
href: '/templates',
|
||||||
|
label: 'Bank Templates Hub',
|
||||||
|
customProps: { icon: 'lu-layout-template', iconAfter: 'lu-arrow-up-right' },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'link',
|
type: 'link',
|
||||||
href: '/best-practices',
|
href: '/best-practices',
|
||||||
|
|
|
||||||
130
hindsight-docs/src/data/templates.json
Normal file
130
hindsight-docs/src/data/templates.json
Normal file
|
|
@ -0,0 +1,130 @@
|
||||||
|
{
|
||||||
|
"templates": [
|
||||||
|
{
|
||||||
|
"id": "conversation",
|
||||||
|
"name": "Conversation",
|
||||||
|
"description": "For chat-based agents and assistants. Tracks user preferences, conversation patterns, and builds a profile over time.",
|
||||||
|
"category": "chat",
|
||||||
|
"integrations": [
|
||||||
|
"litellm",
|
||||||
|
"langgraph",
|
||||||
|
"pydantic-ai",
|
||||||
|
"ai-sdk",
|
||||||
|
"chat",
|
||||||
|
"crewai",
|
||||||
|
"ag2",
|
||||||
|
"agno",
|
||||||
|
"strands",
|
||||||
|
"llamaindex",
|
||||||
|
"local-mcp",
|
||||||
|
"skills"
|
||||||
|
],
|
||||||
|
"manifest": {
|
||||||
|
"version": "1",
|
||||||
|
"bank": {
|
||||||
|
"retain_mission": "Extract user preferences, stated facts about themselves, requests they've made, topics they care about, and any commitments or follow-ups. Ignore small talk and filler.",
|
||||||
|
"enable_observations": true,
|
||||||
|
"observations_mission": "Track stable user preferences, communication style, recurring topics, and how the user's needs evolve over time."
|
||||||
|
},
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "user-profile",
|
||||||
|
"name": "User Profile",
|
||||||
|
"source_query": "What do we know about this user? What are their preferences, background, and how do they like to interact?",
|
||||||
|
"max_tokens": 2048,
|
||||||
|
"trigger": {
|
||||||
|
"refresh_after_consolidation": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "open-threads",
|
||||||
|
"name": "Open Threads",
|
||||||
|
"source_query": "What topics, tasks, or follow-ups are still open or unresolved from past conversations?",
|
||||||
|
"max_tokens": 1024,
|
||||||
|
"trigger": {
|
||||||
|
"refresh_after_consolidation": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "coding-agent",
|
||||||
|
"name": "Coding Agent",
|
||||||
|
"description": "For coding assistants. Remembers project architecture, technical decisions, coding patterns, and user preferences across sessions. High literalism for precise technical recall.",
|
||||||
|
"category": "coding",
|
||||||
|
"integrations": [
|
||||||
|
"claude-code",
|
||||||
|
"codex"
|
||||||
|
],
|
||||||
|
"manifest": {
|
||||||
|
"version": "1",
|
||||||
|
"bank": {
|
||||||
|
"retain_mission": "Extract technical decisions and their rationale, architectural choices, coding patterns and conventions, project structure facts, library/tool preferences, and recurring issues. Ignore transient debugging output and boilerplate.",
|
||||||
|
"enable_observations": true,
|
||||||
|
"observations_mission": "Track stable project facts: tech stack, team conventions, architecture patterns, and how the codebase evolves over time."
|
||||||
|
},
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "project-context",
|
||||||
|
"name": "Project Context",
|
||||||
|
"source_query": "What is the project's tech stack, architecture, and key conventions? What are the main components and how do they fit together?",
|
||||||
|
"max_tokens": 2048,
|
||||||
|
"trigger": {
|
||||||
|
"refresh_after_consolidation": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "developer-preferences",
|
||||||
|
"name": "Developer Preferences",
|
||||||
|
"source_query": "What are the developer's preferences for tools, libraries, coding style, and workflow? How do they like code to be written and reviewed?",
|
||||||
|
"max_tokens": 1024,
|
||||||
|
"trigger": {
|
||||||
|
"refresh_after_consolidation": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "personal-assistant",
|
||||||
|
"name": "Personal Assistant",
|
||||||
|
"description": "For always-on personal assistants that manage tasks, remember preferences, and maintain context across daily life. Tracks commitments, routines, and personal context.",
|
||||||
|
"category": "assistant",
|
||||||
|
"integrations": [
|
||||||
|
"openclaw",
|
||||||
|
"hermes",
|
||||||
|
"nemoclaw",
|
||||||
|
"hindclaw"
|
||||||
|
],
|
||||||
|
"manifest": {
|
||||||
|
"version": "1",
|
||||||
|
"bank": {
|
||||||
|
"retain_mission": "Extract the user's preferences, routines, scheduled events, commitments, people they mention, and any personal context they share. Track what they ask for repeatedly and what they care about.",
|
||||||
|
"enable_observations": true,
|
||||||
|
"observations_mission": "Track the user's stable preferences, recurring routines, important people and relationships, and how their priorities shift over time."
|
||||||
|
},
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "user-profile",
|
||||||
|
"name": "User Profile",
|
||||||
|
"source_query": "What do we know about this user? What are their preferences, routines, important people, and how do they like to be helped?",
|
||||||
|
"max_tokens": 2048,
|
||||||
|
"trigger": {
|
||||||
|
"refresh_after_consolidation": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "active-tasks",
|
||||||
|
"name": "Active Tasks & Commitments",
|
||||||
|
"source_query": "What tasks, commitments, or follow-ups is the user currently tracking? What deadlines or promises have been made?",
|
||||||
|
"max_tokens": 1024,
|
||||||
|
"trigger": {
|
||||||
|
"refresh_after_consolidation": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
569
hindsight-docs/src/pages/templates/index.module.css
Normal file
569
hindsight-docs/src/pages/templates/index.module.css
Normal file
|
|
@ -0,0 +1,569 @@
|
||||||
|
/* ── Full-width hero ─────────────────────────────────────────────────────── */
|
||||||
|
.heroSection {
|
||||||
|
width: 100%;
|
||||||
|
padding: 5rem 1.5rem 4rem;
|
||||||
|
text-align: center;
|
||||||
|
background: radial-gradient(ellipse 80% 60% at 50% 0%, rgba(0, 116, 217, 0.12) 0%, transparent 70%),
|
||||||
|
var(--ifm-background-color);
|
||||||
|
border-bottom: 1px solid var(--ifm-color-emphasis-200);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .heroSection {
|
||||||
|
background: radial-gradient(ellipse 80% 60% at 50% 0%, rgba(0, 116, 217, 0.18) 0%, transparent 70%),
|
||||||
|
var(--ifm-background-color);
|
||||||
|
border-bottom-color: rgba(255, 255, 255, 0.07);
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroTitle {
|
||||||
|
font-size: 3.2rem;
|
||||||
|
font-weight: 800;
|
||||||
|
background: linear-gradient(135deg, #0074d9, #009296);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
letter-spacing: -0.03em;
|
||||||
|
line-height: 1.1;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroSubtitle {
|
||||||
|
font-size: 1.05rem;
|
||||||
|
color: var(--ifm-color-emphasis-600);
|
||||||
|
max-width: 520px;
|
||||||
|
margin: 0 auto 2.25rem;
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroLink {
|
||||||
|
color: var(--ifm-color-primary);
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: 500;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heroLink:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Search ──────────────────────────────────────────────────────────────── */
|
||||||
|
.searchWrapper {
|
||||||
|
position: relative;
|
||||||
|
max-width: 640px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchInput {
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 1.05rem 3.5rem 1.05rem 1.5rem;
|
||||||
|
border-radius: 14px;
|
||||||
|
border: 2px solid var(--ifm-color-emphasis-300);
|
||||||
|
background: var(--ifm-background-surface-color);
|
||||||
|
color: var(--ifm-font-color-base);
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-family: inherit;
|
||||||
|
outline: none;
|
||||||
|
transition: border-color 0.15s ease, box-shadow 0.15s ease;
|
||||||
|
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchInput::placeholder {
|
||||||
|
color: var(--ifm-color-emphasis-400);
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchInput:focus {
|
||||||
|
border-color: #0074d9;
|
||||||
|
box-shadow: 0 0 0 4px rgba(0, 116, 217, 0.15), 0 4px 24px rgba(0, 0, 0, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .searchInput {
|
||||||
|
background: #242428;
|
||||||
|
border-color: rgba(255, 255, 255, 0.15);
|
||||||
|
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .searchInput:focus {
|
||||||
|
border-color: #4da6ff;
|
||||||
|
box-shadow: 0 0 0 4px rgba(77, 166, 255, 0.18), 0 4px 24px rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchClear {
|
||||||
|
position: absolute;
|
||||||
|
right: 1rem;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
background: var(--ifm-color-emphasis-200);
|
||||||
|
border: none;
|
||||||
|
color: var(--ifm-color-emphasis-600);
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: background 0.1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.searchClear:hover {
|
||||||
|
background: var(--ifm-color-emphasis-300);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Hero stats ──────────────────────────────────────────────────────────── */
|
||||||
|
.heroStats {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.6rem;
|
||||||
|
font-size: 0.82rem;
|
||||||
|
color: var(--ifm-color-emphasis-500);
|
||||||
|
margin-top: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat strong {
|
||||||
|
color: var(--ifm-color-emphasis-800);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .stat strong {
|
||||||
|
color: var(--ifm-color-emphasis-700);
|
||||||
|
}
|
||||||
|
|
||||||
|
.statDivider {
|
||||||
|
color: var(--ifm-color-emphasis-300);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Page container ──────────────────────────────────────────────────────── */
|
||||||
|
.page {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 2.5rem 1.5rem 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Toolbar (filters + count) ───────────────────────────────────────────── */
|
||||||
|
.toolbar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 1.75rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filterGroup {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.4rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filterPill {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 0.82rem;
|
||||||
|
font-weight: 500;
|
||||||
|
padding: 0.3rem 0.85rem;
|
||||||
|
border-radius: 999px;
|
||||||
|
border: 1px solid var(--ifm-color-emphasis-300);
|
||||||
|
background: transparent;
|
||||||
|
color: var(--ifm-color-emphasis-700);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.15s ease;
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filterPill:hover {
|
||||||
|
border-color: var(--ifm-color-primary);
|
||||||
|
color: var(--ifm-color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.filterPillActive {
|
||||||
|
background: var(--ifm-color-primary);
|
||||||
|
border-color: var(--ifm-color-primary);
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .filterPill {
|
||||||
|
border-color: rgba(255, 255, 255, 0.15);
|
||||||
|
color: var(--ifm-color-emphasis-600);
|
||||||
|
}
|
||||||
|
|
||||||
|
.resultCount {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
color: var(--ifm-color-emphasis-400);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Grid ────────────────────────────────────────────────────────────────── */
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 1.25rem;
|
||||||
|
margin-bottom: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 996px) {
|
||||||
|
.grid { grid-template-columns: repeat(2, 1fr); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.grid { grid-template-columns: 1fr; }
|
||||||
|
.heroTitle { font-size: 2.2rem; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Card ────────────────────────────────────────────────────────────────── */
|
||||||
|
.card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border-radius: 12px;
|
||||||
|
border: 1px solid var(--ifm-color-emphasis-200);
|
||||||
|
background: var(--ifm-background-surface-color);
|
||||||
|
text-decoration: none !important;
|
||||||
|
color: inherit;
|
||||||
|
text-align: left;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: box-shadow 0.2s ease, transform 0.2s ease;
|
||||||
|
overflow: hidden;
|
||||||
|
font-family: inherit;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .card {
|
||||||
|
background: #1c1c1e;
|
||||||
|
border-color: rgba(255, 255, 255, 0.07);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 6px 24px rgba(0, 116, 217, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardHeader {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 1rem 1.1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.categoryBadge {
|
||||||
|
font-size: 0.63rem;
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
padding: 0.15rem 0.5rem;
|
||||||
|
border-radius: 999px;
|
||||||
|
background: rgba(0, 116, 217, 0.12);
|
||||||
|
color: #0074d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .categoryBadge {
|
||||||
|
background: rgba(0, 116, 217, 0.2);
|
||||||
|
color: #4da6ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.integrationIcons {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.35rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.integrationIcon {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
object-fit: contain;
|
||||||
|
border-radius: 4px;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardBody {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0.85rem 1.1rem 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardTitle {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 700;
|
||||||
|
margin: 0 0 0.4rem;
|
||||||
|
color: var(--ifm-heading-color);
|
||||||
|
letter-spacing: -0.01em;
|
||||||
|
border-bottom: none !important;
|
||||||
|
border-image: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardDescription {
|
||||||
|
font-size: 0.82rem;
|
||||||
|
color: var(--ifm-color-emphasis-600);
|
||||||
|
line-height: 1.6;
|
||||||
|
margin: 0;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardFooter {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0.65rem 1.1rem 0.9rem;
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
border-top: 1px solid var(--ifm-color-emphasis-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .cardFooter {
|
||||||
|
border-top-color: rgba(255, 255, 255, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.viewLabel {
|
||||||
|
font-size: 0.78rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--ifm-color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Schema section ──────────────────────────────────────────────────────── */
|
||||||
|
.schemaSection {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
padding: 2rem;
|
||||||
|
border-radius: 14px;
|
||||||
|
border: 1px solid var(--ifm-color-emphasis-200);
|
||||||
|
background: var(--ifm-background-surface-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .schemaSection {
|
||||||
|
background: #1c1c1e;
|
||||||
|
border-color: rgba(255, 255, 255, 0.07);
|
||||||
|
}
|
||||||
|
|
||||||
|
.schemaSectionTitle {
|
||||||
|
font-size: 1.4rem;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.schemaSectionDescription {
|
||||||
|
font-size: 0.88rem;
|
||||||
|
color: var(--ifm-color-emphasis-600);
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.schemaSectionDescription code {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
padding: 0.1rem 0.35rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: var(--ifm-color-emphasis-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .schemaSectionDescription code {
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Modal ───────────────────────────────────────────────────────────────── */
|
||||||
|
.modalOverlay {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
z-index: 1000;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .modalOverlay {
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
background: var(--ifm-background-surface-color);
|
||||||
|
border-radius: 16px;
|
||||||
|
max-width: 700px;
|
||||||
|
width: 100%;
|
||||||
|
max-height: 85vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 24px 64px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .modal {
|
||||||
|
background: #1c1c1e;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modalHeader {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 1.5rem 1.5rem 0;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modalTitle {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: 700;
|
||||||
|
margin: 0 0 0.25rem;
|
||||||
|
color: var(--ifm-heading-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modalDescription {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: var(--ifm-color-emphasis-600);
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modalClose {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
color: var(--ifm-color-emphasis-500);
|
||||||
|
cursor: pointer;
|
||||||
|
line-height: 1;
|
||||||
|
padding: 0.25rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modalClose:hover {
|
||||||
|
color: var(--ifm-color-emphasis-800);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modalBody {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 1rem 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manifestHeader {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manifestLabel {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
color: var(--ifm-color-emphasis-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyButton {
|
||||||
|
font-size: 0.78rem;
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 0.3rem 0.75rem;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid var(--ifm-color-primary);
|
||||||
|
background: transparent;
|
||||||
|
color: var(--ifm-color-primary);
|
||||||
|
cursor: pointer;
|
||||||
|
font-family: inherit;
|
||||||
|
transition: all 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copyButton:hover {
|
||||||
|
background: var(--ifm-color-primary);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manifestCode {
|
||||||
|
background: var(--ifm-color-emphasis-100);
|
||||||
|
border-radius: 10px;
|
||||||
|
padding: 1rem 1.25rem;
|
||||||
|
font-size: 0.78rem;
|
||||||
|
line-height: 1.6;
|
||||||
|
overflow-x: auto;
|
||||||
|
margin: 0;
|
||||||
|
border: 1px solid var(--ifm-color-emphasis-200);
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .manifestCode {
|
||||||
|
background: #0d0d0f;
|
||||||
|
border-color: rgba(255, 255, 255, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modalFooter {
|
||||||
|
padding: 0.75rem 1.5rem 1.25rem;
|
||||||
|
border-top: 1px solid var(--ifm-color-emphasis-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .modalFooter {
|
||||||
|
border-top-color: rgba(255, 255, 255, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.usageHint {
|
||||||
|
font-size: 0.78rem;
|
||||||
|
color: var(--ifm-color-emphasis-500);
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.usageHint code {
|
||||||
|
font-size: 0.72rem;
|
||||||
|
padding: 0.1rem 0.35rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: var(--ifm-color-emphasis-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .usageHint code {
|
||||||
|
background: rgba(255, 255, 255, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Empty state ─────────────────────────────────────────────────────────── */
|
||||||
|
.empty {
|
||||||
|
text-align: center;
|
||||||
|
padding: 4rem 2rem;
|
||||||
|
color: var(--ifm-color-emphasis-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
.resetButton {
|
||||||
|
margin-top: 1rem;
|
||||||
|
padding: 0.4rem 1rem;
|
||||||
|
border-radius: 6px;
|
||||||
|
border: 1px solid var(--ifm-color-primary);
|
||||||
|
background: transparent;
|
||||||
|
color: var(--ifm-color-primary);
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-family: inherit;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resetButton:hover {
|
||||||
|
background: var(--ifm-color-primary);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ── Submit banner ───────────────────────────────────────────────────────── */
|
||||||
|
.submitBanner {
|
||||||
|
border-radius: 14px;
|
||||||
|
border: 1px solid var(--ifm-color-emphasis-200);
|
||||||
|
background: linear-gradient(135deg, rgba(0, 116, 217, 0.06), rgba(0, 146, 150, 0.06));
|
||||||
|
padding: 2.5rem 2rem;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-theme='dark'] .submitBanner {
|
||||||
|
border-color: rgba(255, 255, 255, 0.08);
|
||||||
|
background: linear-gradient(135deg, rgba(0, 116, 217, 0.1), rgba(0, 146, 150, 0.1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.submitBannerContent {
|
||||||
|
max-width: 480px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submitBannerTitle {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submitBannerText {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: var(--ifm-color-emphasis-600);
|
||||||
|
margin-bottom: 0;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
219
hindsight-docs/src/pages/templates/index.tsx
Normal file
219
hindsight-docs/src/pages/templates/index.tsx
Normal file
|
|
@ -0,0 +1,219 @@
|
||||||
|
import React, {useMemo, useState, useCallback} from 'react';
|
||||||
|
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||||
|
import Layout from '@theme/Layout';
|
||||||
|
import templatesData from '@site/src/data/templates.json';
|
||||||
|
import integrationsData from '@site/src/data/integrations.json';
|
||||||
|
import styles from './index.module.css';
|
||||||
|
|
||||||
|
const CATEGORIES = ['all', 'chat', 'coding', 'assistant'] as const;
|
||||||
|
type Category = (typeof CATEGORIES)[number];
|
||||||
|
|
||||||
|
const CATEGORY_LABELS: Record<Category, string> = {
|
||||||
|
all: 'All',
|
||||||
|
chat: 'Chat',
|
||||||
|
coding: 'Coding',
|
||||||
|
assistant: 'Assistant',
|
||||||
|
};
|
||||||
|
|
||||||
|
// Build a lookup from integration ID to icon path and name
|
||||||
|
const INTEGRATION_MAP = Object.fromEntries(
|
||||||
|
integrationsData.integrations.map((i) => [i.id, {icon: i.icon, name: i.name}]),
|
||||||
|
);
|
||||||
|
|
||||||
|
interface Template {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
category: string;
|
||||||
|
integrations?: string[];
|
||||||
|
manifest: Record<string, unknown>;
|
||||||
|
}
|
||||||
|
|
||||||
|
function IntegrationIcons({ids}: {ids: string[]}) {
|
||||||
|
return (
|
||||||
|
<div className={styles.integrationIcons}>
|
||||||
|
{ids.map((id) => {
|
||||||
|
const info = INTEGRATION_MAP[id];
|
||||||
|
if (!info?.icon) return null;
|
||||||
|
const src = useBaseUrl(info.icon);
|
||||||
|
return <img key={id} src={src} alt={info.name} title={info.name} className={styles.integrationIcon} />;
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function TemplateCard({template, onSelect}: {template: Template; onSelect: () => void}) {
|
||||||
|
return (
|
||||||
|
<button className={styles.card} onClick={onSelect}>
|
||||||
|
<div className={styles.cardHeader}>
|
||||||
|
<span className={styles.categoryBadge}>{template.category}</span>
|
||||||
|
{template.integrations && template.integrations.length > 0 && (
|
||||||
|
<IntegrationIcons ids={template.integrations} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className={styles.cardBody}>
|
||||||
|
<h3 className={styles.cardTitle}>{template.name}</h3>
|
||||||
|
<p className={styles.cardDescription}>{template.description}</p>
|
||||||
|
</div>
|
||||||
|
<div className={styles.cardFooter}>
|
||||||
|
<span className={styles.viewLabel}>View manifest →</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ManifestModal({
|
||||||
|
template,
|
||||||
|
onClose,
|
||||||
|
}: {
|
||||||
|
template: Template;
|
||||||
|
onClose: () => void;
|
||||||
|
}) {
|
||||||
|
const [copied, setCopied] = useState(false);
|
||||||
|
const json = JSON.stringify(template.manifest, null, 2);
|
||||||
|
|
||||||
|
const handleCopy = useCallback(async () => {
|
||||||
|
await navigator.clipboard.writeText(json);
|
||||||
|
setCopied(true);
|
||||||
|
setTimeout(() => setCopied(false), 2000);
|
||||||
|
}, [json]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={styles.modalOverlay} onClick={onClose}>
|
||||||
|
<div className={styles.modal} onClick={(e) => e.stopPropagation()}>
|
||||||
|
<div className={styles.modalHeader}>
|
||||||
|
<div>
|
||||||
|
<h2 className={styles.modalTitle}>{template.name}</h2>
|
||||||
|
<p className={styles.modalDescription}>{template.description}</p>
|
||||||
|
</div>
|
||||||
|
<button className={styles.modalClose} onClick={onClose} aria-label="Close">
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className={styles.modalBody}>
|
||||||
|
<div className={styles.manifestHeader}>
|
||||||
|
<span className={styles.manifestLabel}>Template Manifest</span>
|
||||||
|
<button className={styles.copyButton} onClick={handleCopy}>
|
||||||
|
{copied ? 'Copied!' : 'Copy JSON'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<pre className={styles.manifestCode}>
|
||||||
|
<code>{json}</code>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
<div className={styles.modalFooter}>
|
||||||
|
<p className={styles.usageHint}>
|
||||||
|
Use this manifest with <code>POST /v1/default/banks/{bank_id}/import</code> or
|
||||||
|
paste it in the bank creation dialog in the control plane.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function TemplateGallery(): React.ReactElement {
|
||||||
|
const [search, setSearch] = useState('');
|
||||||
|
const [selectedCategory, setSelectedCategory] = useState<Category>('all');
|
||||||
|
const [selectedTemplate, setSelectedTemplate] = useState<Template | null>(null);
|
||||||
|
|
||||||
|
const templates = templatesData.templates as Template[];
|
||||||
|
|
||||||
|
const filtered = useMemo(() => {
|
||||||
|
const q = search.toLowerCase().trim();
|
||||||
|
return templates.filter((t) => {
|
||||||
|
if (selectedCategory !== 'all' && t.category !== selectedCategory) return false;
|
||||||
|
if (q && !t.name.toLowerCase().includes(q) && !t.description.toLowerCase().includes(q)) return false;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}, [templates, search, selectedCategory]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Layout title="Bank Templates Hub" description="Pre-built bank templates for common use cases">
|
||||||
|
<div className={styles.heroSection}>
|
||||||
|
<h1 className={styles.heroTitle}>Bank Templates Hub</h1>
|
||||||
|
<p className={styles.heroSubtitle}>
|
||||||
|
Pre-built bank templates to get started fast. Browse, preview, and import into your Hindsight banks.
|
||||||
|
{' '}<a href="/developer/api/bank-templates" className={styles.heroLink}>Learn how templates work →</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div className={styles.searchWrapper}>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className={styles.searchInput}
|
||||||
|
placeholder="Search templates..."
|
||||||
|
value={search}
|
||||||
|
onChange={(e) => setSearch(e.target.value)}
|
||||||
|
aria-label="Search templates"
|
||||||
|
autoComplete="off"
|
||||||
|
autoFocus
|
||||||
|
/>
|
||||||
|
{search && (
|
||||||
|
<button className={styles.searchClear} onClick={() => setSearch('')} aria-label="Clear search">
|
||||||
|
×
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.heroStats}>
|
||||||
|
<span className={styles.stat}>
|
||||||
|
<strong>{templates.length}</strong> templates
|
||||||
|
</span>
|
||||||
|
<span className={styles.statDivider}>·</span>
|
||||||
|
<span className={styles.stat}>
|
||||||
|
<strong>{new Set(templates.map((t) => t.category)).size}</strong> categories
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.page}>
|
||||||
|
<div className={styles.toolbar}>
|
||||||
|
<div className={styles.filterGroup}>
|
||||||
|
{CATEGORIES.map((c) => (
|
||||||
|
<button
|
||||||
|
key={c}
|
||||||
|
className={`${styles.filterPill} ${selectedCategory === c ? styles.filterPillActive : ''}`}
|
||||||
|
onClick={() => setSelectedCategory(c)}>
|
||||||
|
{CATEGORY_LABELS[c]}
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<span className={styles.resultCount}>
|
||||||
|
{filtered.length} template{filtered.length !== 1 ? 's' : ''}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{filtered.length === 0 ? (
|
||||||
|
<div className={styles.empty}>
|
||||||
|
<p>No templates match your search.</p>
|
||||||
|
<button
|
||||||
|
className={styles.resetButton}
|
||||||
|
onClick={() => {
|
||||||
|
setSearch('');
|
||||||
|
setSelectedCategory('all');
|
||||||
|
}}>
|
||||||
|
Reset filters
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className={styles.grid}>
|
||||||
|
{filtered.map((t) => (
|
||||||
|
<TemplateCard key={t.id} template={t} onSelect={() => setSelectedTemplate(t)} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className={styles.submitBanner}>
|
||||||
|
<div className={styles.submitBannerContent}>
|
||||||
|
<h3 className={styles.submitBannerTitle}>Have a template to share?</h3>
|
||||||
|
<p className={styles.submitBannerText}>
|
||||||
|
Add your template to the gallery by editing templates.json on GitHub.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{selectedTemplate && <ManifestModal template={selectedTemplate} onClose={() => setSelectedTemplate(null)} />}
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -12,6 +12,7 @@ import {
|
||||||
LuNetwork, LuCode, LuLayers, LuCpu,
|
LuNetwork, LuCode, LuLayers, LuCpu,
|
||||||
LuArrowUpRight, LuBookOpen, LuRss, LuCloud, LuMessageCircle,
|
LuArrowUpRight, LuBookOpen, LuRss, LuCloud, LuMessageCircle,
|
||||||
LuChartBar, LuChartColumn, LuStar, LuCircleHelp,
|
LuChartBar, LuChartColumn, LuStar, LuCircleHelp,
|
||||||
|
LuLayoutTemplate, LuFileJson,
|
||||||
} from 'react-icons/lu';
|
} from 'react-icons/lu';
|
||||||
import {SiGo, SiPython, SiGithub, SiSlack} from 'react-icons/si';
|
import {SiGo, SiPython, SiGithub, SiSlack} from 'react-icons/si';
|
||||||
|
|
||||||
|
|
@ -54,6 +55,8 @@ const ICON_MAP: Record<string, IconType> = {
|
||||||
'lu-star': LuStar,
|
'lu-star': LuStar,
|
||||||
'lu-circle-help': LuCircleHelp,
|
'lu-circle-help': LuCircleHelp,
|
||||||
'lu-file-text': LuFileText,
|
'lu-file-text': LuFileText,
|
||||||
|
'lu-layout-template': LuLayoutTemplate,
|
||||||
|
'lu-file-json': LuFileJson,
|
||||||
};
|
};
|
||||||
|
|
||||||
type Props = WrapperProps<typeof LinkType>;
|
type Props = WrapperProps<typeof LinkType>;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import type {WrapperProps} from '@docusaurus/types';
|
||||||
import type {IconType} from 'react-icons';
|
import type {IconType} from 'react-icons';
|
||||||
import {
|
import {
|
||||||
LuArrowUpRight, LuCode, LuCircleHelp, LuScrollText,
|
LuArrowUpRight, LuCode, LuCircleHelp, LuScrollText,
|
||||||
LuLayoutGrid, LuCloud, LuBook, LuRss, LuBookOpen,
|
LuLayoutGrid, LuLayoutTemplate, LuCloud, LuBook, LuRss, LuBookOpen,
|
||||||
LuChartBar, LuCpu, LuFileText, LuStar,
|
LuChartBar, LuCpu, LuFileText, LuStar,
|
||||||
} from 'react-icons/lu';
|
} from 'react-icons/lu';
|
||||||
import {SiGithub, SiSlack} from 'react-icons/si';
|
import {SiGithub, SiSlack} from 'react-icons/si';
|
||||||
|
|
@ -14,7 +14,8 @@ const ICON_MAP: Record<string, IconType> = {
|
||||||
'lu-code': LuCode,
|
'lu-code': LuCode,
|
||||||
'lu-circle-help': LuCircleHelp,
|
'lu-circle-help': LuCircleHelp,
|
||||||
'lu-scroll-text': LuScrollText,
|
'lu-scroll-text': LuScrollText,
|
||||||
'lu-layout-grid': LuLayoutGrid,
|
'lu-layout-grid': LuLayoutGrid,
|
||||||
|
'lu-layout-template': LuLayoutTemplate,
|
||||||
'lu-cloud': LuCloud,
|
'lu-cloud': LuCloud,
|
||||||
'lu-book': LuBook,
|
'lu-book': LuBook,
|
||||||
'lu-rss': LuRss,
|
'lu-rss': LuRss,
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,16 @@ import DropdownNavbarItem from '@theme-original/NavbarItem/DropdownNavbarItem';
|
||||||
import type DropdownNavbarItemType from '@theme/NavbarItem/DropdownNavbarItem';
|
import type DropdownNavbarItemType from '@theme/NavbarItem/DropdownNavbarItem';
|
||||||
import type {WrapperProps} from '@docusaurus/types';
|
import type {WrapperProps} from '@docusaurus/types';
|
||||||
import type {IconType} from 'react-icons';
|
import type {IconType} from 'react-icons';
|
||||||
import {LuLayoutGrid, LuBook, LuRss, LuBookOpen} from 'react-icons/lu';
|
import {LuLayoutGrid, LuLayoutTemplate, LuBook, LuRss, LuBookOpen} from 'react-icons/lu';
|
||||||
import {SiSlack} from 'react-icons/si';
|
import {SiSlack} from 'react-icons/si';
|
||||||
|
|
||||||
const ICON_MAP: Record<string, IconType> = {
|
const ICON_MAP: Record<string, IconType> = {
|
||||||
'lu-layout-grid': LuLayoutGrid,
|
'lu-layout-grid': LuLayoutGrid,
|
||||||
'lu-book': LuBook,
|
'lu-layout-template': LuLayoutTemplate,
|
||||||
'lu-rss': LuRss,
|
'lu-book': LuBook,
|
||||||
'lu-book-open': LuBookOpen,
|
'lu-rss': LuRss,
|
||||||
'si-slack': SiSlack,
|
'lu-book-open': LuBookOpen,
|
||||||
|
'si-slack': SiSlack,
|
||||||
};
|
};
|
||||||
|
|
||||||
type Props = WrapperProps<typeof DropdownNavbarItemType>;
|
type Props = WrapperProps<typeof DropdownNavbarItemType>;
|
||||||
|
|
|
||||||
569
hindsight-docs/static/bank-template-schema.json
Normal file
569
hindsight-docs/static/bank-template-schema.json
Normal file
|
|
@ -0,0 +1,569 @@
|
||||||
|
{
|
||||||
|
"$defs": {
|
||||||
|
"BankTemplateConfig": {
|
||||||
|
"description": "Bank configuration fields within a template manifest.\n\nOnly includes configurable (per-bank) fields. Credential fields\n(API keys, base URLs) are intentionally excluded for security.",
|
||||||
|
"properties": {
|
||||||
|
"reflect_mission": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Mission/context for Reflect operations",
|
||||||
|
"title": "Reflect Mission"
|
||||||
|
},
|
||||||
|
"retain_mission": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Steers what gets extracted during retain",
|
||||||
|
"title": "Retain Mission"
|
||||||
|
},
|
||||||
|
"retain_extraction_mode": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Fact extraction mode: 'concise' (default), 'verbose', or 'custom'",
|
||||||
|
"title": "Retain Extraction Mode"
|
||||||
|
},
|
||||||
|
"retain_custom_instructions": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Custom extraction prompt (when mode='custom')",
|
||||||
|
"title": "Retain Custom Instructions"
|
||||||
|
},
|
||||||
|
"retain_chunk_size": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Max token size for each content chunk",
|
||||||
|
"title": "Retain Chunk Size"
|
||||||
|
},
|
||||||
|
"enable_observations": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Toggle observation consolidation",
|
||||||
|
"title": "Enable Observations"
|
||||||
|
},
|
||||||
|
"observations_mission": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Controls what gets synthesised",
|
||||||
|
"title": "Observations Mission"
|
||||||
|
},
|
||||||
|
"disposition_skepticism": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"maximum": 5,
|
||||||
|
"minimum": 1,
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Skepticism trait (1-5)",
|
||||||
|
"title": "Disposition Skepticism"
|
||||||
|
},
|
||||||
|
"disposition_literalism": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"maximum": 5,
|
||||||
|
"minimum": 1,
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Literalism trait (1-5)",
|
||||||
|
"title": "Disposition Literalism"
|
||||||
|
},
|
||||||
|
"disposition_empathy": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"maximum": 5,
|
||||||
|
"minimum": 1,
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Empathy trait (1-5)",
|
||||||
|
"title": "Disposition Empathy"
|
||||||
|
},
|
||||||
|
"entity_labels": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Controlled vocabulary for entity labels",
|
||||||
|
"title": "Entity Labels"
|
||||||
|
},
|
||||||
|
"entities_allow_free_form": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Allow entities outside the label vocabulary",
|
||||||
|
"title": "Entities Allow Free Form"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "BankTemplateConfig",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"BankTemplateDirective": {
|
||||||
|
"description": "A directive definition within a bank template manifest.\n\nDirectives are matched by name on re-import: existing directives\nwith the same name are updated, new ones are created.",
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"description": "Human-readable name for the directive (used as match key on re-import)",
|
||||||
|
"title": "Name",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"description": "The directive text to inject into prompts",
|
||||||
|
"title": "Content",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"priority": {
|
||||||
|
"default": 0,
|
||||||
|
"description": "Higher priority directives are injected first",
|
||||||
|
"title": "Priority",
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"is_active": {
|
||||||
|
"default": true,
|
||||||
|
"description": "Whether this directive is active",
|
||||||
|
"title": "Is Active",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
|
"default": [],
|
||||||
|
"description": "Tags for filtering",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"title": "Tags",
|
||||||
|
"type": "array"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"content"
|
||||||
|
],
|
||||||
|
"title": "BankTemplateDirective",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"BankTemplateMentalModel": {
|
||||||
|
"description": "A mental model definition within a bank template manifest.",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"description": "Unique ID for the mental model (alphanumeric lowercase with hyphens)",
|
||||||
|
"title": "Id",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"description": "Human-readable name for the mental model",
|
||||||
|
"title": "Name",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"source_query": {
|
||||||
|
"description": "The query to run to generate content",
|
||||||
|
"title": "Source Query",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
|
"default": [],
|
||||||
|
"description": "Tags for scoped visibility",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"title": "Tags",
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"max_tokens": {
|
||||||
|
"default": 2048,
|
||||||
|
"description": "Maximum tokens for generated content",
|
||||||
|
"maximum": 8192,
|
||||||
|
"minimum": 256,
|
||||||
|
"title": "Max Tokens",
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"trigger": {
|
||||||
|
"$ref": "#/$defs/MentalModelTrigger",
|
||||||
|
"default": {},
|
||||||
|
"description": "Trigger settings"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"source_query"
|
||||||
|
],
|
||||||
|
"title": "BankTemplateMentalModel",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"MentalModelTrigger": {
|
||||||
|
"description": "Trigger settings for a mental model.",
|
||||||
|
"properties": {
|
||||||
|
"refresh_after_consolidation": {
|
||||||
|
"default": false,
|
||||||
|
"description": "If true, refresh this mental model after observations consolidation (real-time mode)",
|
||||||
|
"title": "Refresh After Consolidation",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"fact_types": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"items": {
|
||||||
|
"enum": [
|
||||||
|
"world",
|
||||||
|
"experience",
|
||||||
|
"observation"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Filter which fact types are retrieved during reflect. None means all types (world, experience, observation).",
|
||||||
|
"title": "Fact Types"
|
||||||
|
},
|
||||||
|
"exclude_mental_models": {
|
||||||
|
"default": false,
|
||||||
|
"description": "If true, exclude all mental models from the reflect loop (skip search_mental_models tool).",
|
||||||
|
"title": "Exclude Mental Models",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"exclude_mental_model_ids": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Exclude specific mental models by ID from the reflect loop.",
|
||||||
|
"title": "Exclude Mental Model Ids"
|
||||||
|
},
|
||||||
|
"tags_match": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"enum": [
|
||||||
|
"any",
|
||||||
|
"all",
|
||||||
|
"any_strict",
|
||||||
|
"all_strict"
|
||||||
|
],
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Override how the model's tags filter memories during refresh. If not set, defaults to 'all_strict' when the model has tags (security isolation) or 'any' when the model has no tags. Set to 'any' to include untagged memories alongside tagged ones during refresh.",
|
||||||
|
"title": "Tags Match"
|
||||||
|
},
|
||||||
|
"tag_groups": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"items": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/TagGroupLeaf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/TagGroupAnd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/TagGroupOr"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/TagGroupNot"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Compound boolean tag expressions to use during refresh instead of the model's own tags. When set, these tag groups are passed to reflect and the model's flat tags are NOT used for filtering. Supports nested and/or/not expressions for complex tag-based scoping.",
|
||||||
|
"title": "Tag Groups"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "MentalModelTrigger",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"TagGroupAnd": {
|
||||||
|
"description": "Compound AND group: all child filters must match.",
|
||||||
|
"properties": {
|
||||||
|
"and": {
|
||||||
|
"items": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/TagGroupLeaf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/TagGroupAnd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/TagGroupOr"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/TagGroupNot"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"title": "And",
|
||||||
|
"type": "array"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"and"
|
||||||
|
],
|
||||||
|
"title": "TagGroupAnd",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"TagGroupLeaf": {
|
||||||
|
"description": "A leaf tag filter: matches memories by tag list and match mode.",
|
||||||
|
"properties": {
|
||||||
|
"tags": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"title": "Tags",
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"match": {
|
||||||
|
"default": "any_strict",
|
||||||
|
"enum": [
|
||||||
|
"any",
|
||||||
|
"all",
|
||||||
|
"any_strict",
|
||||||
|
"all_strict"
|
||||||
|
],
|
||||||
|
"title": "Match",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"tags"
|
||||||
|
],
|
||||||
|
"title": "TagGroupLeaf",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"TagGroupNot": {
|
||||||
|
"description": "Compound NOT group: child filter must NOT match.",
|
||||||
|
"properties": {
|
||||||
|
"not": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/TagGroupLeaf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/TagGroupAnd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/TagGroupOr"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/TagGroupNot"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Not"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"not"
|
||||||
|
],
|
||||||
|
"title": "TagGroupNot",
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"TagGroupOr": {
|
||||||
|
"description": "Compound OR group: at least one child filter must match.",
|
||||||
|
"properties": {
|
||||||
|
"or": {
|
||||||
|
"items": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/TagGroupLeaf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/TagGroupAnd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/TagGroupOr"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/TagGroupNot"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"title": "Or",
|
||||||
|
"type": "array"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"or"
|
||||||
|
],
|
||||||
|
"title": "TagGroupOr",
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "A bank template manifest for import/export.\n\nVersion field enables forward-compatible schema evolution: the API\nauto-upgrades older manifest versions to the current schema on import.",
|
||||||
|
"example": {
|
||||||
|
"bank": {
|
||||||
|
"disposition_empathy": 5,
|
||||||
|
"enable_observations": true,
|
||||||
|
"reflect_mission": "You are helping a support agent remember customer interactions.",
|
||||||
|
"retain_mission": "Extract customer issues, resolutions, and sentiment."
|
||||||
|
},
|
||||||
|
"directives": [
|
||||||
|
{
|
||||||
|
"content": "Always respond with empathy and understanding.",
|
||||||
|
"name": "Always be empathetic",
|
||||||
|
"priority": 10
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "sentiment-overview",
|
||||||
|
"name": "Customer Sentiment Overview",
|
||||||
|
"source_query": "What is the overall sentiment trend?",
|
||||||
|
"trigger": {
|
||||||
|
"refresh_after_consolidation": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": "1"
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"version": {
|
||||||
|
"description": "Manifest schema version (currently '1')",
|
||||||
|
"title": "Version",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"bank": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/BankTemplateConfig"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Bank configuration to apply. Omit to leave config unchanged."
|
||||||
|
},
|
||||||
|
"mental_models": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/$defs/BankTemplateMentalModel"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Mental models to create or update (matched by id). Omit to leave unchanged.",
|
||||||
|
"title": "Mental Models"
|
||||||
|
},
|
||||||
|
"directives": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/$defs/BankTemplateDirective"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"default": null,
|
||||||
|
"description": "Directives to create or update (matched by name). Omit to leave unchanged.",
|
||||||
|
"title": "Directives"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"version"
|
||||||
|
],
|
||||||
|
"title": "BankTemplateManifest",
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
|
@ -3100,6 +3100,156 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/v1/default/banks/{bank_id}/import": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Bank Templates"
|
||||||
|
],
|
||||||
|
"summary": "Import bank template",
|
||||||
|
"description": "Import a bank template manifest to create or update a bank's configuration, mental models, and directives. If the bank does not exist it is created. Config fields are applied as per-bank overrides. Mental models are matched by id, directives by name \u2014 existing ones are updated, new ones are created. Use dry_run=true to validate the manifest without applying changes.",
|
||||||
|
"operationId": "import_bank_template",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "bank_id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Bank Id"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dry_run",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Validate only, do not apply changes",
|
||||||
|
"default": false,
|
||||||
|
"title": "Dry Run"
|
||||||
|
},
|
||||||
|
"description": "Validate only, do not apply changes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "authorization",
|
||||||
|
"in": "header",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Authorization"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/BankTemplateImportResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"description": "Validation Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/HTTPValidationError"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/v1/default/banks/{bank_id}/export": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Bank Templates"
|
||||||
|
],
|
||||||
|
"summary": "Export bank template",
|
||||||
|
"description": "Export a bank's current configuration, mental models, and directives as a template manifest. The exported manifest can be imported into another bank to replicate the setup.",
|
||||||
|
"operationId": "export_bank_template",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "bank_id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Bank Id"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "authorization",
|
||||||
|
"in": "header",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Authorization"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/BankTemplateManifest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"description": "Validation Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/HTTPValidationError"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/v1/bank-template-schema": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Bank Templates"
|
||||||
|
],
|
||||||
|
"summary": "Get bank template JSON Schema",
|
||||||
|
"description": "Returns the JSON Schema for the bank template manifest format. Use this to validate template manifests before importing.",
|
||||||
|
"operationId": "get_bank_template_schema",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/v1/default/banks/{bank_id}/observations": {
|
"/v1/default/banks/{bank_id}/observations": {
|
||||||
"delete": {
|
"delete": {
|
||||||
"tags": [
|
"tags": [
|
||||||
|
|
@ -4993,6 +5143,411 @@
|
||||||
"total_observations": 45
|
"total_observations": 45
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"BankTemplateConfig": {
|
||||||
|
"properties": {
|
||||||
|
"reflect_mission": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Reflect Mission",
|
||||||
|
"description": "Mission/context for Reflect operations"
|
||||||
|
},
|
||||||
|
"retain_mission": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Retain Mission",
|
||||||
|
"description": "Steers what gets extracted during retain"
|
||||||
|
},
|
||||||
|
"retain_extraction_mode": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Retain Extraction Mode",
|
||||||
|
"description": "Fact extraction mode: 'concise' (default), 'verbose', or 'custom'"
|
||||||
|
},
|
||||||
|
"retain_custom_instructions": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Retain Custom Instructions",
|
||||||
|
"description": "Custom extraction prompt (when mode='custom')"
|
||||||
|
},
|
||||||
|
"retain_chunk_size": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Retain Chunk Size",
|
||||||
|
"description": "Max token size for each content chunk"
|
||||||
|
},
|
||||||
|
"enable_observations": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Enable Observations",
|
||||||
|
"description": "Toggle observation consolidation"
|
||||||
|
},
|
||||||
|
"observations_mission": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Observations Mission",
|
||||||
|
"description": "Controls what gets synthesised"
|
||||||
|
},
|
||||||
|
"disposition_skepticism": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 5.0,
|
||||||
|
"minimum": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Disposition Skepticism",
|
||||||
|
"description": "Skepticism trait (1-5)"
|
||||||
|
},
|
||||||
|
"disposition_literalism": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 5.0,
|
||||||
|
"minimum": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Disposition Literalism",
|
||||||
|
"description": "Literalism trait (1-5)"
|
||||||
|
},
|
||||||
|
"disposition_empathy": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 5.0,
|
||||||
|
"minimum": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Disposition Empathy",
|
||||||
|
"description": "Empathy trait (1-5)"
|
||||||
|
},
|
||||||
|
"entity_labels": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Entity Labels",
|
||||||
|
"description": "Controlled vocabulary for entity labels"
|
||||||
|
},
|
||||||
|
"entities_allow_free_form": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Entities Allow Free Form",
|
||||||
|
"description": "Allow entities outside the label vocabulary"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"title": "BankTemplateConfig",
|
||||||
|
"description": "Bank configuration fields within a template manifest.\n\nOnly includes configurable (per-bank) fields. Credential fields\n(API keys, base URLs) are intentionally excluded for security."
|
||||||
|
},
|
||||||
|
"BankTemplateDirective": {
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Name",
|
||||||
|
"description": "Human-readable name for the directive (used as match key on re-import)"
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Content",
|
||||||
|
"description": "The directive text to inject into prompts"
|
||||||
|
},
|
||||||
|
"priority": {
|
||||||
|
"type": "integer",
|
||||||
|
"title": "Priority",
|
||||||
|
"description": "Higher priority directives are injected first",
|
||||||
|
"default": 0
|
||||||
|
},
|
||||||
|
"is_active": {
|
||||||
|
"type": "boolean",
|
||||||
|
"title": "Is Active",
|
||||||
|
"description": "Whether this directive is active",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
"title": "Tags",
|
||||||
|
"description": "Tags for filtering",
|
||||||
|
"default": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"content"
|
||||||
|
],
|
||||||
|
"title": "BankTemplateDirective",
|
||||||
|
"description": "A directive definition within a bank template manifest.\n\nDirectives are matched by name on re-import: existing directives\nwith the same name are updated, new ones are created."
|
||||||
|
},
|
||||||
|
"BankTemplateImportResponse": {
|
||||||
|
"properties": {
|
||||||
|
"bank_id": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Bank Id",
|
||||||
|
"description": "Bank that was imported into"
|
||||||
|
},
|
||||||
|
"config_applied": {
|
||||||
|
"type": "boolean",
|
||||||
|
"title": "Config Applied",
|
||||||
|
"description": "Whether bank config was updated"
|
||||||
|
},
|
||||||
|
"mental_models_created": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
"title": "Mental Models Created",
|
||||||
|
"description": "IDs of newly created mental models",
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"mental_models_updated": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
"title": "Mental Models Updated",
|
||||||
|
"description": "IDs of updated mental models",
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"directives_created": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
"title": "Directives Created",
|
||||||
|
"description": "Names of newly created directives",
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"directives_updated": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
"title": "Directives Updated",
|
||||||
|
"description": "Names of updated directives",
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"operation_ids": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
"title": "Operation Ids",
|
||||||
|
"description": "Operation IDs for mental model content generation (async)",
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"dry_run": {
|
||||||
|
"type": "boolean",
|
||||||
|
"title": "Dry Run",
|
||||||
|
"description": "True if this was a validation-only run",
|
||||||
|
"default": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"bank_id",
|
||||||
|
"config_applied"
|
||||||
|
],
|
||||||
|
"title": "BankTemplateImportResponse",
|
||||||
|
"description": "Response model for the bank template import endpoint."
|
||||||
|
},
|
||||||
|
"BankTemplateManifest": {
|
||||||
|
"properties": {
|
||||||
|
"version": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Version",
|
||||||
|
"description": "Manifest schema version (currently '1')"
|
||||||
|
},
|
||||||
|
"bank": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/BankTemplateConfig"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Bank configuration to apply. Omit to leave config unchanged."
|
||||||
|
},
|
||||||
|
"mental_models": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/BankTemplateMentalModel"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Mental Models",
|
||||||
|
"description": "Mental models to create or update (matched by id). Omit to leave unchanged."
|
||||||
|
},
|
||||||
|
"directives": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/BankTemplateDirective"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Directives",
|
||||||
|
"description": "Directives to create or update (matched by name). Omit to leave unchanged."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"version"
|
||||||
|
],
|
||||||
|
"title": "BankTemplateManifest",
|
||||||
|
"description": "A bank template manifest for import/export.\n\nVersion field enables forward-compatible schema evolution: the API\nauto-upgrades older manifest versions to the current schema on import.",
|
||||||
|
"example": {
|
||||||
|
"bank": {
|
||||||
|
"disposition_empathy": 5,
|
||||||
|
"enable_observations": true,
|
||||||
|
"reflect_mission": "You are helping a support agent remember customer interactions.",
|
||||||
|
"retain_mission": "Extract customer issues, resolutions, and sentiment."
|
||||||
|
},
|
||||||
|
"directives": [
|
||||||
|
{
|
||||||
|
"content": "Always respond with empathy and understanding.",
|
||||||
|
"name": "Always be empathetic",
|
||||||
|
"priority": 10
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "sentiment-overview",
|
||||||
|
"name": "Customer Sentiment Overview",
|
||||||
|
"source_query": "What is the overall sentiment trend?",
|
||||||
|
"trigger": {
|
||||||
|
"refresh_after_consolidation": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"BankTemplateMentalModel": {
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Id",
|
||||||
|
"description": "Unique ID for the mental model (alphanumeric lowercase with hyphens)"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Name",
|
||||||
|
"description": "Human-readable name for the mental model"
|
||||||
|
},
|
||||||
|
"source_query": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Source Query",
|
||||||
|
"description": "The query to run to generate content"
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
"title": "Tags",
|
||||||
|
"description": "Tags for scoped visibility",
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"max_tokens": {
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 8192.0,
|
||||||
|
"minimum": 256.0,
|
||||||
|
"title": "Max Tokens",
|
||||||
|
"description": "Maximum tokens for generated content",
|
||||||
|
"default": 2048
|
||||||
|
},
|
||||||
|
"trigger": {
|
||||||
|
"$ref": "#/components/schemas/MentalModelTrigger-Output",
|
||||||
|
"description": "Trigger settings",
|
||||||
|
"default": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"source_query"
|
||||||
|
],
|
||||||
|
"title": "BankTemplateMentalModel",
|
||||||
|
"description": "A mental model definition within a bank template manifest."
|
||||||
|
},
|
||||||
"Body_file_retain": {
|
"Body_file_retain": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"files": {
|
"files": {
|
||||||
|
|
|
||||||
437
skills/hindsight-docs/references/developer/api/bank-templates.md
Normal file
437
skills/hindsight-docs/references/developer/api/bank-templates.md
Normal file
|
|
@ -0,0 +1,437 @@
|
||||||
|
|
||||||
|
# Bank Templates
|
||||||
|
|
||||||
|
Declarative JSON manifests for creating pre-configured memory banks with a single API call.
|
||||||
|
|
||||||
|
{/* Import raw source files */}
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
A bank template is a JSON manifest that describes a bank's full setup: configuration overrides, mental models, directives, and more. Instead of making multiple API calls to configure a bank, you submit one manifest and the API provisions everything.
|
||||||
|
|
||||||
|
Templates are useful for:
|
||||||
|
- **Replication** — stamp out identically-configured banks for multiple users or agents
|
||||||
|
- **Onboarding** — new users start with a known-good configuration instead of configuring from scratch
|
||||||
|
- **Sharing** — distribute recommended setups as portable JSON files
|
||||||
|
- **Framework integrations** — ship a recommended template alongside your integration
|
||||||
|
|
||||||
|
Browse the Bank Templates Hub for ready-to-use templates.
|
||||||
|
|
||||||
|
## Manifest Schema
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"version": "1",
|
||||||
|
"bank": {
|
||||||
|
"reflect_mission": "...",
|
||||||
|
"retain_mission": "...",
|
||||||
|
"retain_extraction_mode": "concise | verbose | custom | chunks",
|
||||||
|
"retain_custom_instructions": "...",
|
||||||
|
"retain_chunk_size": 2048,
|
||||||
|
"disposition_skepticism": 3,
|
||||||
|
"disposition_literalism": 3,
|
||||||
|
"disposition_empathy": 3,
|
||||||
|
"enable_observations": true,
|
||||||
|
"observations_mission": "...",
|
||||||
|
"entity_labels": ["PERSON", "ORGANIZATION"],
|
||||||
|
"entities_allow_free_form": true
|
||||||
|
},
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "unique-lowercase-id",
|
||||||
|
"name": "Human-Readable Name",
|
||||||
|
"source_query": "The query that generates this mental model's content",
|
||||||
|
"tags": ["optional", "tags"],
|
||||||
|
"max_tokens": 2048,
|
||||||
|
"trigger": {
|
||||||
|
"refresh_after_consolidation": false,
|
||||||
|
"fact_types": ["world", "experience", "observation"],
|
||||||
|
"exclude_mental_models": false,
|
||||||
|
"exclude_mental_model_ids": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"directives": [
|
||||||
|
{
|
||||||
|
"name": "directive-name",
|
||||||
|
"content": "The directive instruction text",
|
||||||
|
"priority": 0,
|
||||||
|
"is_active": true,
|
||||||
|
"tags": ["optional", "tags"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fields
|
||||||
|
|
||||||
|
| Field | Required | Description |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| `version` | Yes | Schema version. Currently `"1"`. |
|
||||||
|
| `bank` | No | Bank configuration overrides. Omit to leave config unchanged. |
|
||||||
|
| `mental_models` | No | Mental models to create or update. Omit to leave unchanged. |
|
||||||
|
| `directives` | No | Directives to create or update. Omit to leave unchanged. |
|
||||||
|
|
||||||
|
All of `bank`, `mental_models`, and `directives` are optional. Omit any section to leave that part of the bank unchanged.
|
||||||
|
|
||||||
|
### Bank Config Fields
|
||||||
|
|
||||||
|
All fields in `bank` are optional. Only the fields you include will be set as per-bank overrides — everything else inherits from the server/tenant defaults.
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-------|------|-------------|
|
||||||
|
| `reflect_mission` | string | Mission/context for reflect operations |
|
||||||
|
| `retain_mission` | string | Steers what gets extracted during retain |
|
||||||
|
| `retain_extraction_mode` | string | `concise`, `verbose`, `custom`, or `chunks` |
|
||||||
|
| `retain_custom_instructions` | string | Custom extraction prompt (requires `mode=custom`) |
|
||||||
|
| `retain_chunk_size` | integer | Max token size per content chunk |
|
||||||
|
| `disposition_skepticism` | integer (1-5) | How skeptical the disposition is |
|
||||||
|
| `disposition_literalism` | integer (1-5) | How literal the disposition is |
|
||||||
|
| `disposition_empathy` | integer (1-5) | How empathetic the disposition is |
|
||||||
|
| `enable_observations` | boolean | Toggle observation consolidation |
|
||||||
|
| `observations_mission` | string | Controls what gets synthesised into observations |
|
||||||
|
| `entity_labels` | string[] | Controlled vocabulary for entity labels |
|
||||||
|
| `entities_allow_free_form` | boolean | Allow entities outside the label vocabulary |
|
||||||
|
|
||||||
|
### Mental Model Fields
|
||||||
|
|
||||||
|
| Field | Required | Description |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| `id` | Yes | Unique ID (lowercase alphanumeric with hyphens). Used to match on re-import. |
|
||||||
|
| `name` | Yes | Human-readable name |
|
||||||
|
| `source_query` | Yes | The query that generates this model's content via reflect |
|
||||||
|
| `tags` | No | Tags for scoped visibility. Default: `[]` |
|
||||||
|
| `max_tokens` | No | Max tokens for generated content (256-8192). Default: `2048` |
|
||||||
|
| `trigger` | No | Trigger settings for auto-refresh |
|
||||||
|
|
||||||
|
### Directive Fields
|
||||||
|
|
||||||
|
| Field | Required | Description |
|
||||||
|
|-------|----------|-------------|
|
||||||
|
| `name` | Yes | Directive name. Used as the match key on re-import. |
|
||||||
|
| `content` | Yes | The directive instruction text. |
|
||||||
|
| `priority` | No | Priority value (higher = more important). Default: `0` |
|
||||||
|
| `is_active` | No | Whether the directive is active. Default: `true` |
|
||||||
|
| `tags` | No | Tags for categorization. Default: `[]` |
|
||||||
|
|
||||||
|
## Import
|
||||||
|
|
||||||
|
Import a manifest into a bank. If the bank doesn't exist, it's created automatically.
|
||||||
|
|
||||||
|
### Python
|
||||||
|
|
||||||
|
```python
|
||||||
|
template = {
|
||||||
|
"version": "1",
|
||||||
|
"bank": {
|
||||||
|
"retain_mission": "Extract customer issues, resolutions, and sentiment.",
|
||||||
|
"enable_observations": True,
|
||||||
|
"observations_mission": "Track recurring customer pain points.",
|
||||||
|
},
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "sentiment-overview",
|
||||||
|
"name": "Customer Sentiment Overview",
|
||||||
|
"source_query": "What is the overall sentiment trend?",
|
||||||
|
"trigger": {"refresh_after_consolidation": True},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"directives": [
|
||||||
|
{
|
||||||
|
"name": "Acknowledge frustration",
|
||||||
|
"content": "Always acknowledge frustration before offering solutions.",
|
||||||
|
"priority": 10,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.post(
|
||||||
|
f"{HINDSIGHT_URL}/v1/default/banks/my-bank/import",
|
||||||
|
json=template,
|
||||||
|
)
|
||||||
|
result = response.json()
|
||||||
|
print(f"Config applied: {result['config_applied']}")
|
||||||
|
print(f"Mental models created: {result['mental_models_created']}")
|
||||||
|
print(f"Directives created: {result['directives_created']}")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Node.js
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const template = {
|
||||||
|
version: '1',
|
||||||
|
bank: {
|
||||||
|
retain_mission: 'Extract customer issues, resolutions, and sentiment.',
|
||||||
|
enable_observations: true,
|
||||||
|
observations_mission: 'Track recurring customer pain points.',
|
||||||
|
},
|
||||||
|
mental_models: [
|
||||||
|
{
|
||||||
|
id: 'sentiment-overview',
|
||||||
|
name: 'Customer Sentiment Overview',
|
||||||
|
source_query: 'What is the overall sentiment trend?',
|
||||||
|
trigger: { refresh_after_consolidation: true },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
directives: [
|
||||||
|
{
|
||||||
|
name: 'Acknowledge frustration',
|
||||||
|
content: 'Always acknowledge frustration before offering solutions.',
|
||||||
|
priority: 10,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const importResponse = await fetch(
|
||||||
|
`${HINDSIGHT_URL}/v1/default/banks/my-bank/import`,
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(template),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const result = await importResponse.json();
|
||||||
|
console.log('Config applied:', result.config_applied);
|
||||||
|
console.log('Mental models created:', result.mental_models_created);
|
||||||
|
console.log('Directives created:', result.directives_created);
|
||||||
|
```
|
||||||
|
|
||||||
|
### CLI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "$HINDSIGHT_URL/v1/default/banks/my-bank/import" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"version": "1",
|
||||||
|
"bank": {
|
||||||
|
"retain_mission": "Extract customer issues, resolutions, and sentiment.",
|
||||||
|
"enable_observations": true,
|
||||||
|
"observations_mission": "Track recurring customer pain points."
|
||||||
|
},
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "sentiment-overview",
|
||||||
|
"name": "Customer Sentiment Overview",
|
||||||
|
"source_query": "What is the overall sentiment trend?",
|
||||||
|
"trigger": { "refresh_after_consolidation": true }
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"directives": [
|
||||||
|
{
|
||||||
|
"name": "Acknowledge frustration",
|
||||||
|
"content": "Always acknowledge frustration before offering solutions.",
|
||||||
|
"priority": 10
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Go
|
||||||
|
|
||||||
|
```go
|
||||||
|
# Section 'import-template' not found in api/bank-templates.go
|
||||||
|
```
|
||||||
|
|
||||||
|
### Behavior
|
||||||
|
|
||||||
|
- **Config**: all `bank` fields are applied as per-bank config overrides
|
||||||
|
- **Mental models**: matched by `id` — existing models are updated, new ones are created
|
||||||
|
- **Directives**: matched by `name` — existing directives are updated, new ones are created
|
||||||
|
- **Async**: mental model content is generated asynchronously. The response includes `operation_ids` to track progress.
|
||||||
|
|
||||||
|
### Dry Run
|
||||||
|
|
||||||
|
Validate a manifest without applying changes:
|
||||||
|
|
||||||
|
### Python
|
||||||
|
|
||||||
|
```python
|
||||||
|
response = requests.post(
|
||||||
|
f"{HINDSIGHT_URL}/v1/default/banks/my-bank/import",
|
||||||
|
params={"dry_run": "true"},
|
||||||
|
json=template,
|
||||||
|
)
|
||||||
|
result = response.json()
|
||||||
|
print(f"Dry run: {result['dry_run']}")
|
||||||
|
print(f"Would apply config: {result['config_applied']}")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Node.js
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const dryRunResponse = await fetch(
|
||||||
|
`${HINDSIGHT_URL}/v1/default/banks/my-bank/import?dry_run=true`,
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(template),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const dryRunResult = await dryRunResponse.json();
|
||||||
|
console.log('Dry run:', dryRunResult.dry_run);
|
||||||
|
console.log('Would apply config:', dryRunResult.config_applied);
|
||||||
|
```
|
||||||
|
|
||||||
|
### CLI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -X POST "$HINDSIGHT_URL/v1/default/banks/my-bank/import?dry_run=true" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d @template.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Go
|
||||||
|
|
||||||
|
```go
|
||||||
|
# Section 'import-dry-run' not found in api/bank-templates.go
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns what *would* happen (which config would be applied, which mental models would be created) without making any changes. Returns HTTP 400 with a detailed error message if the manifest is invalid.
|
||||||
|
|
||||||
|
## Export
|
||||||
|
|
||||||
|
Export a bank's current config overrides, mental models, and directives as a manifest:
|
||||||
|
|
||||||
|
### Python
|
||||||
|
|
||||||
|
```python
|
||||||
|
response = requests.get(
|
||||||
|
f"{HINDSIGHT_URL}/v1/default/banks/my-bank/export"
|
||||||
|
)
|
||||||
|
exported = response.json()
|
||||||
|
print(json.dumps(exported, indent=2))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Node.js
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const exportResponse = await fetch(
|
||||||
|
`${HINDSIGHT_URL}/v1/default/banks/my-bank/export`,
|
||||||
|
);
|
||||||
|
const exported = await exportResponse.json();
|
||||||
|
console.log(JSON.stringify(exported, null, 2));
|
||||||
|
```
|
||||||
|
|
||||||
|
### CLI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl "$HINDSIGHT_URL/v1/default/banks/my-bank/export"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Go
|
||||||
|
|
||||||
|
```go
|
||||||
|
# Section 'export-template' not found in api/bank-templates.go
|
||||||
|
```
|
||||||
|
|
||||||
|
The exported manifest only includes config fields that were explicitly set as per-bank overrides — not the fully resolved config (which includes server/tenant defaults). This means the exported manifest is portable: importing it into a new bank only overrides the fields that were intentionally customized.
|
||||||
|
|
||||||
|
### Round-trip
|
||||||
|
|
||||||
|
Export from one bank and import into another to replicate the setup:
|
||||||
|
|
||||||
|
### Python
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Export from source bank
|
||||||
|
response = requests.get(
|
||||||
|
f"{HINDSIGHT_URL}/v1/default/banks/source-bank/export"
|
||||||
|
)
|
||||||
|
exported = response.json()
|
||||||
|
|
||||||
|
# Import into a new bank
|
||||||
|
response = requests.post(
|
||||||
|
f"{HINDSIGHT_URL}/v1/default/banks/new-bank/import",
|
||||||
|
json=exported,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Node.js
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Export from source bank
|
||||||
|
const srcResponse = await fetch(
|
||||||
|
`${HINDSIGHT_URL}/v1/default/banks/source-bank/export`,
|
||||||
|
);
|
||||||
|
const srcExported = await srcResponse.json();
|
||||||
|
|
||||||
|
// Import into a new bank
|
||||||
|
await fetch(`${HINDSIGHT_URL}/v1/default/banks/new-bank/import`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(srcExported),
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### CLI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Export from source bank
|
||||||
|
curl "$HINDSIGHT_URL/v1/default/banks/source-bank/export" > template.json
|
||||||
|
|
||||||
|
# Import into a new bank
|
||||||
|
curl -X POST "$HINDSIGHT_URL/v1/default/banks/new-bank/import" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d @template.json
|
||||||
|
```
|
||||||
|
|
||||||
|
### Go
|
||||||
|
|
||||||
|
```go
|
||||||
|
# Section 'export-reimport' not found in api/bank-templates.go
|
||||||
|
```
|
||||||
|
|
||||||
|
## JSON Schema
|
||||||
|
|
||||||
|
The manifest format is defined by a JSON Schema. Fetch the live schema from your server:
|
||||||
|
|
||||||
|
### Python
|
||||||
|
|
||||||
|
```python
|
||||||
|
response = requests.get(
|
||||||
|
f"{HINDSIGHT_URL}/v1/bank-template-schema"
|
||||||
|
)
|
||||||
|
schema = response.json()
|
||||||
|
print(json.dumps(schema, indent=2))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Node.js
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const schemaResponse = await fetch(
|
||||||
|
`${HINDSIGHT_URL}/v1/bank-template-schema`,
|
||||||
|
);
|
||||||
|
const schema = await schemaResponse.json();
|
||||||
|
console.log(JSON.stringify(schema, null, 2));
|
||||||
|
```
|
||||||
|
|
||||||
|
### CLI
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl "$HINDSIGHT_URL/v1/bank-template-schema"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Go
|
||||||
|
|
||||||
|
```go
|
||||||
|
# Section 'get-schema' not found in api/bank-templates.go
|
||||||
|
```
|
||||||
|
|
||||||
|
The static schema is also available at bank-template-schema.json.
|
||||||
|
|
||||||
|
## Control Plane
|
||||||
|
|
||||||
|
The control plane bank creation dialog includes an optional "Import from template" toggle. Enable it to paste a manifest JSON and pre-configure the bank on creation.
|
||||||
|
|
||||||
|
You can also export any bank's template from the bank Settings page via **Actions → Export Template**, which copies the manifest JSON to your clipboard.
|
||||||
|
|
||||||
|
## Versioning
|
||||||
|
|
||||||
|
The `version` field enables forward-compatible schema evolution. The current version is `"1"`.
|
||||||
|
|
||||||
|
When future versions are released:
|
||||||
|
- Older manifests are automatically upgraded to the current schema on import
|
||||||
|
- Export always produces the latest version
|
||||||
|
- The API rejects manifests with a version newer than what the server supports (with a clear error message suggesting an upgrade)
|
||||||
|
|
||||||
|
This means old templates keep working indefinitely — no need to manually update them.
|
||||||
|
|
@ -3066,6 +3066,156 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/v1/default/banks/{bank_id}/import": {
|
||||||
|
"post": {
|
||||||
|
"tags": [
|
||||||
|
"Bank Templates"
|
||||||
|
],
|
||||||
|
"summary": "Import bank template",
|
||||||
|
"description": "Import a bank template manifest to create or update a bank's configuration, mental models, and directives. If the bank does not exist it is created. Config fields are applied as per-bank overrides. Mental models are matched by id, directives by name \u2014 existing ones are updated, new ones are created. Use dry_run=true to validate the manifest without applying changes.",
|
||||||
|
"operationId": "import_bank_template",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "bank_id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Bank Id"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dry_run",
|
||||||
|
"in": "query",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Validate only, do not apply changes",
|
||||||
|
"default": false,
|
||||||
|
"title": "Dry Run"
|
||||||
|
},
|
||||||
|
"description": "Validate only, do not apply changes"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "authorization",
|
||||||
|
"in": "header",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Authorization"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/BankTemplateImportResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"description": "Validation Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/HTTPValidationError"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/v1/default/banks/{bank_id}/export": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Bank Templates"
|
||||||
|
],
|
||||||
|
"summary": "Export bank template",
|
||||||
|
"description": "Export a bank's current configuration, mental models, and directives as a template manifest. The exported manifest can be imported into another bank to replicate the setup.",
|
||||||
|
"operationId": "export_bank_template",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "bank_id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Bank Id"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "authorization",
|
||||||
|
"in": "header",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Authorization"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/BankTemplateManifest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"422": {
|
||||||
|
"description": "Validation Error",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/HTTPValidationError"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/v1/bank-template-schema": {
|
||||||
|
"get": {
|
||||||
|
"tags": [
|
||||||
|
"Bank Templates"
|
||||||
|
],
|
||||||
|
"summary": "Get bank template JSON Schema",
|
||||||
|
"description": "Returns the JSON Schema for the bank template manifest format. Use this to validate template manifests before importing.",
|
||||||
|
"operationId": "get_bank_template_schema",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Successful Response",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/v1/default/banks/{bank_id}/observations": {
|
"/v1/default/banks/{bank_id}/observations": {
|
||||||
"delete": {
|
"delete": {
|
||||||
"tags": [
|
"tags": [
|
||||||
|
|
@ -4959,6 +5109,411 @@
|
||||||
"total_observations": 45
|
"total_observations": 45
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"BankTemplateConfig": {
|
||||||
|
"properties": {
|
||||||
|
"reflect_mission": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Reflect Mission",
|
||||||
|
"description": "Mission/context for Reflect operations"
|
||||||
|
},
|
||||||
|
"retain_mission": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Retain Mission",
|
||||||
|
"description": "Steers what gets extracted during retain"
|
||||||
|
},
|
||||||
|
"retain_extraction_mode": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Retain Extraction Mode",
|
||||||
|
"description": "Fact extraction mode: 'concise' (default), 'verbose', or 'custom'"
|
||||||
|
},
|
||||||
|
"retain_custom_instructions": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Retain Custom Instructions",
|
||||||
|
"description": "Custom extraction prompt (when mode='custom')"
|
||||||
|
},
|
||||||
|
"retain_chunk_size": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Retain Chunk Size",
|
||||||
|
"description": "Max token size for each content chunk"
|
||||||
|
},
|
||||||
|
"enable_observations": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Enable Observations",
|
||||||
|
"description": "Toggle observation consolidation"
|
||||||
|
},
|
||||||
|
"observations_mission": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Observations Mission",
|
||||||
|
"description": "Controls what gets synthesised"
|
||||||
|
},
|
||||||
|
"disposition_skepticism": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 5.0,
|
||||||
|
"minimum": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Disposition Skepticism",
|
||||||
|
"description": "Skepticism trait (1-5)"
|
||||||
|
},
|
||||||
|
"disposition_literalism": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 5.0,
|
||||||
|
"minimum": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Disposition Literalism",
|
||||||
|
"description": "Literalism trait (1-5)"
|
||||||
|
},
|
||||||
|
"disposition_empathy": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 5.0,
|
||||||
|
"minimum": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Disposition Empathy",
|
||||||
|
"description": "Empathy trait (1-5)"
|
||||||
|
},
|
||||||
|
"entity_labels": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Entity Labels",
|
||||||
|
"description": "Controlled vocabulary for entity labels"
|
||||||
|
},
|
||||||
|
"entities_allow_free_form": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Entities Allow Free Form",
|
||||||
|
"description": "Allow entities outside the label vocabulary"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"title": "BankTemplateConfig",
|
||||||
|
"description": "Bank configuration fields within a template manifest.\n\nOnly includes configurable (per-bank) fields. Credential fields\n(API keys, base URLs) are intentionally excluded for security."
|
||||||
|
},
|
||||||
|
"BankTemplateDirective": {
|
||||||
|
"properties": {
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Name",
|
||||||
|
"description": "Human-readable name for the directive (used as match key on re-import)"
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Content",
|
||||||
|
"description": "The directive text to inject into prompts"
|
||||||
|
},
|
||||||
|
"priority": {
|
||||||
|
"type": "integer",
|
||||||
|
"title": "Priority",
|
||||||
|
"description": "Higher priority directives are injected first",
|
||||||
|
"default": 0
|
||||||
|
},
|
||||||
|
"is_active": {
|
||||||
|
"type": "boolean",
|
||||||
|
"title": "Is Active",
|
||||||
|
"description": "Whether this directive is active",
|
||||||
|
"default": true
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
"title": "Tags",
|
||||||
|
"description": "Tags for filtering",
|
||||||
|
"default": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"content"
|
||||||
|
],
|
||||||
|
"title": "BankTemplateDirective",
|
||||||
|
"description": "A directive definition within a bank template manifest.\n\nDirectives are matched by name on re-import: existing directives\nwith the same name are updated, new ones are created."
|
||||||
|
},
|
||||||
|
"BankTemplateImportResponse": {
|
||||||
|
"properties": {
|
||||||
|
"bank_id": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Bank Id",
|
||||||
|
"description": "Bank that was imported into"
|
||||||
|
},
|
||||||
|
"config_applied": {
|
||||||
|
"type": "boolean",
|
||||||
|
"title": "Config Applied",
|
||||||
|
"description": "Whether bank config was updated"
|
||||||
|
},
|
||||||
|
"mental_models_created": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
"title": "Mental Models Created",
|
||||||
|
"description": "IDs of newly created mental models",
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"mental_models_updated": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
"title": "Mental Models Updated",
|
||||||
|
"description": "IDs of updated mental models",
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"directives_created": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
"title": "Directives Created",
|
||||||
|
"description": "Names of newly created directives",
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"directives_updated": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
"title": "Directives Updated",
|
||||||
|
"description": "Names of updated directives",
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"operation_ids": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
"title": "Operation Ids",
|
||||||
|
"description": "Operation IDs for mental model content generation (async)",
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"dry_run": {
|
||||||
|
"type": "boolean",
|
||||||
|
"title": "Dry Run",
|
||||||
|
"description": "True if this was a validation-only run",
|
||||||
|
"default": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"bank_id",
|
||||||
|
"config_applied"
|
||||||
|
],
|
||||||
|
"title": "BankTemplateImportResponse",
|
||||||
|
"description": "Response model for the bank template import endpoint."
|
||||||
|
},
|
||||||
|
"BankTemplateManifest": {
|
||||||
|
"properties": {
|
||||||
|
"version": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Version",
|
||||||
|
"description": "Manifest schema version (currently '1')"
|
||||||
|
},
|
||||||
|
"bank": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/BankTemplateConfig"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Bank configuration to apply. Omit to leave config unchanged."
|
||||||
|
},
|
||||||
|
"mental_models": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/BankTemplateMentalModel"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Mental Models",
|
||||||
|
"description": "Mental models to create or update (matched by id). Omit to leave unchanged."
|
||||||
|
},
|
||||||
|
"directives": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/BankTemplateDirective"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"title": "Directives",
|
||||||
|
"description": "Directives to create or update (matched by name). Omit to leave unchanged."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"version"
|
||||||
|
],
|
||||||
|
"title": "BankTemplateManifest",
|
||||||
|
"description": "A bank template manifest for import/export.\n\nVersion field enables forward-compatible schema evolution: the API\nauto-upgrades older manifest versions to the current schema on import.",
|
||||||
|
"example": {
|
||||||
|
"bank": {
|
||||||
|
"disposition_empathy": 5,
|
||||||
|
"enable_observations": true,
|
||||||
|
"reflect_mission": "You are helping a support agent remember customer interactions.",
|
||||||
|
"retain_mission": "Extract customer issues, resolutions, and sentiment."
|
||||||
|
},
|
||||||
|
"directives": [
|
||||||
|
{
|
||||||
|
"content": "Always respond with empathy and understanding.",
|
||||||
|
"name": "Always be empathetic",
|
||||||
|
"priority": 10
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"mental_models": [
|
||||||
|
{
|
||||||
|
"id": "sentiment-overview",
|
||||||
|
"name": "Customer Sentiment Overview",
|
||||||
|
"source_query": "What is the overall sentiment trend?",
|
||||||
|
"trigger": {
|
||||||
|
"refresh_after_consolidation": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"BankTemplateMentalModel": {
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Id",
|
||||||
|
"description": "Unique ID for the mental model (alphanumeric lowercase with hyphens)"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Name",
|
||||||
|
"description": "Human-readable name for the mental model"
|
||||||
|
},
|
||||||
|
"source_query": {
|
||||||
|
"type": "string",
|
||||||
|
"title": "Source Query",
|
||||||
|
"description": "The query to run to generate content"
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "array",
|
||||||
|
"title": "Tags",
|
||||||
|
"description": "Tags for scoped visibility",
|
||||||
|
"default": []
|
||||||
|
},
|
||||||
|
"max_tokens": {
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 8192.0,
|
||||||
|
"minimum": 256.0,
|
||||||
|
"title": "Max Tokens",
|
||||||
|
"description": "Maximum tokens for generated content",
|
||||||
|
"default": 2048
|
||||||
|
},
|
||||||
|
"trigger": {
|
||||||
|
"$ref": "#/components/schemas/MentalModelTrigger-Output",
|
||||||
|
"description": "Trigger settings",
|
||||||
|
"default": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"source_query"
|
||||||
|
],
|
||||||
|
"title": "BankTemplateMentalModel",
|
||||||
|
"description": "A mental model definition within a bank template manifest."
|
||||||
|
},
|
||||||
"Body_file_retain": {
|
"Body_file_retain": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"files": {
|
"files": {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue