hindsight-api 0.0.18__tar.gz → 0.0.21__tar.gz

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.
Files changed (81) hide show
  1. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/.gitignore +3 -1
  2. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/PKG-INFO +2 -1
  3. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/alembic/env.py +17 -0
  4. hindsight_api-0.0.21/alembic/versions/d9f6a3b4c5e2_rename_bank_to_interactions.py +48 -0
  5. hindsight_api-0.0.21/alembic/versions/rename_personality_to_disposition.py +65 -0
  6. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/api/__init__.py +2 -2
  7. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/api/http.py +60 -60
  8. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/api/mcp.py +1 -1
  9. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/llm_wrapper.py +140 -5
  10. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/memory_engine.py +33 -31
  11. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/response_models.py +6 -6
  12. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/retain/bank_utils.py +66 -66
  13. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/retain/fact_extraction.py +8 -8
  14. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/retain/fact_storage.py +1 -1
  15. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/retain/link_utils.py +112 -43
  16. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/retain/types.py +1 -1
  17. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/search/think_utils.py +20 -20
  18. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/search/trace.py +1 -1
  19. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/models.py +3 -3
  20. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/pyproject.toml +2 -1
  21. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/test_agents_api.py +2 -2
  22. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/README.md +0 -0
  23. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/alembic/README +0 -0
  24. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/alembic/script.py.mako +0 -0
  25. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/alembic/versions/5a366d414dce_initial_schema.py +0 -0
  26. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/alembic/versions/b7c4d8e9f1a2_add_chunks_table.py +0 -0
  27. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/alembic/versions/c8e5f2a3b4d1_add_retain_params_to_documents.py +0 -0
  28. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/__init__.py +0 -0
  29. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/cli.py +0 -0
  30. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/__init__.py +0 -0
  31. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/cross_encoder.py +0 -0
  32. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/db_utils.py +0 -0
  33. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/embeddings.py +0 -0
  34. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/entity_resolver.py +0 -0
  35. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/query_analyzer.py +0 -0
  36. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/retain/__init__.py +0 -0
  37. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/retain/chunk_storage.py +0 -0
  38. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/retain/deduplication.py +0 -0
  39. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/retain/embedding_processing.py +0 -0
  40. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/retain/embedding_utils.py +0 -0
  41. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/retain/entity_processing.py +0 -0
  42. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/retain/link_creation.py +0 -0
  43. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/retain/orchestrator.py +0 -0
  44. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/search/__init__.py +0 -0
  45. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/search/fusion.py +0 -0
  46. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/search/observation_utils.py +0 -0
  47. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/search/reranking.py +0 -0
  48. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/search/retrieval.py +0 -0
  49. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/search/scoring.py +0 -0
  50. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/search/temporal_extraction.py +0 -0
  51. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/search/tracer.py +0 -0
  52. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/search/types.py +0 -0
  53. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/task_backend.py +0 -0
  54. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/engine/utils.py +0 -0
  55. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/metrics.py +0 -0
  56. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/migrations.py +0 -0
  57. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/pg0.py +0 -0
  58. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/web/__init__.py +0 -0
  59. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/hindsight_api/web/server.py +0 -0
  60. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/test_chunks_debug.py +0 -0
  61. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/test_mentioned_at.py +0 -0
  62. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/RETAIN_TEST_COVERAGE_PLAN.md +0 -0
  63. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/__init__.py +0 -0
  64. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/conftest.py +0 -0
  65. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/fixtures/README.md +0 -0
  66. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/fixtures/locomo_conversation_sample.json +0 -0
  67. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/test_batch_chunking.py +0 -0
  68. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/test_chunking.py +0 -0
  69. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/test_document_tracking.py +0 -0
  70. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/test_fact_extraction_quality.py +0 -0
  71. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/test_fact_ordering.py +0 -0
  72. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/test_http_api_integration.py +0 -0
  73. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/test_link_utils.py +0 -0
  74. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/test_mcp_api_integration.py +0 -0
  75. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/test_mcp_routing.py +0 -0
  76. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/test_observations.py +0 -0
  77. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/test_query_analyzer.py +0 -0
  78. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/test_retain.py +0 -0
  79. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/test_search_trace.py +0 -0
  80. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/test_temporal_ranges.py +0 -0
  81. {hindsight_api-0.0.18 → hindsight_api-0.0.21}/tests/test_think.py +0 -0
