hindsight-api 0.2.1__py3-none-any.whl → 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hindsight_api/admin/__init__.py +1 -0
- hindsight_api/admin/cli.py +311 -0
- hindsight_api/alembic/versions/f1a2b3c4d5e6_add_memory_links_composite_index.py +44 -0
- hindsight_api/alembic/versions/g2a3b4c5d6e7_add_tags_column.py +48 -0
- hindsight_api/alembic/versions/h3c4d5e6f7g8_mental_models_v4.py +112 -0
- hindsight_api/alembic/versions/i4d5e6f7g8h9_delete_opinions.py +41 -0
- hindsight_api/alembic/versions/j5e6f7g8h9i0_mental_model_versions.py +95 -0
- hindsight_api/alembic/versions/k6f7g8h9i0j1_add_directive_subtype.py +58 -0
- hindsight_api/alembic/versions/l7g8h9i0j1k2_add_worker_columns.py +109 -0
- hindsight_api/alembic/versions/m8h9i0j1k2l3_mental_model_id_to_text.py +41 -0
- hindsight_api/alembic/versions/n9i0j1k2l3m4_learnings_and_pinned_reflections.py +134 -0
- hindsight_api/alembic/versions/o0j1k2l3m4n5_migrate_mental_models_data.py +113 -0
- hindsight_api/alembic/versions/p1k2l3m4n5o6_new_knowledge_architecture.py +194 -0
- hindsight_api/alembic/versions/q2l3m4n5o6p7_fix_mental_model_fact_type.py +50 -0
- hindsight_api/alembic/versions/r3m4n5o6p7q8_add_reflect_response_to_reflections.py +47 -0
- hindsight_api/alembic/versions/s4n5o6p7q8r9_add_consolidated_at_to_memory_units.py +53 -0
- hindsight_api/alembic/versions/t5o6p7q8r9s0_rename_mental_models_to_observations.py +134 -0
- hindsight_api/alembic/versions/u6p7q8r9s0t1_mental_models_text_id.py +41 -0
- hindsight_api/alembic/versions/v7q8r9s0t1u2_add_max_tokens_to_mental_models.py +50 -0
- hindsight_api/api/http.py +1406 -118
- hindsight_api/api/mcp.py +11 -196
- hindsight_api/config.py +359 -27
- hindsight_api/engine/consolidation/__init__.py +5 -0
- hindsight_api/engine/consolidation/consolidator.py +859 -0
- hindsight_api/engine/consolidation/prompts.py +69 -0
- hindsight_api/engine/cross_encoder.py +706 -88
- hindsight_api/engine/db_budget.py +284 -0
- hindsight_api/engine/db_utils.py +11 -0
- hindsight_api/engine/directives/__init__.py +5 -0
- hindsight_api/engine/directives/models.py +37 -0
- hindsight_api/engine/embeddings.py +553 -29
- hindsight_api/engine/entity_resolver.py +8 -5
- hindsight_api/engine/interface.py +40 -17
- hindsight_api/engine/llm_wrapper.py +744 -68
- hindsight_api/engine/memory_engine.py +2505 -1017
- hindsight_api/engine/mental_models/__init__.py +14 -0
- hindsight_api/engine/mental_models/models.py +53 -0
- hindsight_api/engine/query_analyzer.py +4 -3
- hindsight_api/engine/reflect/__init__.py +18 -0
- hindsight_api/engine/reflect/agent.py +933 -0
- hindsight_api/engine/reflect/models.py +109 -0
- hindsight_api/engine/reflect/observations.py +186 -0
- hindsight_api/engine/reflect/prompts.py +483 -0
- hindsight_api/engine/reflect/tools.py +437 -0
- hindsight_api/engine/reflect/tools_schema.py +250 -0
- hindsight_api/engine/response_models.py +168 -4
- hindsight_api/engine/retain/bank_utils.py +79 -201
- hindsight_api/engine/retain/fact_extraction.py +424 -195
- hindsight_api/engine/retain/fact_storage.py +35 -12
- hindsight_api/engine/retain/link_utils.py +29 -24
- hindsight_api/engine/retain/orchestrator.py +24 -43
- hindsight_api/engine/retain/types.py +11 -2
- hindsight_api/engine/search/graph_retrieval.py +43 -14
- hindsight_api/engine/search/link_expansion_retrieval.py +391 -0
- hindsight_api/engine/search/mpfp_retrieval.py +362 -117
- hindsight_api/engine/search/reranking.py +2 -2
- hindsight_api/engine/search/retrieval.py +848 -201
- hindsight_api/engine/search/tags.py +172 -0
- hindsight_api/engine/search/think_utils.py +42 -141
- hindsight_api/engine/search/trace.py +12 -1
- hindsight_api/engine/search/tracer.py +26 -6
- hindsight_api/engine/search/types.py +21 -3
- hindsight_api/engine/task_backend.py +113 -106
- hindsight_api/engine/utils.py +1 -152
- hindsight_api/extensions/__init__.py +10 -1
- hindsight_api/extensions/builtin/tenant.py +5 -1
- hindsight_api/extensions/context.py +10 -1
- hindsight_api/extensions/operation_validator.py +81 -4
- hindsight_api/extensions/tenant.py +26 -0
- hindsight_api/main.py +69 -6
- hindsight_api/mcp_local.py +12 -53
- hindsight_api/mcp_tools.py +494 -0
- hindsight_api/metrics.py +433 -48
- hindsight_api/migrations.py +141 -1
- hindsight_api/models.py +3 -3
- hindsight_api/pg0.py +53 -0
- hindsight_api/server.py +39 -2
- hindsight_api/worker/__init__.py +11 -0
- hindsight_api/worker/main.py +296 -0
- hindsight_api/worker/poller.py +486 -0
- {hindsight_api-0.2.1.dist-info → hindsight_api-0.4.0.dist-info}/METADATA +16 -6
- hindsight_api-0.4.0.dist-info/RECORD +112 -0
- {hindsight_api-0.2.1.dist-info → hindsight_api-0.4.0.dist-info}/entry_points.txt +2 -0
- hindsight_api/engine/retain/observation_regeneration.py +0 -254
- hindsight_api/engine/search/observation_utils.py +0 -125
- hindsight_api/engine/search/scoring.py +0 -159
- hindsight_api-0.2.1.dist-info/RECORD +0 -75
- {hindsight_api-0.2.1.dist-info → hindsight_api-0.4.0.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""fix_mental_model_fact_type
|
|
2
|
+
|
|
3
|
+
Revision ID: q2l3m4n5o6p7
|
|
4
|
+
Revises: p1k2l3m4n5o6
|
|
5
|
+
Create Date: 2026-01-21 13:30:00.000000
|
|
6
|
+
|
|
7
|
+
Fix the fact_type check constraint to include 'mental_model'.
|
|
8
|
+
This is a fix for p1k2l3m4n5o6 which should have included this change.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from collections.abc import Sequence
|
|
12
|
+
|
|
13
|
+
from alembic import context, op
|
|
14
|
+
|
|
15
|
+
# revision identifiers, used by Alembic.
|
|
16
|
+
revision: str = "q2l3m4n5o6p7"
|
|
17
|
+
down_revision: str | Sequence[str] | None = "p1k2l3m4n5o6"
|
|
18
|
+
branch_labels: str | Sequence[str] | None = None
|
|
19
|
+
depends_on: str | Sequence[str] | None = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _get_schema_prefix() -> str:
|
|
23
|
+
"""Get schema prefix for table names (required for multi-tenant support)."""
|
|
24
|
+
schema = context.config.get_main_option("target_schema")
|
|
25
|
+
return f'"{schema}".' if schema else ""
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def upgrade() -> None:
|
|
29
|
+
"""Add 'mental_model' to the fact_type check constraint."""
|
|
30
|
+
schema = _get_schema_prefix()
|
|
31
|
+
|
|
32
|
+
# Drop the old constraint and add the new one with mental_model included
|
|
33
|
+
op.execute(f"ALTER TABLE {schema}memory_units DROP CONSTRAINT IF EXISTS memory_units_fact_type_check")
|
|
34
|
+
op.execute(f"""
|
|
35
|
+
ALTER TABLE {schema}memory_units
|
|
36
|
+
ADD CONSTRAINT memory_units_fact_type_check
|
|
37
|
+
CHECK (fact_type IN ('world', 'experience', 'opinion', 'observation', 'mental_model'))
|
|
38
|
+
""")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def downgrade() -> None:
|
|
42
|
+
"""Remove 'mental_model' from the fact_type check constraint."""
|
|
43
|
+
schema = _get_schema_prefix()
|
|
44
|
+
|
|
45
|
+
op.execute(f"ALTER TABLE {schema}memory_units DROP CONSTRAINT IF EXISTS memory_units_fact_type_check")
|
|
46
|
+
op.execute(f"""
|
|
47
|
+
ALTER TABLE {schema}memory_units
|
|
48
|
+
ADD CONSTRAINT memory_units_fact_type_check
|
|
49
|
+
CHECK (fact_type IN ('world', 'experience', 'opinion', 'observation'))
|
|
50
|
+
""")
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Add reflect_response JSONB column to reflections
|
|
2
|
+
|
|
3
|
+
Revision ID: r3m4n5o6p7q8
|
|
4
|
+
Revises: q2l3m4n5o6p7
|
|
5
|
+
Create Date: 2026-01-21
|
|
6
|
+
|
|
7
|
+
This migration adds a reflect_response JSONB column to store the full
|
|
8
|
+
reflect API response payload, including based_on facts and trace data.
|
|
9
|
+
|
|
10
|
+
Note: Table was renamed from pinned_reflections to reflections in p1k2l3m4n5o6.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from collections.abc import Sequence
|
|
14
|
+
|
|
15
|
+
from alembic import context, op
|
|
16
|
+
|
|
17
|
+
revision: str = "r3m4n5o6p7q8"
|
|
18
|
+
down_revision: str | Sequence[str] | None = "q2l3m4n5o6p7"
|
|
19
|
+
branch_labels: str | Sequence[str] | None = None
|
|
20
|
+
depends_on: str | Sequence[str] | None = None
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _get_schema_prefix() -> str:
|
|
24
|
+
"""Get schema prefix for table names (required for multi-tenant support)."""
|
|
25
|
+
schema = context.config.get_main_option("target_schema")
|
|
26
|
+
return f'"{schema}".' if schema else ""
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def upgrade() -> None:
|
|
30
|
+
"""Add reflect_response JSONB column to reflections."""
|
|
31
|
+
schema = _get_schema_prefix()
|
|
32
|
+
|
|
33
|
+
# Add reflect_response column to store the full reflect API response
|
|
34
|
+
op.execute(f"""
|
|
35
|
+
ALTER TABLE {schema}reflections
|
|
36
|
+
ADD COLUMN IF NOT EXISTS reflect_response JSONB
|
|
37
|
+
""")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def downgrade() -> None:
|
|
41
|
+
"""Remove reflect_response column from reflections."""
|
|
42
|
+
schema = _get_schema_prefix()
|
|
43
|
+
|
|
44
|
+
op.execute(f"""
|
|
45
|
+
ALTER TABLE {schema}reflections
|
|
46
|
+
DROP COLUMN IF EXISTS reflect_response
|
|
47
|
+
""")
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""Add consolidated_at column to memory_units for incremental consolidation tracking.
|
|
2
|
+
|
|
3
|
+
This allows consolidation to track progress at the memory level rather than
|
|
4
|
+
using a bank-level watermark. If consolidation crashes, already-processed
|
|
5
|
+
memories won't be reprocessed.
|
|
6
|
+
|
|
7
|
+
Revision ID: s4n5o6p7q8r9
|
|
8
|
+
Revises: r3m4n5o6p7q8
|
|
9
|
+
Create Date: 2025-01-22
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from collections.abc import Sequence
|
|
13
|
+
|
|
14
|
+
from alembic import context, op
|
|
15
|
+
|
|
16
|
+
revision: str = "s4n5o6p7q8r9"
|
|
17
|
+
down_revision: str | Sequence[str] | None = "r3m4n5o6p7q8"
|
|
18
|
+
branch_labels: str | Sequence[str] | None = None
|
|
19
|
+
depends_on: str | Sequence[str] | None = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _get_schema_prefix() -> str:
|
|
23
|
+
"""Get schema prefix for table names (required for multi-tenant support)."""
|
|
24
|
+
schema = context.config.get_main_option("target_schema")
|
|
25
|
+
return f'"{schema}".' if schema else ""
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def upgrade() -> None:
|
|
29
|
+
schema = _get_schema_prefix()
|
|
30
|
+
|
|
31
|
+
# Add consolidated_at column to memory_units
|
|
32
|
+
op.execute(
|
|
33
|
+
f"""
|
|
34
|
+
ALTER TABLE {schema}memory_units
|
|
35
|
+
ADD COLUMN IF NOT EXISTS consolidated_at TIMESTAMPTZ DEFAULT NULL
|
|
36
|
+
"""
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# Create index for efficient querying of unconsolidated memories
|
|
40
|
+
op.execute(
|
|
41
|
+
f"""
|
|
42
|
+
CREATE INDEX IF NOT EXISTS idx_memory_units_unconsolidated
|
|
43
|
+
ON {schema}memory_units (bank_id, created_at)
|
|
44
|
+
WHERE consolidated_at IS NULL AND fact_type IN ('experience', 'world')
|
|
45
|
+
"""
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def downgrade() -> None:
|
|
50
|
+
schema = _get_schema_prefix()
|
|
51
|
+
|
|
52
|
+
op.execute(f"DROP INDEX IF EXISTS {schema}idx_memory_units_unconsolidated")
|
|
53
|
+
op.execute(f"ALTER TABLE {schema}memory_units DROP COLUMN IF EXISTS consolidated_at")
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"""Rename mental_model fact_type to observation and reflections table to mental_models
|
|
2
|
+
|
|
3
|
+
Revision ID: t5o6p7q8r9s0
|
|
4
|
+
Revises: s4n5o6p7q8r9
|
|
5
|
+
Create Date: 2026-01-26
|
|
6
|
+
|
|
7
|
+
This migration implements the terminology rename:
|
|
8
|
+
1. mental_model (fact_type in memory_units) -> observation
|
|
9
|
+
2. reflections table -> mental_models table
|
|
10
|
+
|
|
11
|
+
The new terminology:
|
|
12
|
+
- Observations: Consolidated knowledge synthesized from facts (was mental_model)
|
|
13
|
+
- Mental Models: Stored reflect responses (was reflections)
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from collections.abc import Sequence
|
|
17
|
+
|
|
18
|
+
from alembic import context, op
|
|
19
|
+
|
|
20
|
+
revision: str = "t5o6p7q8r9s0"
|
|
21
|
+
down_revision: str | Sequence[str] | None = "s4n5o6p7q8r9"
|
|
22
|
+
branch_labels: str | Sequence[str] | None = None
|
|
23
|
+
depends_on: str | Sequence[str] | None = None
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _get_schema_prefix() -> str:
|
|
27
|
+
"""Get schema prefix for table names (required for multi-tenant support)."""
|
|
28
|
+
schema = context.config.get_main_option("target_schema")
|
|
29
|
+
return f'"{schema}".' if schema else ""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def upgrade() -> None:
|
|
33
|
+
"""Rename mental_model -> observation and reflections -> mental_models."""
|
|
34
|
+
schema = _get_schema_prefix()
|
|
35
|
+
|
|
36
|
+
# 1. Update fact_type values: mental_model -> observation
|
|
37
|
+
op.execute(f"""
|
|
38
|
+
UPDATE {schema}memory_units
|
|
39
|
+
SET fact_type = 'observation'
|
|
40
|
+
WHERE fact_type = 'mental_model'
|
|
41
|
+
""")
|
|
42
|
+
|
|
43
|
+
# 2. Update the CHECK constraint - remove mental_model, keep observation
|
|
44
|
+
op.execute(f"ALTER TABLE {schema}memory_units DROP CONSTRAINT IF EXISTS memory_units_fact_type_check")
|
|
45
|
+
op.execute(f"""
|
|
46
|
+
ALTER TABLE {schema}memory_units
|
|
47
|
+
ADD CONSTRAINT memory_units_fact_type_check
|
|
48
|
+
CHECK (fact_type IN ('world', 'experience', 'opinion', 'observation'))
|
|
49
|
+
""")
|
|
50
|
+
|
|
51
|
+
# 3. Rename the index for observations (was for mental_models)
|
|
52
|
+
op.execute(f"DROP INDEX IF EXISTS {schema}idx_memory_units_mental_models")
|
|
53
|
+
op.execute(f"""
|
|
54
|
+
CREATE INDEX IF NOT EXISTS idx_memory_units_observations
|
|
55
|
+
ON {schema}memory_units(bank_id, fact_type)
|
|
56
|
+
WHERE fact_type = 'observation'
|
|
57
|
+
""")
|
|
58
|
+
|
|
59
|
+
# 4. Update the unconsolidated index to not filter by fact_type since observations
|
|
60
|
+
# are now the consolidated type
|
|
61
|
+
op.execute(f"DROP INDEX IF EXISTS {schema}idx_memory_units_unconsolidated")
|
|
62
|
+
op.execute(f"""
|
|
63
|
+
CREATE INDEX IF NOT EXISTS idx_memory_units_unconsolidated
|
|
64
|
+
ON {schema}memory_units (bank_id, created_at)
|
|
65
|
+
WHERE consolidated_at IS NULL AND fact_type IN ('experience', 'world')
|
|
66
|
+
""")
|
|
67
|
+
|
|
68
|
+
# 5. Rename reflections table to mental_models
|
|
69
|
+
op.execute(f"ALTER TABLE IF EXISTS {schema}reflections RENAME TO mental_models")
|
|
70
|
+
|
|
71
|
+
# 6. Rename indexes for mental_models (was reflections)
|
|
72
|
+
op.execute(f"ALTER INDEX IF EXISTS {schema}idx_reflections_bank_id RENAME TO idx_mental_models_bank_id")
|
|
73
|
+
op.execute(f"ALTER INDEX IF EXISTS {schema}idx_reflections_embedding RENAME TO idx_mental_models_embedding")
|
|
74
|
+
op.execute(f"ALTER INDEX IF EXISTS {schema}idx_reflections_tags RENAME TO idx_mental_models_tags")
|
|
75
|
+
op.execute(f"ALTER INDEX IF EXISTS {schema}idx_reflections_text_search RENAME TO idx_mental_models_text_search")
|
|
76
|
+
|
|
77
|
+
# 7. Rename foreign key constraint
|
|
78
|
+
op.execute(f"""
|
|
79
|
+
ALTER TABLE {schema}mental_models
|
|
80
|
+
DROP CONSTRAINT IF EXISTS fk_reflections_bank_id
|
|
81
|
+
""")
|
|
82
|
+
op.execute(f"""
|
|
83
|
+
ALTER TABLE {schema}mental_models
|
|
84
|
+
ADD CONSTRAINT fk_mental_models_bank_id
|
|
85
|
+
FOREIGN KEY (bank_id) REFERENCES {schema}banks(bank_id) ON DELETE CASCADE
|
|
86
|
+
""")
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def downgrade() -> None:
|
|
90
|
+
"""Reverse: observation -> mental_model and mental_models -> reflections."""
|
|
91
|
+
schema = _get_schema_prefix()
|
|
92
|
+
|
|
93
|
+
# 1. Rename mental_models table back to reflections
|
|
94
|
+
op.execute(f"ALTER TABLE IF EXISTS {schema}mental_models RENAME TO reflections")
|
|
95
|
+
|
|
96
|
+
# 2. Rename indexes back
|
|
97
|
+
op.execute(f"ALTER INDEX IF EXISTS {schema}idx_mental_models_bank_id RENAME TO idx_reflections_bank_id")
|
|
98
|
+
op.execute(f"ALTER INDEX IF EXISTS {schema}idx_mental_models_embedding RENAME TO idx_reflections_embedding")
|
|
99
|
+
op.execute(f"ALTER INDEX IF EXISTS {schema}idx_mental_models_tags RENAME TO idx_reflections_tags")
|
|
100
|
+
op.execute(f"ALTER INDEX IF EXISTS {schema}idx_mental_models_text_search RENAME TO idx_reflections_text_search")
|
|
101
|
+
|
|
102
|
+
# 3. Rename foreign key back
|
|
103
|
+
op.execute(f"""
|
|
104
|
+
ALTER TABLE {schema}reflections
|
|
105
|
+
DROP CONSTRAINT IF EXISTS fk_mental_models_bank_id
|
|
106
|
+
""")
|
|
107
|
+
op.execute(f"""
|
|
108
|
+
ALTER TABLE {schema}reflections
|
|
109
|
+
ADD CONSTRAINT fk_reflections_bank_id
|
|
110
|
+
FOREIGN KEY (bank_id) REFERENCES {schema}banks(bank_id) ON DELETE CASCADE
|
|
111
|
+
""")
|
|
112
|
+
|
|
113
|
+
# 4. Update fact_type values: observation -> mental_model
|
|
114
|
+
op.execute(f"""
|
|
115
|
+
UPDATE {schema}memory_units
|
|
116
|
+
SET fact_type = 'mental_model'
|
|
117
|
+
WHERE fact_type = 'observation'
|
|
118
|
+
""")
|
|
119
|
+
|
|
120
|
+
# 5. Update the CHECK constraint back
|
|
121
|
+
op.execute(f"ALTER TABLE {schema}memory_units DROP CONSTRAINT IF EXISTS memory_units_fact_type_check")
|
|
122
|
+
op.execute(f"""
|
|
123
|
+
ALTER TABLE {schema}memory_units
|
|
124
|
+
ADD CONSTRAINT memory_units_fact_type_check
|
|
125
|
+
CHECK (fact_type IN ('world', 'experience', 'opinion', 'observation', 'mental_model'))
|
|
126
|
+
""")
|
|
127
|
+
|
|
128
|
+
# 6. Rename index back
|
|
129
|
+
op.execute(f"DROP INDEX IF EXISTS {schema}idx_memory_units_observations")
|
|
130
|
+
op.execute(f"""
|
|
131
|
+
CREATE INDEX IF NOT EXISTS idx_memory_units_mental_models
|
|
132
|
+
ON {schema}memory_units(bank_id, fact_type)
|
|
133
|
+
WHERE fact_type = 'mental_model'
|
|
134
|
+
""")
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Change mental_models.id from UUID to TEXT
|
|
2
|
+
|
|
3
|
+
Revision ID: u6p7q8r9s0t1
|
|
4
|
+
Revises: t5o6p7q8r9s0
|
|
5
|
+
Create Date: 2026-01-27
|
|
6
|
+
|
|
7
|
+
This migration changes the mental_models.id column from UUID to TEXT
|
|
8
|
+
to support user-defined text identifiers like 'team-communication' instead of UUIDs.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from collections.abc import Sequence
|
|
12
|
+
|
|
13
|
+
from alembic import context, op
|
|
14
|
+
|
|
15
|
+
revision: str = "u6p7q8r9s0t1"
|
|
16
|
+
down_revision: str | Sequence[str] | None = "t5o6p7q8r9s0"
|
|
17
|
+
branch_labels: str | Sequence[str] | None = None
|
|
18
|
+
depends_on: str | Sequence[str] | None = None
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _get_schema_prefix() -> str:
|
|
22
|
+
"""Get schema prefix for table names (required for multi-tenant support)."""
|
|
23
|
+
schema = context.config.get_main_option("target_schema")
|
|
24
|
+
return f'"{schema}".' if schema else ""
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def upgrade() -> None:
|
|
28
|
+
"""Change mental_models.id from UUID to TEXT."""
|
|
29
|
+
schema = _get_schema_prefix()
|
|
30
|
+
|
|
31
|
+
# Change the id column type from UUID to TEXT
|
|
32
|
+
# Existing UUIDs will be converted to their string representation
|
|
33
|
+
op.execute(f"ALTER TABLE {schema}mental_models ALTER COLUMN id TYPE TEXT USING id::TEXT")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def downgrade() -> None:
|
|
37
|
+
"""Revert mental_models.id from TEXT to UUID."""
|
|
38
|
+
schema = _get_schema_prefix()
|
|
39
|
+
|
|
40
|
+
# Note: This will fail if any id values are not valid UUIDs
|
|
41
|
+
op.execute(f"ALTER TABLE {schema}mental_models ALTER COLUMN id TYPE UUID USING id::UUID")
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Add max_tokens and trigger columns to mental_models
|
|
2
|
+
|
|
3
|
+
Revision ID: v7q8r9s0t1u2
|
|
4
|
+
Revises: u6p7q8r9s0t1
|
|
5
|
+
Create Date: 2026-01-27
|
|
6
|
+
|
|
7
|
+
This migration adds:
|
|
8
|
+
- max_tokens column: token limit for content generation during refresh
|
|
9
|
+
- trigger column: JSONB for trigger settings (e.g., refresh_after_consolidation)
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from collections.abc import Sequence
|
|
13
|
+
|
|
14
|
+
from alembic import context, op
|
|
15
|
+
|
|
16
|
+
revision: str = "v7q8r9s0t1u2"
|
|
17
|
+
down_revision: str | Sequence[str] | None = "u6p7q8r9s0t1"
|
|
18
|
+
branch_labels: str | Sequence[str] | None = None
|
|
19
|
+
depends_on: str | Sequence[str] | None = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _get_schema_prefix() -> str:
|
|
23
|
+
"""Get schema prefix for table names (required for multi-tenant support)."""
|
|
24
|
+
schema = context.config.get_main_option("target_schema")
|
|
25
|
+
return f'"{schema}".' if schema else ""
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def upgrade() -> None:
|
|
29
|
+
"""Add max_tokens and trigger columns to mental_models."""
|
|
30
|
+
schema = _get_schema_prefix()
|
|
31
|
+
|
|
32
|
+
op.execute(f"""
|
|
33
|
+
ALTER TABLE {schema}mental_models
|
|
34
|
+
ADD COLUMN IF NOT EXISTS max_tokens INT NOT NULL DEFAULT 2048
|
|
35
|
+
""")
|
|
36
|
+
|
|
37
|
+
# trigger column stores trigger settings as JSONB
|
|
38
|
+
# Default: refresh_after_consolidation = false (not "real time")
|
|
39
|
+
op.execute(f"""
|
|
40
|
+
ALTER TABLE {schema}mental_models
|
|
41
|
+
ADD COLUMN IF NOT EXISTS trigger JSONB NOT NULL DEFAULT '{{"refresh_after_consolidation": false}}'::jsonb
|
|
42
|
+
""")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def downgrade() -> None:
|
|
46
|
+
"""Remove max_tokens and trigger columns from mental_models."""
|
|
47
|
+
schema = _get_schema_prefix()
|
|
48
|
+
|
|
49
|
+
op.execute(f"ALTER TABLE {schema}mental_models DROP COLUMN IF EXISTS max_tokens")
|
|
50
|
+
op.execute(f"ALTER TABLE {schema}mental_models DROP COLUMN IF EXISTS trigger")
|