@@ -31,4 +31,6 @@ logs/
31
31
 
32
32
 
33
33
  hindsight-dev/benchmarks/locomo/results/
34
- hindsight-dev/benchmarks/longmemeval/results/
34
+ hindsight-dev/benchmarks/longmemeval/results/
35
+ hindsight-cli/target
36
+ hindsight-clients/rust/target
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hindsight-api
3
- Version: 0.0.18
3
+ Version: 0.0.21
4
4
  Summary: Temporal + Semantic + Entity Memory System for AI agents using PostgreSQL
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: alembic>=1.17.1
@@ -8,6 +8,7 @@ Requires-Dist: asyncpg>=0.29.0
8
8
  Requires-Dist: dateparser>=1.2.2
9
9
  Requires-Dist: fastapi[standard]>=0.120.3
10
10
  Requires-Dist: fastmcp>=2.0.0
11
+ Requires-Dist: google-genai>=1.0.0
11
12
  Requires-Dist: greenlet>=3.2.4
12
13
  Requires-Dist: httpx>=0.27.0
13
14
  Requires-Dist: langchain-text-splitters>=0.3.0
@@ -105,6 +105,8 @@ def run_migrations_offline() -> None:
105
105
 
106
106
  def run_migrations_online() -> None:
107
107
  """Run migrations in 'online' mode with synchronous engine."""
108
+ from sqlalchemy import event, text
109
+
108
110
  get_database_url() # Process and set the database URL in config
109
111
 
110
112
  connectable = engine_from_config(
@@ -113,7 +115,19 @@ def run_migrations_online() -> None:
113
115
  poolclass=pool.NullPool,
114
116
  )
115
117
 
118
+ # Add event listener to ensure connection is in read-write mode
119
+ # This is needed for Supabase which may start connections in read-only mode
120
+ @event.listens_for(connectable, "connect")
121
+ def set_read_write_mode(dbapi_connection, connection_record):
122
+ cursor = dbapi_connection.cursor()
123
+ cursor.execute("SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE")
124
+ cursor.close()
125
+
116
126
  with connectable.connect() as connection:
127
+ # Also explicitly set read-write mode on this connection
128
+ connection.execute(text("SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE"))
129
+ connection.commit() # Commit the SET command
130
+
117
131
  context.configure(
118
132
  connection=connection,
119
133
  target_metadata=target_metadata
@@ -122,6 +136,9 @@ def run_migrations_online() -> None:
122
136
  with context.begin_transaction():
123
137
  context.run_migrations()
124
138
 
139
+ # Explicit commit to ensure changes are persisted (especially for Supabase)
140
+ connection.commit()
141
+
125
142
 
126
143
  if context.is_offline_mode():
127
144
  run_migrations_offline()
@@ -0,0 +1,48 @@
1
+ """Rename fact_type 'bank' to 'experience'
2
+
3
+ Revision ID: d9f6a3b4c5e2
4
+ Revises: c8e5f2a3b4d1
5
+ Create Date: 2024-12-04 15:00:00.000000
6
+
7
+ """
8
+ from alembic import op
9
+ import sqlalchemy as sa
10
+
11
+
12
+ # revision identifiers, used by Alembic.
13
+ revision = 'd9f6a3b4c5e2'
14
+ down_revision = 'c8e5f2a3b4d1'
15
+ branch_labels = None
16
+ depends_on = None
17
+
18
+
19
+ def upgrade():
20
+ # Drop old check constraint FIRST (before updating data)
21
+ op.drop_constraint('memory_units_fact_type_check', 'memory_units', type_='check')
22
+
23
+ # Update existing 'bank' values to 'experience'
24
+ op.execute("UPDATE memory_units SET fact_type = 'experience' WHERE fact_type = 'bank'")
25
+ # Also update any 'interactions' values (in case of partial migration)
26
+ op.execute("UPDATE memory_units SET fact_type = 'experience' WHERE fact_type = 'interactions'")
27
+
28
+ # Create new check constraint with 'experience' instead of 'bank'
29
+ op.create_check_constraint(
30
+ 'memory_units_fact_type_check',
31
+ 'memory_units',
32
+ "fact_type IN ('world', 'experience', 'opinion', 'observation')"
33
+ )
34
+
35
+
36
+ def downgrade():
37
+ # Drop new check constraint FIRST
38
+ op.drop_constraint('memory_units_fact_type_check', 'memory_units', type_='check')
39
+
40
+ # Update 'experience' back to 'bank'
41
+ op.execute("UPDATE memory_units SET fact_type = 'bank' WHERE fact_type = 'experience'")
42
+
43
+ # Recreate old check constraint
44
+ op.create_check_constraint(
45
+ 'memory_units_fact_type_check',
46
+ 'memory_units',
47
+ "fact_type IN ('world', 'bank', 'opinion', 'observation')"
48
+ )
@@ -0,0 +1,65 @@
1
+ """rename_personality_to_disposition
2
+
3
+ Revision ID: rename_personality
4
+ Revises: d9f6a3b4c5e2
5
+ Create Date: 2024-12-04
6
+
7
+ """
8
+ from typing import Sequence, Union
9
+
10
+ from alembic import op
11
+ import sqlalchemy as sa
12
+ from sqlalchemy.dialects import postgresql
13
+
14
+
15
+ # revision identifiers, used by Alembic.
16
+ revision: str = 'rename_personality'
17
+ down_revision: Union[str, Sequence[str], None] = 'd9f6a3b4c5e2'
18
+ branch_labels: Union[str, Sequence[str], None] = None
19
+ depends_on: Union[str, Sequence[str], None] = None
20
+
21
+
22
+ def upgrade() -> None:
23
+ """Rename personality column to disposition in banks table (if it exists)."""
24
+ conn = op.get_bind()
25
+
26
+ # Check if 'personality' column exists (old database)
27
+ result = conn.execute(sa.text("""
28
+ SELECT column_name
29
+ FROM information_schema.columns
30
+ WHERE table_name = 'banks' AND column_name = 'personality'
31
+ """))
32
+ has_personality = result.fetchone() is not None
33
+
34
+ # Check if 'disposition' column exists (new database)
35
+ result = conn.execute(sa.text("""
36
+ SELECT column_name
37
+ FROM information_schema.columns
38
+ WHERE table_name = 'banks' AND column_name = 'disposition'
39
+ """))
40
+ has_disposition = result.fetchone() is not None
41
+
42
+ if has_personality and not has_disposition:
43
+ # Old database: rename personality -> disposition
44
+ op.alter_column('banks', 'personality', new_column_name='disposition')
45
+ elif not has_personality and not has_disposition:
46
+ # Neither exists (shouldn't happen, but be safe): add disposition column
47
+ op.add_column('banks', sa.Column(
48
+ 'disposition',
49
+ postgresql.JSONB(astext_type=sa.Text()),
50
+ server_default=sa.text("'{}'::jsonb"),
51
+ nullable=False
52
+ ))
53
+ # else: disposition already exists, nothing to do
54
+
55
+
56
+ def downgrade() -> None:
57
+ """Revert disposition column back to personality."""
58
+ conn = op.get_bind()
59
+ result = conn.execute(sa.text("""
60
+ SELECT column_name
61
+ FROM information_schema.columns
62
+ WHERE table_name = 'banks' AND column_name = 'disposition'
63
+ """))
64
+ if result.fetchone():
65
+ op.alter_column('banks', 'disposition', new_column_name='personality')
@@ -87,7 +87,7 @@ from .http import (
87
87
  ReflectRequest,
88
88
  ReflectResponse,
89
89
  CreateBankRequest,
90
- PersonalityTraits,
90
+ DispositionTraits,
91
91
  )
92
92
 
93
93
  __all__ = [
@@ -100,5 +100,5 @@ __all__ = [
100
100
  "ReflectRequest",
101
101
  "ReflectResponse",
102
102
  "CreateBankRequest",
103
- "PersonalityTraits",
103
+ "DispositionTraits",
104
104
  ]
@@ -84,7 +84,7 @@ class RecallRequest(BaseModel):
84
84
  model_config = ConfigDict(json_schema_extra={
85
85
  "example": {
86
86
  "query": "What did Alice say about machine learning?",
87
- "types": ["world", "bank"],
87
+ "types": ["world", "experience"],
88
88
  "budget": "mid",
89
89
  "max_tokens": 4096,
90
90
  "trace": True,
@@ -131,7 +131,7 @@ class RecallResult(BaseModel):
131
131
 
132
132
  id: str
133
133
  text: str
134
- type: Optional[str] = None # fact type: world, agent, opinion, observation
134
+ type: Optional[str] = None # fact type: world, experience, opinion, observation
135
135
  entities: Optional[List[str]] = None # Entity names mentioned in this fact
136
136
  context: Optional[str] = None
137
137
  occurred_start: Optional[str] = None # ISO format date when the event started
@@ -397,7 +397,7 @@ class ReflectFact(BaseModel):
397
397
 
398
398
  id: Optional[str] = None
399
399
  text: str
400
- type: Optional[str] = None # fact type: world, agent, opinion
400
+ type: Optional[str] = None # fact type: world, experience, opinion
401
401
  context: Optional[str] = None
402
402
  occurred_start: Optional[str] = None
403
403
  occurred_end: Optional[str] = None
@@ -417,7 +417,7 @@ class ReflectResponse(BaseModel):
417
417
  {
418
418
  "id": "456",
419
419
  "text": "I discussed AI applications last week",
420
- "type": "bank"
420
+ "type": "experience"
421
421
  }
422
422
  ]
423
423
  }
@@ -438,8 +438,8 @@ class BanksResponse(BaseModel):
438
438
  banks: List[str]
439
439
 
440
440
 
441
- class PersonalityTraits(BaseModel):
442
- """Personality traits based on Big Five model."""
441
+ class DispositionTraits(BaseModel):
442
+ """Disposition traits based on Big Five model."""
443
443
  model_config = ConfigDict(json_schema_extra={
444
444
  "example": {
445
445
  "openness": 0.8,
@@ -456,7 +456,7 @@ class PersonalityTraits(BaseModel):
456
456
  extraversion: float = Field(ge=0.0, le=1.0, description="Extraversion (0-1)")
457
457
  agreeableness: float = Field(ge=0.0, le=1.0, description="Agreeableness (0-1)")
458
458
  neuroticism: float = Field(ge=0.0, le=1.0, description="Neuroticism (0-1)")
459
- bias_strength: float = Field(ge=0.0, le=1.0, description="How strongly personality influences opinions (0-1)")
459
+ bias_strength: float = Field(ge=0.0, le=1.0, description="How strongly disposition influences opinions (0-1)")
460
460
 
461
461
 
462
462
  class BankProfileResponse(BaseModel):
@@ -465,7 +465,7 @@ class BankProfileResponse(BaseModel):
465
465
  "example": {
466
466
  "bank_id": "user123",
467
467
  "name": "Alice",
468
- "personality": {
468
+ "disposition": {
469
469
  "openness": 0.8,
470
470
  "conscientiousness": 0.6,
471
471
  "extraversion": 0.5,
@@ -479,13 +479,13 @@ class BankProfileResponse(BaseModel):
479
479
 
480
480
  bank_id: str
481
481
  name: str
482
- personality: PersonalityTraits
482
+ disposition: DispositionTraits
483
483
  background: str
484
484
 
485
485
 
486
- class UpdatePersonalityRequest(BaseModel):
487
- """Request model for updating personality traits."""
488
- personality: PersonalityTraits
486
+ class UpdateDispositionRequest(BaseModel):
487
+ """Request model for updating disposition traits."""
488
+ disposition: DispositionTraits
489
489
 
490
490
 
491
491
  class AddBackgroundRequest(BaseModel):
@@ -493,14 +493,14 @@ class AddBackgroundRequest(BaseModel):
493
493
  model_config = ConfigDict(json_schema_extra={
494
494
  "example": {
495
495
  "content": "I was born in Texas",
496
- "update_personality": True
496
+ "update_disposition": True
497
497
  }
498
498
  })
499
499
 
500
500
  content: str = Field(description="New background information to add or merge")
501
- update_personality: bool = Field(
501
+ update_disposition: bool = Field(
502
502
  default=True,
503
- description="If true, infer Big Five personality traits from the merged background (default: true)"
503
+ description="If true, infer Big Five disposition traits from the merged background (default: true)"
504
504
  )
505
505
 
506
506
 
@@ -509,7 +509,7 @@ class BackgroundResponse(BaseModel):
509
509
  model_config = ConfigDict(json_schema_extra={
510
510
  "example": {
511
511
  "background": "I was born in Texas. I am a software engineer with 10 years of experience.",
512
- "personality": {
512
+ "disposition": {
513
513
  "openness": 0.7,
514
514
  "conscientiousness": 0.6,
515
515
  "extraversion": 0.5,
@@ -521,14 +521,14 @@ class BackgroundResponse(BaseModel):
521
521
  })
522
522
 
523
523
  background: str
524
- personality: Optional[PersonalityTraits] = None
524
+ disposition: Optional[DispositionTraits] = None
525
525
 
526
526
 
527
527
  class BankListItem(BaseModel):
528
528
  """Bank list item with profile summary."""
529
529
  bank_id: str
530
530
  name: str
531
- personality: PersonalityTraits
531
+ disposition: DispositionTraits
532
532
  background: str
533
533
  created_at: Optional[str] = None
534
534
  updated_at: Optional[str] = None
@@ -542,7 +542,7 @@ class BankListResponse(BaseModel):
542
542
  {
543
543
  "bank_id": "user123",
544
544
  "name": "Alice",
545
- "personality": {
545
+ "disposition": {
546
546
  "openness": 0.5,
547
547
  "conscientiousness": 0.5,
548
548
  "extraversion": 0.5,
@@ -566,7 +566,7 @@ class CreateBankRequest(BaseModel):
566
566
  model_config = ConfigDict(json_schema_extra={
567
567
  "example": {
568
568
  "name": "Alice",
569
- "personality": {
569
+ "disposition": {
570
570
  "openness": 0.8,
571
571
  "conscientiousness": 0.6,
572
572
  "extraversion": 0.5,
@@ -579,7 +579,7 @@ class CreateBankRequest(BaseModel):
579
579
  })
580
580
 
581
581
  name: Optional[str] = None
582
- personality: Optional[PersonalityTraits] = None
582
+ disposition: Optional[DispositionTraits] = None
583
583
  background: Optional[str] = None
584
584
 
585
585
 
@@ -833,7 +833,7 @@ def _register_routes(app: FastAPI):
833
833
  "/v1/default/banks/{bank_id}/graph",
834
834
  response_model=GraphDataResponse,
835
835
  summary="Get memory graph data",
836
- description="Retrieve graph data for visualization, optionally filtered by type (world/agent/opinion). Limited to 1000 most recent items.",
836
+ description="Retrieve graph data for visualization, optionally filtered by type (world/experience/opinion). Limited to 1000 most recent items.",
837
837
  operation_id="get_graph"
838
838
  )
839
839
  async def api_graph(bank_id: str,
@@ -871,7 +871,7 @@ def _register_routes(app: FastAPI):
871
871
 
872
872
  Args:
873
873
  bank_id: Memory Bank ID (from path)
874
- type: Filter by fact type (world, agent, opinion)
874
+ type: Filter by fact type (world, experience, opinion)
875
875
  q: Search query for full-text search (searches text and context)
876
876
  limit: Maximum number of results (default: 100)
877
877
  offset: Offset for pagination (default: 0)
@@ -901,7 +901,7 @@ def _register_routes(app: FastAPI):
901
901
 
902
902
  The type parameter is optional and must be one of:
903
903
  - 'world': General knowledge about people, places, events, and things that happen
904
- - 'bank': Memories about what the AI agent did, actions taken, and tasks performed
904
+ - 'experience': Memories about experience, conversations, actions taken, and tasks performed
905
905
  - 'opinion': The bank's formed beliefs, perspectives, and viewpoints
906
906
 
907
907
  Set include_entities=true to get entity observations alongside recall results.
@@ -914,10 +914,10 @@ def _register_routes(app: FastAPI):
914
914
 
915
915
  try:
916
916
  # Validate types
917
- valid_fact_types = ["world", "bank", "opinion"]
917
+ valid_fact_types = ["world", "experience", "opinion"]
918
918
 
919
- # Default to world, agent, opinion if not specified (exclude observation by default)
920
- fact_types = request.types if request.types else ["world", "bank", "opinion"]
919
+ # Default to world, experience, opinion if not specified (exclude observation by default)
920
+ fact_types = request.types if request.types else ["world", "experience", "opinion"]
921
921
  for ft in fact_types:
922
922
  if ft not in valid_fact_types:
923
923
  raise HTTPException(
@@ -1026,7 +1026,7 @@ def _register_routes(app: FastAPI):
1026
1026
  Reflect and formulate an answer using bank identity, world facts, and opinions.
1027
1027
 
1028
1028
  This endpoint:
1029
- 1. Retrieves agent facts (bank's identity)
1029
+ 1. Retrieves experience (conversations and events)
1030
1030
  2. Retrieves world facts relevant to the query
1031
1031
  3. Retrieves existing opinions (bank's perspectives)
1032
1032
  4. Uses LLM to formulate a contextual answer
@@ -1579,19 +1579,19 @@ This operation cannot be undone.
1579
1579
  "/v1/default/banks/{bank_id}/profile",
1580
1580
  response_model=BankProfileResponse,
1581
1581
  summary="Get memory bank profile",
1582
- description="Get personality traits and background for a memory bank. Auto-creates agent with defaults if not exists.",
1582
+ description="Get disposition traits and background for a memory bank. Auto-creates agent with defaults if not exists.",
1583
1583
  operation_id="get_bank_profile"
1584
1584
  )
1585
1585
  async def api_get_bank_profile(bank_id: str):
1586
- """Get memory bank profile (personality + background)."""
1586
+ """Get memory bank profile (disposition + background)."""
1587
1587
  try:
1588
1588
  profile = await app.state.memory.get_bank_profile(bank_id)
1589
- # Convert PersonalityTraits object to dict for Pydantic
1590
- personality_dict = profile["personality"].model_dump() if hasattr(profile["personality"], 'model_dump') else dict(profile["personality"])
1589
+ # Convert DispositionTraits object to dict for Pydantic
1590
+ disposition_dict = profile["disposition"].model_dump() if hasattr(profile["disposition"], 'model_dump') else dict(profile["disposition"])
1591
1591
  return BankProfileResponse(
1592
1592
  bank_id=bank_id,
1593
1593
  name=profile["name"],
1594
- personality=PersonalityTraits(**personality_dict),
1594
+ disposition=DispositionTraits(**disposition_dict),
1595
1595
  background=profile["background"]
1596
1596
  )
1597
1597
  except Exception as e:
@@ -1604,28 +1604,28 @@ This operation cannot be undone.
1604
1604
  @app.put(
1605
1605
  "/v1/default/banks/{bank_id}/profile",
1606
1606
  response_model=BankProfileResponse,
1607
- summary="Update memory bank personality",
1608
- description="Update bank's Big Five personality traits and bias strength",
1609
- operation_id="update_bank_personality"
1607
+ summary="Update memory bank disposition",
1608
+ description="Update bank's Big Five disposition traits and bias strength",
1609
+ operation_id="update_bank_disposition"
1610
1610
  )
1611
- async def api_update_bank_personality(bank_id: str,
1612
- request: UpdatePersonalityRequest
1611
+ async def api_update_bank_disposition(bank_id: str,
1612
+ request: UpdateDispositionRequest
1613
1613
  ):
1614
- """Update bank personality traits."""
1614
+ """Update bank disposition traits."""
1615
1615
  try:
1616
- # Update personality
1617
- await app.state.memory.update_bank_personality(
1616
+ # Update disposition
1617
+ await app.state.memory.update_bank_disposition(
1618
1618
  bank_id,
1619
- request.personality.model_dump()
1619
+ request.disposition.model_dump()
1620
1620
  )
1621
1621
 
1622
1622
  # Get updated profile
1623
1623
  profile = await app.state.memory.get_bank_profile(bank_id)
1624
- personality_dict = profile["personality"].model_dump() if hasattr(profile["personality"], 'model_dump') else dict(profile["personality"])
1624
+ disposition_dict = profile["disposition"].model_dump() if hasattr(profile["disposition"], 'model_dump') else dict(profile["disposition"])
1625
1625
  return BankProfileResponse(
1626
1626
  bank_id=bank_id,
1627
1627
  name=profile["name"],
1628
- personality=PersonalityTraits(**personality_dict),
1628
+ disposition=DispositionTraits(**disposition_dict),
1629
1629
  background=profile["background"]
1630
1630
  )
1631
1631
  except Exception as e:
@@ -1639,23 +1639,23 @@ This operation cannot be undone.
1639
1639
  "/v1/default/banks/{bank_id}/background",
1640
1640
  response_model=BackgroundResponse,
1641
1641
  summary="Add/merge memory bank background",
1642
- description="Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers personality traits.",
1642
+ description="Add new background information or merge with existing. LLM intelligently resolves conflicts, normalizes to first person, and optionally infers disposition traits.",
1643
1643
  operation_id="add_bank_background"
1644
1644
  )
1645
1645
  async def api_add_bank_background(bank_id: str,
1646
1646
  request: AddBackgroundRequest
1647
1647
  ):
1648
- """Add or merge bank background information. Optionally infer personality traits."""
1648
+ """Add or merge bank background information. Optionally infer disposition traits."""
1649
1649
  try:
1650
1650
  result = await app.state.memory.merge_bank_background(
1651
1651
  bank_id,
1652
1652
  request.content,
1653
- update_personality=request.update_personality
1653
+ update_disposition=request.update_disposition
1654
1654
  )
1655
1655
 
1656
1656
  response = BackgroundResponse(background=result["background"])
1657
- if "personality" in result:
1658
- response.personality = PersonalityTraits(**result["personality"])
1657
+ if "disposition" in result:
1658
+ response.disposition = DispositionTraits(**result["disposition"])
1659
1659
 
1660
1660
  return response
1661
1661
  except Exception as e:
@@ -1669,13 +1669,13 @@ This operation cannot be undone.
1669
1669
  "/v1/default/banks/{bank_id}",
1670
1670
  response_model=BankProfileResponse,
1671
1671
  summary="Create or update memory bank",
1672
- description="Create a new agent or update existing agent with personality and background. Auto-fills missing fields with defaults.",
1672
+ description="Create a new agent or update existing agent with disposition and background. Auto-fills missing fields with defaults.",
1673
1673
  operation_id="create_or_update_bank"
1674
1674
  )
1675
1675
  async def api_create_or_update_bank(bank_id: str,
1676
1676
  request: CreateBankRequest
1677
1677
  ):
1678
- """Create or update an agent with personality and background."""
1678
+ """Create or update an agent with disposition and background."""
1679
1679
  try:
1680
1680
  # Get existing profile or create with defaults
1681
1681
  profile = await app.state.memory.get_bank_profile(bank_id)
@@ -1696,13 +1696,13 @@ This operation cannot be undone.
1696
1696
  )
1697
1697
  profile["name"] = request.name
1698
1698
 
1699
- # Update personality if provided
1700
- if request.personality is not None:
1701
- await app.state.memory.update_bank_personality(
1699
+ # Update disposition if provided
1700
+ if request.disposition is not None:
1701
+ await app.state.memory.update_bank_disposition(
1702
1702
  bank_id,
1703
- request.personality.model_dump()
1703
+ request.disposition.model_dump()
1704
1704
  )
1705
- profile["personality"] = request.personality.model_dump()
1705
+ profile["disposition"] = request.disposition.model_dump()
1706
1706
 
1707
1707
  # Update background if provided (replace, not merge)
1708
1708
  if request.background is not None:
@@ -1722,11 +1722,11 @@ This operation cannot be undone.
1722
1722
 
1723
1723
  # Get final profile
1724
1724
  final_profile = await app.state.memory.get_bank_profile(bank_id)
1725
- personality_dict = final_profile["personality"].model_dump() if hasattr(final_profile["personality"], 'model_dump') else dict(final_profile["personality"])
1725
+ disposition_dict = final_profile["disposition"].model_dump() if hasattr(final_profile["disposition"], 'model_dump') else dict(final_profile["disposition"])
1726
1726
  return BankProfileResponse(
1727
1727
  bank_id=bank_id,
1728
1728
  name=final_profile["name"],
1729
- personality=PersonalityTraits(**personality_dict),
1729
+ disposition=DispositionTraits(**disposition_dict),
1730
1730
  background=final_profile["background"]
1731
1731
  )
1732
1732
  except Exception as e:
@@ -1852,11 +1852,11 @@ This operation cannot be undone.
1852
1852
  "/v1/default/banks/{bank_id}/memories",
1853
1853
  response_model=DeleteResponse,
1854
1854
  summary="Clear memory bank memories",
1855
- description="Delete memory units for a memory bank. Optionally filter by type (world, agent, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The bank profile (personality and background) will be preserved.",
1855
+ description="Delete memory units for a memory bank. Optionally filter by type (world, experience, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The bank profile (personality and background) will be preserved.",
1856
1856
  operation_id="clear_bank_memories"
1857
1857
  )
1858
1858
  async def api_clear_bank_memories(bank_id: str,
1859
- type: Optional[str] = Query(None, description="Optional fact type filter (world, agent, opinion)")
1859
+ type: Optional[str] = Query(None, description="Optional fact type filter (world, experience, opinion)")
1860
1860
  ):
1861
1861
  """Clear memories for a memory bank, optionally filtered by type."""
1862
1862
  try:
@@ -90,7 +90,7 @@ def create_mcp_server(memory: MemoryEngine) -> FastMCP:
90
90
  search_result = await memory.recall_async(
91
91
  bank_id=bank_id,
92
92
  query=query,
93
- fact_type=["world", "bank", "opinion"],
93
+ fact_type=["world", "experience", "opinion"],
94
94
  budget=Budget.LOW
95
95
  )
96
96